diff --git a/docs/img/favicon.ico b/docs/img/favicon.ico new file mode 100644 index 0000000000..16a72bebcb Binary files /dev/null and b/docs/img/favicon.ico differ diff --git a/docs/index.md b/docs/index.md index 1fdc063c46..670e6b7aca 100644 --- a/docs/index.md +++ b/docs/index.md @@ -117,6 +117,11 @@ Mac and Linux machines, and runs on GPU cards with as little as 4 GB of RAM. ## :octicons-gift-24: InvokeAI Features +### Installation + - [Automated Installer](installation/010_INSTALL_AUTOMATED.md) + - [Manual Installation](installation/020_INSTALL_MANUAL.md) + - [Docker Installation](installation/040_INSTALL_DOCKER.md) + ### The InvokeAI Web Interface - [WebUI overview](features/WEB.md) - [WebUI hotkey reference guide](features/WEBUIHOTKEYS.md) diff --git a/docs/installation/INSTALLATION.md b/docs/installation/INSTALLATION.md index 8ac2c56c48..29a82bb57e 100644 --- a/docs/installation/INSTALLATION.md +++ b/docs/installation/INSTALLATION.md @@ -18,13 +18,18 @@ either an Nvidia-based card (with CUDA support) or an AMD card (using the ROCm driver). -## **[Automated Installer](010_INSTALL_AUTOMATED.md)** -✅ This is the recommended installation method for first-time users. +## **[Automated Installer (Recommended)](010_INSTALL_AUTOMATED.md)** + ✅ This is the recommended installation method for first-time users. This is a script that will install all of InvokeAI's essential - third party libraries and InvokeAI itself. It includes access to a - "developer console" which will help us debug problems with you and - give you to access experimental features. + third party libraries and InvokeAI itself. + +🖥️ **Download the latest installer .zip file here** : https://github.com/invoke-ai/InvokeAI/releases/latest + +- *Look for the file labelled "InvokeAI-installer-v3.X.X.zip" at the bottom of the page* +- If you experience issues, read through the full [installation instructions](010_INSTALL_AUTOMATED.md) to make sure you have met all of the installation requirements. If you need more help, join the [Discord](discord.gg/invoke-ai) or create an issue on [Github](https://github.com/invoke-ai/InvokeAI). + + ## **[Manual Installation](020_INSTALL_MANUAL.md)** This method is recommended for experienced users and developers. diff --git a/docs/workflows/SDXL_w_Refiner_Text_to_Image.json b/docs/workflows/SDXL_w_Refiner_Text_to_Image.json index f70d974702..634b3fac4b 100644 --- a/docs/workflows/SDXL_w_Refiner_Text_to_Image.json +++ b/docs/workflows/SDXL_w_Refiner_Text_to_Image.json @@ -37,7 +37,8 @@ } ], "meta": { - "version": "1.0.0" + "category": "user", + "version": "2.0.0" }, "nodes": [ { @@ -46,13 +47,24 @@ "data": { "id": "b2b35add-929d-4538-aecb-02c661768b29", "type": "string", + "label": "Positive Prompt", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "value": { "id": "89854c84-cbc1-4b60-921d-4bade11cab66", "name": "value", - "type": "string", "fieldKind": "input", "label": "Positive Prompt", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "super cute tiger" } }, @@ -60,24 +72,21 @@ "value": { "id": "3617404e-e483-4e2e-8550-7080a1ef283f", "name": "value", - "type": "string", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + } } - }, - "label": "Positive Prompt", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": -75 - } + }, + "width": 320, + "height": 24 }, { "id": "8d54b9db-3662-43af-8369-9a277e063f3b", @@ -85,13 +94,24 @@ "data": { "id": "8d54b9db-3662-43af-8369-9a277e063f3b", "type": "string", + "label": "Negative Style", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "value": { "id": "89854c84-cbc1-4b60-921d-4bade11cab66", "name": "value", - "type": "string", "fieldKind": "input", "label": "Negative Style", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" } }, @@ -99,24 +119,21 @@ "value": { "id": "3617404e-e483-4e2e-8550-7080a1ef283f", "name": "value", - "type": "string", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + } } - }, - "label": "Negative Style", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": 75 - } + }, + "width": 320, + "height": 24 }, { "id": "f1a6a160-4c36-4902-8eeb-8b1c23e81bc8", @@ -124,13 +141,24 @@ "data": { "id": "f1a6a160-4c36-4902-8eeb-8b1c23e81bc8", "type": "string", + "label": "Postive Style", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "value": { "id": "89854c84-cbc1-4b60-921d-4bade11cab66", "name": "value", - "type": "string", "fieldKind": "input", "label": "Positive Style", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" } }, @@ -138,24 +166,21 @@ "value": { "id": "3617404e-e483-4e2e-8550-7080a1ef283f", "name": "value", - "type": "string", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + } } - }, - "label": "Postive Style", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": -25 - } + }, + "width": 320, + "height": 24 }, { "id": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", @@ -163,85 +188,117 @@ "data": { "id": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", "type": "sdxl_refiner_compel_prompt", + "label": "SDXL Refiner Negative Compel Prompt", + "isOpen": true, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "style": { "id": "c6f91ecf-370f-44d0-8243-63724e75510a", "name": "style", - "type": "string", "fieldKind": "input", "label": "Negative Style", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" }, "original_width": { "id": "956f6eca-8324-41eb-a8dd-fa9b34164ca6", "name": "original_width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "original_height": { "id": "a41bb3a1-7664-4dac-b6ae-6f4dff3828a9", "name": "original_height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "crop_top": { "id": "81936e19-0ae7-4006-9d7c-e359fc7c7d15", "name": "crop_top", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "crop_left": { "id": "be94ddb8-88cc-4d6b-a2c0-f2b43143bfa1", "name": "crop_left", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "aesthetic_score": { "id": "60f380de-87b4-4535-b3ef-545a6e57283e", "name": "aesthetic_score", - "type": "float", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "FloatField" + }, "value": 6 }, "clip2": { "id": "773c4054-c005-46ad-92c4-5c1fa4506041", "name": "clip2", - "type": "ClipField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } } }, "outputs": { "conditioning": { "id": "63e16bfa-59d8-4d6f-abda-ad979b26adb5", "name": "conditioning", - "type": "ConditioningField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } } - }, - "label": "SDXL Refiner Negative Compel Prompt", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 547, "position": { "x": 1625, "y": -925 - } + }, + "width": 320, + "height": 483 }, { "id": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", @@ -249,108 +306,152 @@ "data": { "id": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", "type": "sdxl_compel_prompt", + "label": "SDXL Negative Compel Prompt", + "isOpen": true, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "prompt": { "id": "5a6889e6-95cb-462f-8f4a-6b93ae7afaec", "name": "prompt", - "type": "string", "fieldKind": "input", "label": "Negative Prompt", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" }, "style": { "id": "f240d0e6-3a1c-4320-af23-20ebb707c276", "name": "style", - "type": "string", "fieldKind": "input", "label": "Negative Style", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" }, "original_width": { "id": "05af07b0-99a0-4a68-8ad2-697bbdb7fc7e", "name": "original_width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "original_height": { "id": "2c771996-a998-43b7-9dd3-3792664d4e5b", "name": "original_height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "crop_top": { "id": "66519dca-a151-4e3e-ae1f-88f1f9877bde", "name": "crop_top", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "crop_left": { "id": "349cf2e9-f3d0-4e16-9ae2-7097d25b6a51", "name": "crop_left", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "target_width": { "id": "44499347-7bd6-4a73-99d6-5a982786db05", "name": "target_width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "target_height": { "id": "fda359b0-ab80-4f3c-805b-c9f61319d7d2", "name": "target_height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "clip": { "id": "b447adaf-a649-4a76-a827-046a9fc8d89b", "name": "clip", - "type": "ClipField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } }, "clip2": { "id": "86ee4e32-08f9-4baa-9163-31d93f5c0187", "name": "clip2", - "type": "ClipField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } } }, "outputs": { "conditioning": { "id": "7c10118e-7b4e-4911-b98e-d3ba6347dfd0", "name": "conditioning", - "type": "ConditioningField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } } - }, - "label": "SDXL Negative Compel Prompt", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 793, "position": { "x": 900, "y": -925 - } + }, + "width": 320, + "height": 699 }, { "id": "55705012-79b9-4aac-9f26-c0b10309785b", @@ -358,37 +459,60 @@ "data": { "id": "55705012-79b9-4aac-9f26-c0b10309785b", "type": "noise", + "label": "", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.1", + "nodePack": "invokeai", "inputs": { "seed": { "id": "6431737c-918a-425d-a3b4-5d57e2f35d4d", "name": "seed", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "width": { "id": "38fc5b66-fe6e-47c8-bba9-daf58e454ed7", "name": "width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "height": { "id": "16298330-e2bf-4872-a514-d6923df53cbb", "name": "height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "use_cpu": { "id": "c7c436d3-7a7a-4e76-91e4-c6deb271623c", "name": "use_cpu", - "type": "boolean", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "BooleanField" + }, "value": true } }, @@ -396,36 +520,41 @@ "noise": { "id": "50f650dc-0184-4e23-a927-0497a96fe954", "name": "noise", - "type": "LatentsField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "width": { "id": "bb8a452b-133d-42d1-ae4a-3843d7e4109a", "name": "width", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } }, "height": { "id": "35cfaa12-3b8b-4b7a-a884-327ff3abddd9", "name": "height", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } } - }, - "label": "", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 1275, "y": -200 - } + }, + "width": 320, + "height": 24 }, { "id": "ea94bc37-d995-4a83-aa99-4af42479f2f2", @@ -433,21 +562,36 @@ "data": { "id": "ea94bc37-d995-4a83-aa99-4af42479f2f2", "type": "rand_int", + "label": "Random Seed", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": false, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "low": { "id": "3ec65a37-60ba-4b6c-a0b2-553dd7a84b84", "name": "low", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "high": { "id": "085f853a-1a5f-494d-8bec-e4ba29a3f2d1", "name": "high", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 2147483647 } }, @@ -455,24 +599,21 @@ "value": { "id": "812ade4d-7699-4261-b9fc-a6c9d2ab55ee", "name": "value", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } } - }, - "label": "Random Seed", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": false, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 1275, "y": -250 - } + }, + "width": 320, + "height": 24 }, { "id": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", @@ -480,13 +621,24 @@ "data": { "id": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", "type": "sdxl_model_loader", + "label": "", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "model": { "id": "39f9e799-bc95-4318-a200-30eed9e60c42", "name": "model", - "type": "SDXLMainModelField", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "SDXLMainModelField" + }, "value": { "model_name": "stable-diffusion-xl-base-1.0", "base_model": "sdxl", @@ -498,42 +650,51 @@ "unet": { "id": "2626a45e-59aa-4609-b131-2d45c5eaed69", "name": "unet", - "type": "UNetField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "UNetField" + } }, "clip": { "id": "7c9c42fa-93d5-4639-ab8b-c4d9b0559baf", "name": "clip", - "type": "ClipField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } }, "clip2": { "id": "0dafddcf-a472-49c1-a47c-7b8fab4c8bc9", "name": "clip2", - "type": "ClipField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } }, "vae": { "id": "ee6a6997-1b3c-4ff3-99ce-1e7bfba2750c", "name": "vae", - "type": "VaeField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "VaeField" + } } - }, - "label": "", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": 175 - } + }, + "width": 320, + "height": 24 }, { "id": "faf965a4-7530-427b-b1f3-4ba6505c2a08", @@ -541,108 +702,152 @@ "data": { "id": "faf965a4-7530-427b-b1f3-4ba6505c2a08", "type": "sdxl_compel_prompt", + "label": "SDXL Positive Compel Prompt", + "isOpen": true, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "prompt": { "id": "5a6889e6-95cb-462f-8f4a-6b93ae7afaec", "name": "prompt", - "type": "string", "fieldKind": "input", "label": "Positive Prompt", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" }, "style": { "id": "f240d0e6-3a1c-4320-af23-20ebb707c276", "name": "style", - "type": "string", "fieldKind": "input", "label": "Positive Style", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" }, "original_width": { "id": "05af07b0-99a0-4a68-8ad2-697bbdb7fc7e", "name": "original_width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "original_height": { "id": "2c771996-a998-43b7-9dd3-3792664d4e5b", "name": "original_height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "crop_top": { "id": "66519dca-a151-4e3e-ae1f-88f1f9877bde", "name": "crop_top", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "crop_left": { "id": "349cf2e9-f3d0-4e16-9ae2-7097d25b6a51", "name": "crop_left", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "target_width": { "id": "44499347-7bd6-4a73-99d6-5a982786db05", "name": "target_width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "target_height": { "id": "fda359b0-ab80-4f3c-805b-c9f61319d7d2", "name": "target_height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "clip": { "id": "b447adaf-a649-4a76-a827-046a9fc8d89b", "name": "clip", - "type": "ClipField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } }, "clip2": { "id": "86ee4e32-08f9-4baa-9163-31d93f5c0187", "name": "clip2", - "type": "ClipField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } } }, "outputs": { "conditioning": { "id": "7c10118e-7b4e-4911-b98e-d3ba6347dfd0", "name": "conditioning", - "type": "ConditioningField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } } - }, - "label": "SDXL Positive Compel Prompt", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 793, "position": { "x": 550, "y": -925 - } + }, + "width": 320, + "height": 699 }, { "id": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", @@ -650,85 +855,117 @@ "data": { "id": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", "type": "sdxl_refiner_compel_prompt", + "label": "SDXL Refiner Positive Compel Prompt", + "isOpen": true, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "style": { "id": "c6f91ecf-370f-44d0-8243-63724e75510a", "name": "style", - "type": "string", "fieldKind": "input", "label": "Positive Style", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" }, "original_width": { "id": "956f6eca-8324-41eb-a8dd-fa9b34164ca6", "name": "original_width", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "original_height": { "id": "a41bb3a1-7664-4dac-b6ae-6f4dff3828a9", "name": "original_height", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 1024 }, "crop_top": { "id": "81936e19-0ae7-4006-9d7c-e359fc7c7d15", "name": "crop_top", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "crop_left": { "id": "be94ddb8-88cc-4d6b-a2c0-f2b43143bfa1", "name": "crop_left", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 0 }, "aesthetic_score": { "id": "60f380de-87b4-4535-b3ef-545a6e57283e", "name": "aesthetic_score", - "type": "float", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "FloatField" + }, "value": 6 }, "clip2": { "id": "773c4054-c005-46ad-92c4-5c1fa4506041", "name": "clip2", - "type": "ClipField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } } }, "outputs": { "conditioning": { "id": "63e16bfa-59d8-4d6f-abda-ad979b26adb5", "name": "conditioning", - "type": "ConditioningField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } } - }, - "label": "SDXL Refiner Positive Compel Prompt", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 547, "position": { "x": 1275, "y": -925 - } + }, + "width": 320, + "height": 483 }, { "id": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", @@ -736,13 +973,24 @@ "data": { "id": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", "type": "sdxl_refiner_model_loader", + "label": "", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "model": { "id": "2f09431c-096b-4848-b580-b37be773839d", "name": "model", - "type": "SDXLRefinerModelField", "fieldKind": "input", "label": "Refiner Model", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "SDXLRefinerModelField" + }, "value": { "model_name": "stable-diffusion-xl-refiner-1.0", "base_model": "sdxl-refiner", @@ -754,36 +1002,41 @@ "unet": { "id": "c06b335a-7f65-4165-9ca2-40107eb9c85b", "name": "unet", - "type": "UNetField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "UNetField" + } }, "clip2": { "id": "81ec105e-cc1f-4b78-a5bb-8df3a4dd2574", "name": "clip2", - "type": "ClipField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ClipField" + } }, "vae": { "id": "f516feab-873d-47ec-a946-b8f15eed4bed", "name": "vae", - "type": "VaeField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "VaeField" + } } - }, - "label": "", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": 225 - } + }, + "width": 320, + "height": 24 }, { "id": "5639e3bc-b769-4ae5-9262-72db703c5a7b", @@ -791,13 +1044,24 @@ "data": { "id": "5639e3bc-b769-4ae5-9262-72db703c5a7b", "type": "string", + "label": "Negative Prompt", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "value": { "id": "89854c84-cbc1-4b60-921d-4bade11cab66", "name": "value", - "type": "string", "fieldKind": "input", "label": "Negative Prompt", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + }, "value": "" } }, @@ -805,24 +1069,21 @@ "value": { "id": "3617404e-e483-4e2e-8550-7080a1ef283f", "name": "value", - "type": "string", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "StringField" + } } - }, - "label": "Negative Prompt", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": 25 - } + }, + "width": 320, + "height": 24 }, { "id": "06a30867-1e9d-461f-bd58-14a63cc997dd", @@ -830,13 +1091,24 @@ "data": { "id": "06a30867-1e9d-461f-bd58-14a63cc997dd", "type": "scheduler", + "label": "", + "isOpen": false, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.0.0", + "nodePack": "invokeai", "inputs": { "scheduler": { "id": "0be5a5a0-3388-41e1-a6c4-10d414d8fe5b", "name": "scheduler", - "type": "Scheduler", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "SchedulerField" + }, "value": "euler" } }, @@ -844,24 +1116,21 @@ "scheduler": { "id": "cafdef9d-61cd-4f43-be91-356a1d65afca", "name": "scheduler", - "type": "Scheduler", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "SchedulerField" + } } - }, - "label": "", - "isOpen": false, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 32, "position": { "x": 700, "y": 125 - } + }, + "width": 320, + "height": 24 }, { "id": "84df8f00-ea7e-499f-ab86-d019ddea5393", @@ -869,145 +1138,225 @@ "data": { "id": "84df8f00-ea7e-499f-ab86-d019ddea5393", "type": "denoise_latents", + "label": "", + "isOpen": true, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.5.1", + "nodePack": "invokeai", "inputs": { "positive_conditioning": { "id": "73b2ebc2-4a56-4809-b8ab-b78fde786961", "name": "positive_conditioning", - "type": "ConditioningField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } }, "negative_conditioning": { "id": "04d1bfbb-6cdc-4c16-8e08-290ba86ca8ba", "name": "negative_conditioning", - "type": "ConditioningField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } }, "noise": { "id": "39ea4659-ea69-415f-85c0-a06f94d53e14", "name": "noise", - "type": "LatentsField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "steps": { "id": "dfd3c295-adae-499a-8c94-3c6c6d9ece0e", "name": "steps", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 10 }, "cfg_scale": { "id": "2ae0c196-8c94-4ea8-a9fc-1be06938a0c3", "name": "cfg_scale", - "type": "FloatPolymorphic", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "FloatField" + }, "value": 7.5 }, "denoising_start": { "id": "3d085ec1-14de-4eef-9853-2edf5d81daac", "name": "denoising_start", - "type": "float", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "FloatField" + }, "value": 0 }, "denoising_end": { "id": "1a820924-15ca-4ba5-b981-6b588e486a5b", "name": "denoising_end", - "type": "float", "fieldKind": "input", "label": "", - "value": 1 + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "FloatField" + }, + "value": 0.8 }, "scheduler": { "id": "d0d19fab-5001-4c5d-b664-031df1a65311", "name": "scheduler", - "type": "Scheduler", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "SchedulerField" + }, "value": "euler" }, "unet": { "id": "efbdecd1-5c07-420c-bd58-52de43fcde4c", "name": "unet", - "type": "UNetField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "UNetField" + } }, "control": { "id": "e1a457c4-5546-4c02-83e1-092776b27cd1", "name": "control", - "type": "ControlPolymorphic", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "ControlField" + } }, "ip_adapter": { "id": "d4082d78-7f17-4f87-af05-5a76129737ba", "name": "ip_adapter", - "type": "IPAdapterPolymorphic", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "IPAdapterField" + } }, "t2i_adapter": { "id": "4841595c-f81b-440a-9377-fe89b26b42ac", "name": "t2i_adapter", - "type": "T2IAdapterPolymorphic", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "T2IAdapterField" + } + }, + "cfg_rescale_multiplier": { + "id": "679083b2-f137-416f-a9d8-ec38f6263c1f", + "name": "cfg_rescale_multiplier", + "type": { + "name": "FloatField", + "isCollection": false, + "isCollectionOrScalar": false + }, + "label": "", + "fieldKind": "input", + "value": 0 }, "latents": { "id": "60bbfc7e-6641-4354-b678-12029c580aa9", "name": "latents", - "type": "LatentsField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "denoise_mask": { "id": "b2876171-e4c5-45cf-a352-852047c902fc", "name": "denoise_mask", - "type": "DenoiseMaskField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "DenoiseMaskField" + } } }, "outputs": { "latents": { "id": "62705a29-cc3a-4154-8f62-a8f821daf861", "name": "latents", - "type": "LatentsField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "width": { "id": "eb2e2312-1e64-4008-a64f-6783d49dde29", "name": "width", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } }, "height": { "id": "7bd8d012-edcf-4def-98eb-7ebdd724c7c5", "name": "height", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } } - }, - "label": "", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.4.0" + } }, - "width": 320, - "height": 646, "position": { "x": 1269.2683722842958, "y": -119.4839111990423 - } + }, + "width": 320, + "height": 614 }, { "id": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", @@ -1015,145 +1364,225 @@ "data": { "id": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", "type": "denoise_latents", + "label": "", + "isOpen": true, + "notes": "", + "isIntermediate": true, + "useCache": true, + "version": "1.5.1", + "nodePack": "invokeai", "inputs": { "positive_conditioning": { "id": "a9c932a9-6164-4333-bade-3909c9a3ce59", "name": "positive_conditioning", - "type": "ConditioningField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } }, "negative_conditioning": { "id": "a57fced5-aca6-40c9-8197-ce4f01433111", "name": "negative_conditioning", - "type": "ConditioningField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ConditioningField" + } }, "noise": { "id": "b4cbec14-c24e-4ec2-bda3-8fc19c089717", "name": "noise", - "type": "LatentsField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "steps": { "id": "24dd36f7-fdf1-40c9-945c-216471b44a2f", "name": "steps", - "type": "integer", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + }, "value": 10 }, "cfg_scale": { "id": "5f3a7f0c-5088-49e9-b490-75822d0c20cc", "name": "cfg_scale", - "type": "FloatPolymorphic", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "FloatField" + }, "value": 7.5 }, "denoising_start": { "id": "b326ffde-625c-49c5-b5e1-90b79df80979", "name": "denoising_start", - "type": "float", "fieldKind": "input", "label": "", - "value": 0 + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "FloatField" + }, + "value": 0.8 }, "denoising_end": { "id": "d4a458ef-5576-4c5d-8e6d-ee04c9c7c4dc", "name": "denoising_end", - "type": "float", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "FloatField" + }, "value": 1 }, "scheduler": { "id": "95aba2d0-c470-44f2-a25c-a192600be6da", "name": "scheduler", - "type": "Scheduler", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "SchedulerField" + }, "value": "euler" }, "unet": { "id": "68a8636e-3b2f-4a95-bd05-d86a01edb74a", "name": "unet", - "type": "UNetField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "UNetField" + } }, "control": { "id": "508e68a6-1cfc-4121-baed-b829b2886474", "name": "control", - "type": "ControlPolymorphic", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "ControlField" + } }, "ip_adapter": { "id": "e976e72f-8bd1-44d4-ad75-8410db221e3f", "name": "ip_adapter", - "type": "IPAdapterPolymorphic", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "IPAdapterField" + } }, "t2i_adapter": { "id": "38e15c99-ff72-443a-bddc-440fab9ccefc", "name": "t2i_adapter", - "type": "T2IAdapterPolymorphic", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": true, + "name": "T2IAdapterField" + } + }, + "cfg_rescale_multiplier": { + "id": "30c6aca9-333d-49fa-be99-89daf82fe850", + "name": "cfg_rescale_multiplier", + "type": { + "name": "FloatField", + "isCollection": false, + "isCollectionOrScalar": false + }, + "label": "", + "fieldKind": "input", + "value": 0 }, "latents": { "id": "f6d628e8-05ca-4ee3-a5a4-35323ebeb853", "name": "latents", - "type": "LatentsField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "denoise_mask": { "id": "e2385456-d127-4793-98ca-d93b4aee3481", "name": "denoise_mask", - "type": "DenoiseMaskField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "DenoiseMaskField" + } } }, "outputs": { "latents": { "id": "a61efc39-ba21-468b-ae58-5922337cf399", "name": "latents", - "type": "LatentsField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "width": { "id": "9093043b-808b-4ac6-ab18-7d721a7e39d7", "name": "width", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } }, "height": { "id": "5ff472a4-ee22-4988-bcf7-7d6116a37e5a", "name": "height", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } } - }, - "label": "", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": true, - "useCache": true, - "version": "1.4.0" + } }, - "width": 320, - "height": 646, "position": { "x": 1672.552348276784, "y": -118.3156091718022 - } + }, + "width": 320, + "height": 614 }, { "id": "17eb4b88-bdd8-4984-affa-26586b146866", @@ -1161,42 +1590,69 @@ "data": { "id": "17eb4b88-bdd8-4984-affa-26586b146866", "type": "l2i", + "label": "", + "isOpen": true, + "notes": "", + "isIntermediate": false, + "useCache": true, + "version": "1.2.0", + "nodePack": "invokeai", "inputs": { "metadata": { "id": "04f49f70-8ee6-43e3-ac63-af02e5b34204", "name": "metadata", - "type": "MetadataField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "MetadataField" + } }, "latents": { "id": "d27c4313-01db-45cb-b9f4-6a827d0d766a", "name": "latents", - "type": "LatentsField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "LatentsField" + } }, "vae": { "id": "3751b0f6-69f3-4f95-a7f9-476b2d31e9f9", "name": "vae", - "type": "VaeField", "fieldKind": "input", - "label": "" + "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "VaeField" + } }, "tiled": { "id": "07e5e79a-b452-4beb-b26f-715da2387ac7", "name": "tiled", - "type": "boolean", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "BooleanField" + }, "value": false }, "fp32": { "id": "afe954f6-ecaf-4eac-98ee-23f4d0eb7a6b", "name": "fp32", - "type": "boolean", "fieldKind": "input", "label": "", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "BooleanField" + }, "value": false } }, @@ -1204,236 +1660,241 @@ "image": { "id": "98515f37-9fe7-420e-839b-6e349d9407df", "name": "image", - "type": "ImageField", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "ImageField" + } }, "width": { "id": "5203f61f-02db-423c-9c85-80aa20816dea", "name": "width", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } }, "height": { "id": "499e6152-c604-4dad-84c3-8c5b26a39919", "name": "height", - "type": "integer", - "fieldKind": "output" + "fieldKind": "output", + "type": { + "isCollection": false, + "isCollectionOrScalar": false, + "name": "IntegerField" + } } - }, - "label": "", - "isOpen": true, - "notes": "", - "embedWorkflow": false, - "isIntermediate": false, - "useCache": true, - "version": "1.0.0" + } }, - "width": 320, - "height": 267, "position": { "x": 2045.2934900771834, "y": -362.2916292593367 - } + }, + "width": 320, + "height": 225 } ], "edges": [ { - "source": "ea94bc37-d995-4a83-aa99-4af42479f2f2", - "target": "55705012-79b9-4aac-9f26-c0b10309785b", "id": "ea94bc37-d995-4a83-aa99-4af42479f2f2-55705012-79b9-4aac-9f26-c0b10309785b-collapsed", - "type": "collapsed" - }, - { + "type": "collapsed", "source": "ea94bc37-d995-4a83-aa99-4af42479f2f2", - "sourceHandle": "value", - "target": "55705012-79b9-4aac-9f26-c0b10309785b", - "targetHandle": "seed", + "target": "55705012-79b9-4aac-9f26-c0b10309785b" + }, + { "id": "reactflow__edge-ea94bc37-d995-4a83-aa99-4af42479f2f2value-55705012-79b9-4aac-9f26-c0b10309785bseed", - "type": "default" + "type": "default", + "source": "ea94bc37-d995-4a83-aa99-4af42479f2f2", + "target": "55705012-79b9-4aac-9f26-c0b10309785b", + "sourceHandle": "value", + "targetHandle": "seed" }, { - "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", - "sourceHandle": "clip", - "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", - "targetHandle": "clip", "id": "reactflow__edge-30d3289c-773c-4152-a9d2-bd8a99c8fd22clip-faf965a4-7530-427b-b1f3-4ba6505c2a08clip", - "type": "default" - }, - { + "type": "default", "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", - "sourceHandle": "clip2", "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", - "targetHandle": "clip2", - "id": "reactflow__edge-30d3289c-773c-4152-a9d2-bd8a99c8fd22clip2-faf965a4-7530-427b-b1f3-4ba6505c2a08clip2", - "type": "default" - }, - { - "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", "sourceHandle": "clip", - "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", - "targetHandle": "clip", + "targetHandle": "clip" + }, + { + "id": "reactflow__edge-30d3289c-773c-4152-a9d2-bd8a99c8fd22clip2-faf965a4-7530-427b-b1f3-4ba6505c2a08clip2", + "type": "default", + "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", + "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", + "sourceHandle": "clip2", + "targetHandle": "clip2" + }, + { "id": "reactflow__edge-30d3289c-773c-4152-a9d2-bd8a99c8fd22clip-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204clip", - "type": "default" + "type": "default", + "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", + "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", + "sourceHandle": "clip", + "targetHandle": "clip" }, { - "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", - "sourceHandle": "clip2", - "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", - "targetHandle": "clip2", "id": "reactflow__edge-30d3289c-773c-4152-a9d2-bd8a99c8fd22clip2-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204clip2", - "type": "default" - }, - { - "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", - "sourceHandle": "clip2", - "target": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", - "targetHandle": "clip2", - "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0clip2-f0e06b70-9f53-44e3-8f5f-63d813b6b579clip2", - "type": "default" - }, - { - "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", - "sourceHandle": "clip2", - "target": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", - "targetHandle": "clip2", - "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0clip2-fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1clip2", - "type": "default" - }, - { - "source": "5639e3bc-b769-4ae5-9262-72db703c5a7b", - "sourceHandle": "value", - "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", - "targetHandle": "prompt", - "id": "reactflow__edge-5639e3bc-b769-4ae5-9262-72db703c5a7bvalue-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204prompt", - "type": "default" - }, - { - "source": "f1a6a160-4c36-4902-8eeb-8b1c23e81bc8", - "sourceHandle": "value", - "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", - "targetHandle": "style", - "id": "reactflow__edge-f1a6a160-4c36-4902-8eeb-8b1c23e81bc8value-faf965a4-7530-427b-b1f3-4ba6505c2a08style", - "type": "default" - }, - { - "source": "b2b35add-929d-4538-aecb-02c661768b29", - "sourceHandle": "value", - "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", - "targetHandle": "prompt", - "id": "reactflow__edge-b2b35add-929d-4538-aecb-02c661768b29value-faf965a4-7530-427b-b1f3-4ba6505c2a08prompt", - "type": "default" - }, - { - "source": "f1a6a160-4c36-4902-8eeb-8b1c23e81bc8", - "sourceHandle": "value", - "target": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", - "targetHandle": "style", - "id": "reactflow__edge-f1a6a160-4c36-4902-8eeb-8b1c23e81bc8value-f0e06b70-9f53-44e3-8f5f-63d813b6b579style", - "type": "default" - }, - { - "source": "8d54b9db-3662-43af-8369-9a277e063f3b", - "sourceHandle": "value", - "target": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", - "targetHandle": "style", - "id": "reactflow__edge-8d54b9db-3662-43af-8369-9a277e063f3bvalue-fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1style", - "type": "default" - }, - { - "source": "8d54b9db-3662-43af-8369-9a277e063f3b", - "sourceHandle": "value", - "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", - "targetHandle": "style", - "id": "reactflow__edge-8d54b9db-3662-43af-8369-9a277e063f3bvalue-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204style", - "type": "default" - }, - { - "source": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", - "sourceHandle": "conditioning", - "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", - "targetHandle": "negative_conditioning", - "id": "reactflow__edge-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204conditioning-84df8f00-ea7e-499f-ab86-d019ddea5393negative_conditioning", - "type": "default" - }, - { - "source": "faf965a4-7530-427b-b1f3-4ba6505c2a08", - "sourceHandle": "conditioning", - "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", - "targetHandle": "positive_conditioning", - "id": "reactflow__edge-faf965a4-7530-427b-b1f3-4ba6505c2a08conditioning-84df8f00-ea7e-499f-ab86-d019ddea5393positive_conditioning", - "type": "default" - }, - { - "source": "55705012-79b9-4aac-9f26-c0b10309785b", - "sourceHandle": "noise", - "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", - "targetHandle": "noise", - "id": "reactflow__edge-55705012-79b9-4aac-9f26-c0b10309785bnoise-84df8f00-ea7e-499f-ab86-d019ddea5393noise", - "type": "default" - }, - { + "type": "default", "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", - "sourceHandle": "unet", + "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", + "sourceHandle": "clip2", + "targetHandle": "clip2" + }, + { + "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0clip2-f0e06b70-9f53-44e3-8f5f-63d813b6b579clip2", + "type": "default", + "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", + "target": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", + "sourceHandle": "clip2", + "targetHandle": "clip2" + }, + { + "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0clip2-fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1clip2", + "type": "default", + "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", + "target": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", + "sourceHandle": "clip2", + "targetHandle": "clip2" + }, + { + "id": "reactflow__edge-5639e3bc-b769-4ae5-9262-72db703c5a7bvalue-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204prompt", + "type": "default", + "source": "5639e3bc-b769-4ae5-9262-72db703c5a7b", + "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", + "sourceHandle": "value", + "targetHandle": "prompt" + }, + { + "id": "reactflow__edge-f1a6a160-4c36-4902-8eeb-8b1c23e81bc8value-faf965a4-7530-427b-b1f3-4ba6505c2a08style", + "type": "default", + "source": "f1a6a160-4c36-4902-8eeb-8b1c23e81bc8", + "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", + "sourceHandle": "value", + "targetHandle": "style" + }, + { + "id": "reactflow__edge-b2b35add-929d-4538-aecb-02c661768b29value-faf965a4-7530-427b-b1f3-4ba6505c2a08prompt", + "type": "default", + "source": "b2b35add-929d-4538-aecb-02c661768b29", + "target": "faf965a4-7530-427b-b1f3-4ba6505c2a08", + "sourceHandle": "value", + "targetHandle": "prompt" + }, + { + "id": "reactflow__edge-f1a6a160-4c36-4902-8eeb-8b1c23e81bc8value-f0e06b70-9f53-44e3-8f5f-63d813b6b579style", + "type": "default", + "source": "f1a6a160-4c36-4902-8eeb-8b1c23e81bc8", + "target": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", + "sourceHandle": "value", + "targetHandle": "style" + }, + { + "id": "reactflow__edge-8d54b9db-3662-43af-8369-9a277e063f3bvalue-fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1style", + "type": "default", + "source": "8d54b9db-3662-43af-8369-9a277e063f3b", + "target": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", + "sourceHandle": "value", + "targetHandle": "style" + }, + { + "id": "reactflow__edge-8d54b9db-3662-43af-8369-9a277e063f3bvalue-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204style", + "type": "default", + "source": "8d54b9db-3662-43af-8369-9a277e063f3b", + "target": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", + "sourceHandle": "value", + "targetHandle": "style" + }, + { + "id": "reactflow__edge-3193ad09-a7c2-4bf4-a3a9-1c61cc33a204conditioning-84df8f00-ea7e-499f-ab86-d019ddea5393negative_conditioning", + "type": "default", + "source": "3193ad09-a7c2-4bf4-a3a9-1c61cc33a204", "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", - "targetHandle": "unet", + "sourceHandle": "conditioning", + "targetHandle": "negative_conditioning" + }, + { + "id": "reactflow__edge-faf965a4-7530-427b-b1f3-4ba6505c2a08conditioning-84df8f00-ea7e-499f-ab86-d019ddea5393positive_conditioning", + "type": "default", + "source": "faf965a4-7530-427b-b1f3-4ba6505c2a08", + "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", + "sourceHandle": "conditioning", + "targetHandle": "positive_conditioning" + }, + { + "id": "reactflow__edge-55705012-79b9-4aac-9f26-c0b10309785bnoise-84df8f00-ea7e-499f-ab86-d019ddea5393noise", + "type": "default", + "source": "55705012-79b9-4aac-9f26-c0b10309785b", + "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", + "sourceHandle": "noise", + "targetHandle": "noise" + }, + { "id": "reactflow__edge-30d3289c-773c-4152-a9d2-bd8a99c8fd22unet-84df8f00-ea7e-499f-ab86-d019ddea5393unet", - "type": "default" - }, - { - "source": "06a30867-1e9d-461f-bd58-14a63cc997dd", - "sourceHandle": "scheduler", + "type": "default", + "source": "30d3289c-773c-4152-a9d2-bd8a99c8fd22", "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", - "targetHandle": "scheduler", - "id": "reactflow__edge-06a30867-1e9d-461f-bd58-14a63cc997ddscheduler-84df8f00-ea7e-499f-ab86-d019ddea5393scheduler", - "type": "default" - }, - { - "source": "84df8f00-ea7e-499f-ab86-d019ddea5393", - "sourceHandle": "latents", - "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", - "targetHandle": "latents", - "id": "reactflow__edge-84df8f00-ea7e-499f-ab86-d019ddea5393latents-3d40eda5-ff7b-4dff-8d2e-4f44742faa1blatents", - "type": "default" - }, - { - "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", "sourceHandle": "unet", - "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", - "targetHandle": "unet", - "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0unet-3d40eda5-ff7b-4dff-8d2e-4f44742faa1bunet", - "type": "default" + "targetHandle": "unet" }, { - "source": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", - "sourceHandle": "conditioning", - "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", - "targetHandle": "positive_conditioning", - "id": "reactflow__edge-f0e06b70-9f53-44e3-8f5f-63d813b6b579conditioning-3d40eda5-ff7b-4dff-8d2e-4f44742faa1bpositive_conditioning", - "type": "default" + "id": "reactflow__edge-06a30867-1e9d-461f-bd58-14a63cc997ddscheduler-84df8f00-ea7e-499f-ab86-d019ddea5393scheduler", + "type": "default", + "source": "06a30867-1e9d-461f-bd58-14a63cc997dd", + "target": "84df8f00-ea7e-499f-ab86-d019ddea5393", + "sourceHandle": "scheduler", + "targetHandle": "scheduler" }, { - "source": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", - "sourceHandle": "conditioning", + "id": "reactflow__edge-84df8f00-ea7e-499f-ab86-d019ddea5393latents-3d40eda5-ff7b-4dff-8d2e-4f44742faa1blatents", + "type": "default", + "source": "84df8f00-ea7e-499f-ab86-d019ddea5393", "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", - "targetHandle": "negative_conditioning", - "id": "reactflow__edge-fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1conditioning-3d40eda5-ff7b-4dff-8d2e-4f44742faa1bnegative_conditioning", - "type": "default" - }, - { - "source": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", "sourceHandle": "latents", - "target": "17eb4b88-bdd8-4984-affa-26586b146866", - "targetHandle": "latents", - "id": "reactflow__edge-3d40eda5-ff7b-4dff-8d2e-4f44742faa1blatents-17eb4b88-bdd8-4984-affa-26586b146866latents", - "type": "default" + "targetHandle": "latents" }, { + "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0unet-3d40eda5-ff7b-4dff-8d2e-4f44742faa1bunet", + "type": "default", "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", - "sourceHandle": "vae", + "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", + "sourceHandle": "unet", + "targetHandle": "unet" + }, + { + "id": "reactflow__edge-f0e06b70-9f53-44e3-8f5f-63d813b6b579conditioning-3d40eda5-ff7b-4dff-8d2e-4f44742faa1bpositive_conditioning", + "type": "default", + "source": "f0e06b70-9f53-44e3-8f5f-63d813b6b579", + "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", + "sourceHandle": "conditioning", + "targetHandle": "positive_conditioning" + }, + { + "id": "reactflow__edge-fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1conditioning-3d40eda5-ff7b-4dff-8d2e-4f44742faa1bnegative_conditioning", + "type": "default", + "source": "fbb2f1a0-2e68-411d-a955-60c3b8a6f2d1", + "target": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", + "sourceHandle": "conditioning", + "targetHandle": "negative_conditioning" + }, + { + "id": "reactflow__edge-3d40eda5-ff7b-4dff-8d2e-4f44742faa1blatents-17eb4b88-bdd8-4984-affa-26586b146866latents", + "type": "default", + "source": "3d40eda5-ff7b-4dff-8d2e-4f44742faa1b", "target": "17eb4b88-bdd8-4984-affa-26586b146866", - "targetHandle": "vae", + "sourceHandle": "latents", + "targetHandle": "latents" + }, + { "id": "reactflow__edge-62bdf243-d98f-4508-b6b5-c3af00ef49f0vae-17eb4b88-bdd8-4984-affa-26586b146866vae", - "type": "default" + "type": "default", + "source": "62bdf243-d98f-4508-b6b5-c3af00ef49f0", + "target": "17eb4b88-bdd8-4984-affa-26586b146866", + "sourceHandle": "vae", + "targetHandle": "vae" } ] } \ No newline at end of file diff --git a/invokeai/frontend/web/.eslintrc.js b/invokeai/frontend/web/.eslintrc.js index 4ad387951f..2d1f21a0f2 100644 --- a/invokeai/frontend/web/.eslintrc.js +++ b/invokeai/frontend/web/.eslintrc.js @@ -1,131 +1,9 @@ module.exports = { - env: { - browser: true, - es6: true, - node: true, - }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:react/jsx-runtime', - 'prettier', - 'plugin:storybook/recommended', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - ecmaVersion: 2018, - sourceType: 'module', - }, - plugins: [ - 'react', - '@typescript-eslint', - 'eslint-plugin-react-hooks', - 'i18next', - 'path', - '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, + extends: ['@invoke-ai/eslint-config-react'], rules: { - 'path/no-relative-imports': ['error', { maxDepth: 0 }], - curly: 'error', - 'i18next/no-literal-string': 'warn', - 'react/jsx-no-bind': ['error', { allowBind: true }], - 'react/jsx-curly-brace-presence': [ - 'error', - { props: 'never', children: 'never' }, - ], - 'react-hooks/exhaustive-deps': 'error', - 'no-var': 'error', - 'brace-style': 'error', - 'prefer-template': 'error', - 'import/no-duplicates': 'error', - radix: 'error', - 'space-before-blocks': 'error', - 'import/prefer-default-export': 'off', - '@typescript-eslint/no-unused-vars': 'off', - 'unused-imports/no-unused-imports': 'error', - 'unused-imports/no-unused-vars': [ - 'warn', - { - vars: 'all', - varsIgnorePattern: '^_', - args: 'after-used', - 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/no-explicit-any': 'warn', - '@typescript-eslint/no-empty-interface': [ - 'error', - { - 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', - // Prefer @invoke-ai/ui components over chakra - 'no-restricted-imports': 'off', - '@typescript-eslint/no-restricted-imports': [ - 'warn', - { - paths: [ - { - name: '@chakra-ui/react', - message: "Please import from '@invoke-ai/ui' instead.", - }, - { - name: '@chakra-ui/layout', - message: "Please import from '@invoke-ai/ui' instead.", - }, - { - name: '@chakra-ui/portal', - message: "Please import from '@invoke-ai/ui' instead.", - }, - ], - }, - ], - }, - overrides: [ - { - files: ['*.stories.tsx'], - rules: { - 'i18next/no-literal-string': 'off', - }, - }, - ], - settings: { - react: { - version: 'detect', - }, + // TODO(psyche): Enable this rule. Requires no default exports in components - many changes. + 'react-refresh/only-export-components': 'off', + // TODO(psyche): Enable this rule. Requires a lot of eslint-disable-next-line comments. + '@typescript-eslint/consistent-type-assertions': 'off', }, }; diff --git a/invokeai/frontend/web/.prettierrc.js b/invokeai/frontend/web/.prettierrc.js index bffbd08257..c7f57d1475 100644 --- a/invokeai/frontend/web/.prettierrc.js +++ b/invokeai/frontend/web/.prettierrc.js @@ -1,9 +1,5 @@ module.exports = { - trailingComma: 'es5', - tabWidth: 2, - semi: true, - singleQuote: true, - endOfLine: 'auto', + ...require('@invoke-ai/prettier-config-react'), overrides: [ { files: ['public/locales/*.json'], diff --git a/invokeai/frontend/web/.storybook/ReduxInit.tsx b/invokeai/frontend/web/.storybook/ReduxInit.tsx index 9e62877ef0..55d0132242 100644 --- a/invokeai/frontend/web/.storybook/ReduxInit.tsx +++ b/invokeai/frontend/web/.storybook/ReduxInit.tsx @@ -1,7 +1,7 @@ import { PropsWithChildren, memo, useEffect } from 'react'; import { modelChanged } from '../src/features/parameters/store/generationSlice'; import { useAppDispatch } from '../src/app/store/storeHooks'; -import { useGlobalModifiersInit } from '@invoke-ai/ui'; +import { useGlobalModifiersInit } from '@invoke-ai/ui-library'; /** * Initializes some state for storybook. Must be in a different component * so that it is run inside the redux context. diff --git a/invokeai/frontend/web/.unimportedrc.json b/invokeai/frontend/web/.unimportedrc.json index 733e958861..cf96610502 100644 --- a/invokeai/frontend/web/.unimportedrc.json +++ b/invokeai/frontend/web/.unimportedrc.json @@ -1,13 +1,7 @@ { "entry": ["src/main.tsx"], "extensions": [".ts", ".tsx"], - "ignorePatterns": [ - "**/node_modules/**", - "dist/**", - "public/**", - "**/*.stories.tsx", - "config/**" - ], + "ignorePatterns": ["**/node_modules/**", "dist/**", "public/**", "**/*.stories.tsx", "config/**"], "ignoreUnresolved": [], "ignoreUnimported": ["src/i18.d.ts", "vite.config.ts", "src/vite-env.d.ts"], "respectGitignore": true, diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index db43fd2f71..ecc27350bc 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -19,8 +19,8 @@ "dist" ], "scripts": { - "dev": "concurrently \"vite dev\" \"pnpm run theme:watch\"", - "dev:host": "concurrently \"vite dev --host\" \"pnpm run theme:watch\"", + "dev": "vite dev", + "dev:host": "vite dev --host", "build": "pnpm run lint && vite build", "typegen": "node scripts/typegen.js", "preview": "vite preview", @@ -31,9 +31,6 @@ "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 .", "preinstall": "npx only-allow pnpm", - "postinstall": "pnpm run theme", - "theme": "chakra-cli tokens node_modules/@invoke-ai/ui", - "theme:watch": "chakra-cli tokens node_modules/@invoke-ai/ui --watch", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "unimported": "npx unimported" @@ -57,7 +54,7 @@ "@dnd-kit/core": "^6.1.0", "@dnd-kit/utilities": "^3.2.2", "@fontsource-variable/inter": "^5.0.16", - "@invoke-ai/ui": "0.0.13", + "@invoke-ai/ui-library": "^0.0.18", "@mantine/form": "6.0.21", "@nanostores/react": "^0.7.1", "@reduxjs/toolkit": "2.0.1", @@ -107,7 +104,6 @@ "zod-validation-error": "^3.0.0" }, "peerDependencies": { - "@chakra-ui/cli": "^2.4.1", "@chakra-ui/react": "^2.8.2", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -115,7 +111,8 @@ }, "devDependencies": { "@arthurgeron/eslint-plugin-react-usememo": "^2.2.3", - "@chakra-ui/cli": "^2.4.1", + "@invoke-ai/eslint-config-react": "^0.0.12", + "@invoke-ai/prettier-config-react": "^0.0.6", "@storybook/addon-docs": "^7.6.10", "@storybook/addon-essentials": "^7.6.10", "@storybook/addon-interactions": "^7.6.10", diff --git a/invokeai/frontend/web/pnpm-lock.yaml b/invokeai/frontend/web/pnpm-lock.yaml index 958c3f6350..98a307c7d9 100644 --- a/invokeai/frontend/web/pnpm-lock.yaml +++ b/invokeai/frontend/web/pnpm-lock.yaml @@ -28,9 +28,9 @@ dependencies: '@fontsource-variable/inter': specifier: ^5.0.16 version: 5.0.16 - '@invoke-ai/ui': - specifier: 0.0.13 - version: 0.0.13(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.16)(@internationalized/date@3.5.1)(@types/react@18.2.48)(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0) + '@invoke-ai/ui-library': + specifier: ^0.0.18 + version: 0.0.18(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.16)(@internationalized/date@3.5.1)(@types/react@18.2.48)(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0) '@mantine/form': specifier: 6.0.21 version: 6.0.21(react@18.2.0) @@ -177,9 +177,12 @@ devDependencies: '@arthurgeron/eslint-plugin-react-usememo': specifier: ^2.2.3 version: 2.2.3 - '@chakra-ui/cli': - specifier: ^2.4.1 - version: 2.4.1 + '@invoke-ai/eslint-config-react': + specifier: ^0.0.12 + version: 0.0.12(@typescript-eslint/eslint-plugin@6.19.0)(@typescript-eslint/parser@6.19.0)(eslint-config-prettier@9.1.0)(eslint-plugin-i18next@6.0.3)(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-simple-import-sort@10.0.0)(eslint-plugin-storybook@0.6.15)(eslint-plugin-unused-imports@3.0.0)(eslint@8.56.0) + '@invoke-ai/prettier-config-react': + specifier: ^0.0.6 + version: 0.0.6(prettier@3.2.4) '@storybook/addon-docs': specifier: ^7.6.10 version: 7.6.10(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) @@ -1852,19 +1855,6 @@ packages: react: 18.2.0 dev: false - /@chakra-ui/cli@2.4.1: - resolution: {integrity: sha512-GZZuHUA1cXJWpmYNiVTLPihvY4VhIssRl+AXgw/0IbeodTMop3jWlIioPKLAQeXu5CwvRA6iESyGjnu1V8Zykg==} - hasBin: true - dependencies: - chokidar: 3.5.3 - cli-check-node: 1.3.4 - cli-handle-unhandled: 1.1.1 - cli-welcome: 2.2.2 - commander: 9.5.0 - esbuild: 0.17.19 - prettier: 2.8.8 - dev: true - /@chakra-ui/clickable@2.1.0(react@18.2.0): resolution: {integrity: sha512-flRA/ClPUGPYabu+/GLREZVZr9j2uyyazCAUHAdrTUEdDYCr31SVGhgh7dgKdtq23bOvAQJpIJjw/0Bs0WvbXw==} peerDependencies: @@ -2907,7 +2897,7 @@ packages: resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: '@babel/helper-module-imports': 7.22.15 - '@babel/runtime': 7.23.6 + '@babel/runtime': 7.23.8 '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 '@emotion/serialize': 1.1.3 @@ -2966,7 +2956,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.6 + '@babel/runtime': 7.23.8 '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 '@emotion/serialize': 1.1.3 @@ -3041,15 +3031,6 @@ packages: dev: true optional: true - /@esbuild/android-arm64@0.17.19: - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-arm64@0.18.20: resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -3068,15 +3049,6 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.17.19: - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-arm@0.18.20: resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -3095,15 +3067,6 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.17.19: - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-x64@0.18.20: resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -3122,15 +3085,6 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.17.19: - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-arm64@0.18.20: resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -3149,15 +3103,6 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.17.19: - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-x64@0.18.20: resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -3176,15 +3121,6 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.17.19: - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-arm64@0.18.20: resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -3203,15 +3139,6 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.17.19: - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-x64@0.18.20: resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -3230,15 +3157,6 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.17.19: - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm64@0.18.20: resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -3257,15 +3175,6 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.17.19: - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm@0.18.20: resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -3284,15 +3193,6 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.17.19: - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ia32@0.18.20: resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -3311,15 +3211,6 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.17.19: - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-loong64@0.18.20: resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -3338,15 +3229,6 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.17.19: - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-mips64el@0.18.20: resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -3365,15 +3247,6 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.17.19: - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ppc64@0.18.20: resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -3392,15 +3265,6 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.17.19: - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-riscv64@0.18.20: resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -3419,15 +3283,6 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.17.19: - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-s390x@0.18.20: resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -3446,15 +3301,6 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.17.19: - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-x64@0.18.20: resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -3473,15 +3319,6 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.17.19: - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/netbsd-x64@0.18.20: resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -3500,15 +3337,6 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.17.19: - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/openbsd-x64@0.18.20: resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -3527,15 +3355,6 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.17.19: - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - /@esbuild/sunos-x64@0.18.20: resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -3554,15 +3373,6 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.17.19: - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-arm64@0.18.20: resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -3581,15 +3391,6 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.17.19: - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-ia32@0.18.20: resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -3608,15 +3409,6 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.17.19: - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-x64@0.18.20: resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -3759,8 +3551,46 @@ packages: '@swc/helpers': 0.5.3 dev: false - /@invoke-ai/ui@0.0.13(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.16)(@internationalized/date@3.5.1)(@types/react@18.2.48)(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-X4Txij2dMnzPUXTPhorBHezByJQ/ceyHxCM+zZ0gpFsSyXUieOFWjaSu+dAVpghS9y0dxFQGayHvNyX6VsX/PA==} + /@invoke-ai/eslint-config-react@0.0.12(@typescript-eslint/eslint-plugin@6.19.0)(@typescript-eslint/parser@6.19.0)(eslint-config-prettier@9.1.0)(eslint-plugin-i18next@6.0.3)(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-simple-import-sort@10.0.0)(eslint-plugin-storybook@0.6.15)(eslint-plugin-unused-imports@3.0.0)(eslint@8.56.0): + resolution: {integrity: sha512-6IXENcSa7vv+YPO/TYmC8qXXJFQt3JqDY+Yc1AMf4/d3b3o+CA7/mqepXIhydG9Gqo5jTRknXdDmjSaLxgCJ/g==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^6.19.0 + '@typescript-eslint/parser': ^6.19.0 + eslint: ^8.56.0 + eslint-config-prettier: ^9.1.0 + eslint-plugin-i18next: ^6.0.3 + eslint-plugin-import: ^2.29.1 + eslint-plugin-react: ^7.33.2 + eslint-plugin-react-hooks: ^4.6.0 + eslint-plugin-react-refresh: ^0.4.5 + eslint-plugin-simple-import-sort: ^10.0.0 + eslint-plugin-storybook: ^0.6.15 + eslint-plugin-unused-imports: ^3.0.0 + dependencies: + '@typescript-eslint/eslint-plugin': 6.19.0(@typescript-eslint/parser@6.19.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.19.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-prettier: 9.1.0(eslint@8.56.0) + eslint-plugin-i18next: 6.0.3 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.0)(eslint@8.56.0) + eslint-plugin-react: 7.33.2(eslint@8.56.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) + eslint-plugin-react-refresh: 0.4.5(eslint@8.56.0) + eslint-plugin-simple-import-sort: 10.0.0(eslint@8.56.0) + eslint-plugin-storybook: 0.6.15(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-unused-imports: 3.0.0(@typescript-eslint/eslint-plugin@6.19.0)(eslint@8.56.0) + dev: true + + /@invoke-ai/prettier-config-react@0.0.6(prettier@3.2.4): + resolution: {integrity: sha512-qHE6GAw/Aka/8TLTN9U1U+8pxjaFe5irDv/uSgzqmrBR1rGiVyMp19pEficWRRt+03zYdquiiDjTmoabWQxY0Q==} + peerDependencies: + prettier: ^3.2.4 + dependencies: + prettier: 3.2.4 + dev: true + + /@invoke-ai/ui-library@0.0.18(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.16)(@internationalized/date@3.5.1)(@types/react@18.2.48)(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Yme+2+pzYy3TPb7ZT0hYmBwahH29ZRSVIxLKSexh3BsbJXbTzGssRQU78QvK6Ymxemgbso3P8Rs+IW0zNhQKjQ==} peerDependencies: '@fontsource-variable/inter': ^5.0.16 react: ^18.2.0 @@ -3782,11 +3612,12 @@ packages: framer-motion: 10.18.0(react-dom@18.2.0)(react@18.2.0) lodash-es: 4.17.21 nanostores: 0.9.5 - overlayscrollbars: 2.4.6 - overlayscrollbars-react: 0.5.3(overlayscrollbars@2.4.6)(react@18.2.0) + overlayscrollbars: 2.4.7 + overlayscrollbars-react: 0.5.4(overlayscrollbars@2.4.7)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-i18next: 14.0.0(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0) + react-i18next: 14.0.1(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0) + react-icons: 5.0.1(react@18.2.0) react-select: 5.8.0(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) transitivePeerDependencies: - '@chakra-ui/form-control' @@ -7640,7 +7471,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.23.6 + '@babel/runtime': 7.23.8 cosmiconfig: 7.1.0 resolve: 1.22.8 dev: false @@ -7959,17 +7790,6 @@ packages: engines: {node: '>=6'} dev: true - /clear-any-console@1.16.2: - resolution: {integrity: sha512-OL/7wZpNy9x0GBSzz3poWja84Nr7iaH8aYNsJ5Uet2BVLj6Lm1zvWpZN/yH46Vv3ae7YfHmLLMmfHj911fshJg==} - dev: true - - /cli-check-node@1.3.4: - resolution: {integrity: sha512-iLGgQXm82iP8eH3R67qbOWs5qqUOLmNnMy5Lzl/RybcMh3y+H2zWU5POzuQ6oDUOdz4XWuxcFhP75szqd6frLg==} - dependencies: - chalk: 3.0.0 - log-symbols: 3.0.0 - dev: true - /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -7977,19 +7797,6 @@ packages: restore-cursor: 3.1.0 dev: true - /cli-handle-error@4.4.0: - resolution: {integrity: sha512-RyBCnKlc7xVr79cKb9RfBq+4fjwQeX8HKeNzIPnI/W+DWWIUUKh2ur576DpwJ3kZt2UGHlIAOF7N9txy+mgZsA==} - dependencies: - chalk: 3.0.0 - log-symbols: 3.0.0 - dev: true - - /cli-handle-unhandled@1.1.1: - resolution: {integrity: sha512-Em91mJvU7VdgT2MxQpyY633vW1tDzRjPDbii6ZjEBHHLLh0xDoVkFt/wjvi9nSvJcz9rJmvtJSK8KL/hvF0Stg==} - dependencies: - cli-handle-error: 4.4.0 - dev: true - /cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -8004,14 +7811,6 @@ packages: '@colors/colors': 1.5.0 dev: true - /cli-welcome@2.2.2: - resolution: {integrity: sha512-LgDGS0TW4nIf8v81wpuZzfOEDPcy68u0jKR0Fy5IaWftqdminI6FoDiMFt1mjPylqKGNv/wFsZ7fCs93IeDMIw==} - dependencies: - chalk: 2.4.2 - clear-any-console: 1.16.2 - prettier: 2.8.8 - dev: true - /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -8968,36 +8767,6 @@ packages: - supports-color dev: true - /esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - dev: true - /esbuild@0.18.20: resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} engines: {node: '>=12'} @@ -9198,6 +8967,14 @@ packages: eslint: 8.56.0 dev: true + /eslint-plugin-react-refresh@0.4.5(eslint@8.56.0): + resolution: {integrity: sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==} + peerDependencies: + eslint: '>=7' + dependencies: + eslint: 8.56.0 + dev: true + /eslint-plugin-react@7.33.2(eslint@8.56.0): resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} engines: {node: '>=4'} @@ -10908,13 +10685,6 @@ packages: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true - /log-symbols@3.0.0: - resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} - engines: {node: '>=8'} - dependencies: - chalk: 2.4.2 - dev: true - /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -11565,10 +11335,24 @@ packages: react: 18.2.0 dev: false + /overlayscrollbars-react@0.5.4(overlayscrollbars@2.4.7)(react@18.2.0): + resolution: {integrity: sha512-FPKx9XnXovTnI4+2JXig5uEaTLSEJ6svOwPzIfBBXTHBRNsz2+WhYUmfM0K/BNYxjgDEwuPm+NQhEoOA0RoG1g==} + peerDependencies: + overlayscrollbars: ^2.0.0 + react: '>=16.8.0' + dependencies: + overlayscrollbars: 2.4.7 + react: 18.2.0 + dev: false + /overlayscrollbars@2.4.6: resolution: {integrity: sha512-C7tmhetwMv9frEvIT/RfkAVEgbjRNz/Gh2zE8BVmN+jl35GRaAnz73rlGQCMRoC2arpACAXyMNnJkzHb7GBrcA==} dev: false + /overlayscrollbars@2.4.7: + resolution: {integrity: sha512-02X2/nHno35dzebCx+EO2tRDaKAOltZqUKdUqvq3Pt8htCuhJbYi+mjr0CYerVeGRRoZ2Uo6/8XrNg//DJJ+GA==} + dev: false + /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -12207,6 +11991,26 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /react-i18next@14.0.1(i18next@23.7.16)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-TMV8hFismBmpMdIehoFHin/okfvgjFhp723RYgIqB4XyhDobVMyukyM3Z8wtTRmajyFMZrBl/OaaXF2P6WjUAw==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.23.8 + html-parse-stringify: 3.0.1 + i18next: 23.7.16 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-icons@5.0.1(react@18.2.0): resolution: {integrity: sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==} peerDependencies: diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 6b9dbaf7bc..b2d873d6d5 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1463,9 +1463,7 @@ }, "compositingCoherencePass": { "heading": "Coherence Pass", - "paragraphs": [ - "A second round of denoising helps to composite the Inpainted/Outpainted image." - ] + "paragraphs": ["A second round of denoising helps to composite the Inpainted/Outpainted image."] }, "compositingCoherenceMode": { "heading": "Mode", @@ -1473,10 +1471,7 @@ }, "compositingCoherenceSteps": { "heading": "Steps", - "paragraphs": [ - "Number of denoising steps used in the Coherence Pass.", - "Same as the main Steps parameter." - ] + "paragraphs": ["Number of denoising steps used in the Coherence Pass.", "Same as the main Steps parameter."] }, "compositingStrength": { "heading": "Strength", @@ -1498,15 +1493,11 @@ }, "controlNetControlMode": { "heading": "Control Mode", - "paragraphs": [ - "Lends more weight to either the prompt or ControlNet." - ] + "paragraphs": ["Lends more weight to either the prompt or ControlNet."] }, "controlNetResizeMode": { "heading": "Resize Mode", - "paragraphs": [ - "How the ControlNet image will be fit to the image output size." - ] + "paragraphs": ["How the ControlNet image will be fit to the image output size."] }, "controlNet": { "heading": "ControlNet", @@ -1516,9 +1507,7 @@ }, "controlNetWeight": { "heading": "Weight", - "paragraphs": [ - "How strongly the ControlNet will impact the generated image." - ] + "paragraphs": ["How strongly the ControlNet will impact the generated image."] }, "dynamicPrompts": { "heading": "Dynamic Prompts", @@ -1530,9 +1519,7 @@ }, "dynamicPromptsMaxPrompts": { "heading": "Max Prompts", - "paragraphs": [ - "Limits the number of prompts that can be generated by Dynamic Prompts." - ] + "paragraphs": ["Limits the number of prompts that can be generated by Dynamic Prompts."] }, "dynamicPromptsSeedBehaviour": { "heading": "Seed Behaviour", @@ -1549,9 +1536,7 @@ }, "lora": { "heading": "LoRA Weight", - "paragraphs": [ - "Higher LoRA weight will lead to larger impacts on the final image." - ] + "paragraphs": ["Higher LoRA weight will lead to larger impacts on the final image."] }, "noiseUseCPU": { "heading": "Use CPU Noise", @@ -1563,9 +1548,7 @@ }, "paramCFGScale": { "heading": "CFG Scale", - "paragraphs": [ - "Controls how much your prompt influences the generation process." - ] + "paragraphs": ["Controls how much your prompt influences the generation process."] }, "paramCFGRescaleMultiplier": { "heading": "CFG Rescale Multiplier", @@ -1617,9 +1600,7 @@ }, "paramVAE": { "heading": "VAE", - "paragraphs": [ - "Model used for translating AI output into the final image." - ] + "paragraphs": ["Model used for translating AI output into the final image."] }, "paramVAEPrecision": { "heading": "VAE Precision", diff --git a/invokeai/frontend/web/public/locales/it.json b/invokeai/frontend/web/public/locales/it.json index cd8e74258c..c7ba4b782b 100644 --- a/invokeai/frontend/web/public/locales/it.json +++ b/invokeai/frontend/web/public/locales/it.json @@ -384,7 +384,11 @@ "desc": "Apre e chiude le opzioni e i pannelli della galleria", "title": "Attiva/disattiva le Opzioni e la Galleria" }, - "clearSearch": "Cancella ricerca" + "clearSearch": "Cancella ricerca", + "remixImage": { + "desc": "Utilizza tutti i parametri tranne il seme dell'immagine corrente", + "title": "Remixa l'immagine" + } }, "modelManager": { "modelManager": "Gestione Modelli", @@ -670,7 +674,8 @@ "aspect": "Aspetto", "setToOptimalSizeTooLarge": "$t(parameters.setToOptimalSize) (potrebbe essere troppo grande)", "boxBlur": "Box", - "gaussianBlur": "Gaussian" + "gaussianBlur": "Gaussian", + "remixImage": "Remixa l'immagine" }, "settings": { "models": "Modelli", @@ -1245,7 +1250,11 @@ "scribble": "Scarabocchio", "amult": "Angolo di illuminazione", "coarse": "Approssimativo", - "resizeSimple": "Ridimensiona (semplice)" + "resizeSimple": "Ridimensiona (semplice)", + "large": "Grande", + "small": "Piccolo", + "depthAnythingDescription": "Generazione di mappe di profondità utilizzando la tecnica Depth Anything", + "modelSize": "Dimensioni del modello" }, "queue": { "queueFront": "Aggiungi all'inizio della coda", @@ -1677,7 +1686,9 @@ "userWorkflows": "I miei flussi di lavoro", "newWorkflowCreated": "Nuovo flusso di lavoro creato", "downloadWorkflow": "Salva su file", - "uploadWorkflow": "Carica da file" + "uploadWorkflow": "Carica da file", + "projectWorkflows": "Flussi di lavoro del progetto", + "noWorkflows": "Nessun flusso di lavoro" }, "app": { "storeNotInitialized": "Il negozio non è inizializzato" diff --git a/invokeai/frontend/web/public/locales/tr.json b/invokeai/frontend/web/public/locales/tr.json index 0c222eecf7..8199f3306a 100644 --- a/invokeai/frontend/web/public/locales/tr.json +++ b/invokeai/frontend/web/public/locales/tr.json @@ -2,29 +2,35 @@ "accessibility": { "invokeProgressBar": "Invoke ilerleme durumu", "nextImage": "Sonraki Resim", - "useThisParameter": "Kullanıcı parametreleri", + "useThisParameter": "Bu ayarları kullan", "copyMetadataJson": "Metadata verilerini kopyala (JSON)", "exitViewer": "Görüntüleme Modundan Çık", "zoomIn": "Yakınlaştır", "zoomOut": "Uzaklaştır", - "rotateCounterClockwise": "Döndür (Saat yönünün tersine)", - "rotateClockwise": "Döndür (Saat yönünde)", + "rotateCounterClockwise": "Saat yönünün tersine döndür", + "rotateClockwise": "Saat yönüne döndür", "flipHorizontally": "Yatay Çevir", "flipVertically": "Dikey Çevir", "modifyConfig": "Ayarları Değiştir", - "toggleAutoscroll": "Otomatik kaydırmayı aç/kapat", - "toggleLogViewer": "Günlük Görüntüleyici Aç/Kapa", - "showOptionsPanel": "Ayarlar Panelini Göster", - "modelSelect": "Model Seçin", + "toggleAutoscroll": "Otomatik kaydırmayı aç-kapa", + "toggleLogViewer": "Günlüğü Aç-Kapa", + "showOptionsPanel": "Yan Paneli Göster", + "modelSelect": "Model Seçimi", "reset": "Sıfırla", "uploadImage": "Resim Yükle", "previousImage": "Önceki Resim", - "menu": "Menü" + "menu": "Menü", + "about": "Hakkında", + "mode": "Kip", + "resetUI": "$t(accessibility.reset)Arayüz", + "showGalleryPanel": "Galeri Panelini Göster", + "loadMore": "Daha Getir", + "createIssue": "Sorun Bildir" }, "common": { "hotkeysLabel": "Kısayol Tuşları", - "languagePickerLabel": "Dil Seçimi", - "reportBugLabel": "Hata Bildir", + "languagePickerLabel": "Dil", + "reportBugLabel": "Sorun Bildir", "githubLabel": "Github", "discordLabel": "Discord", "settingsLabel": "Ayarlar", @@ -37,22 +43,128 @@ "langJapanese": "Japonca", "langPolish": "Lehçe", "langPortuguese": "Portekizce", - "langBrPortuguese": "Portekizcr (Brezilya)", + "langBrPortuguese": "Portekizce (Brezilya)", "langRussian": "Rusça", "langSimplifiedChinese": "Çince (Basit)", "langUkranian": "Ukraynaca", "langSpanish": "İspanyolca", - "txt2img": "Metinden Resime", - "img2img": "Resimden Metine", - "linear": "Çizgisel", - "nodes": "Düğümler", - "postprocessing": "İşlem Sonrası", - "postProcessing": "İşlem Sonrası", - "postProcessDesc2": "Daha gelişmiş özellikler için ve iş akışını kolaylaştırmak için özel bir kullanıcı arayüzü çok yakında yayınlanacaktır.", - "postProcessDesc3": "Invoke AI komut satırı arayüzü, bir çok yeni özellik sunmaktadır.", + "txt2img": "Yazıdan Resime", + "img2img": "Resimden Resime", + "linear": "Doğrusal", + "nodes": "İş Akış Düzenleyici", + "postprocessing": "Rötuş", + "postProcessing": "Rötuş", + "postProcessDesc2": "Daha gelişmiş iş akışlarına olanak sağlayacak özel bir arayüz yakında yayınlanacaktır.", + "postProcessDesc3": "Invoke AI Komut Satırı Arayüzü, Embiggen dahil birçok yeni özellik sunmaktadır.", "langKorean": "Korece", "unifiedCanvas": "Akıllı Tuval", - "nodesDesc": "Görüntülerin oluşturulmasında hazırladığımız yeni bir sistem geliştirme aşamasındadır. Bu harika özellikler ve çok daha fazlası için bizi takip etmeye devam edin.", - "postProcessDesc1": "Invoke AI son kullanıcıya yönelik bir çok özellik sunar. Görüntü kalitesi yükseltme, yüz restorasyonu WebUI üzerinden kullanılabilir. Metinden resime ve resimden metne araçlarına gelişmiş seçenekler menüsünden ulaşabilirsiniz. İsterseniz mevcut görüntü ekranının üzerindeki veya görüntüleyicideki görüntüyü doğrudan düzenleyebilirsiniz." + "nodesDesc": "Resim oluşturmak için hazırladığımız çizge tabanlı sistem şu an geliştirme aşamasındadır. Bu harika özellik hakkındaki gelişmeler için bizi takip etmeye devam edin.", + "postProcessDesc1": "Invoke AI birçok rötuş (post-process) aracı sağlar. Resim büyütme ve yüz iyileştirme halihazırda WebUI üzerinden kullanılabilir. Bunlara Yazıdan Resime ve Resimden Resime sekmelerindeki Gelişmiş Ayarlar menüsünden ulaşabilirsiniz. İsterseniz mevcut görüntü ekranının üzerindeki veya görüntüleyicideki resmi doğrudan üstteki tuşlar yardımıyla düzenleyebilirsiniz.", + "batch": "Toplu İş Yöneticisi", + "accept": "Kabul et", + "cancel": "İptal et", + "advanced": "Gelişmiş", + "copyError": "$t(gallery.copy) Hata", + "on": "Açık", + "or": "ya da", + "aboutDesc": "Invoke'u iş için mi kullanıyorsunuz? Şuna bir göz atın:", + "advancedOptions": "Gelişmiş Ayarlar", + "ai": "yapay zeka", + "close": "Kapat", + "auto": "Otomatik", + "communityLabel": "Topluluk", + "back": "Geri", + "areYouSure": "Emin misiniz?", + "notInstalled": "$t(common.installed) Değil", + "openInNewTab": "Yeni Sekmede Aç", + "aboutHeading": "Yaratıcı Gücünüzün Sahibi Olun", + "lightMode": "Açık Tema", + "load": "Yükle", + "loading": "Yükleniyor", + "loadingInvokeAI": "Invoke AI Yükleniyor", + "localSystem": "Yerel Sistem", + "inpaint": "içboyama", + "modelManager": "Model Yöneticisi", + "orderBy": "Sırala", + "outpaint": "dışboyama", + "outputs": "Çıktılar", + "langHebrew": "İbranice", + "learnMore": "Bilgi Edin", + "nodeEditor": "Çizge Düzenleyici", + "save": "Kaydet", + "statusMergingModels": "Modeller Birleştiriliyor", + "statusGenerating": "Oluşturuluyor", + "statusGenerationComplete": "Oluşturma Tamamlandı", + "statusGeneratingOutpainting": "Dışboyama Oluşturuluyor", + "statusLoadingModel": "Model Yükleniyor", + "random": "Rastgele", + "simple": "Basit", + "preferencesLabel": "Seçenekler", + "statusConnected": "Bağlandı", + "statusMergedModels": "Modeller Birleştirildi", + "statusModelChanged": "Model Değişti", + "statusModelConverted": "Model Dönüştürüldü", + "statusPreparing": "Hazırlanıyor", + "statusProcessing": "İşleniyor", + "statusProcessingCanceled": "İşlem İptal Edildi", + "statusRestoringFacesCodeFormer": "Yüzler İyileştiriliyor (CodeFormer)", + "statusRestoringFacesGFPGAN": "Yüzler İyileştiriliyor (GFPGAN)", + "template": "Şablon", + "saveAs": "Farklı Kaydet", + "statusProcessingComplete": "İşlem Tamamlandı", + "statusSavingImage": "Resim Kaydediliyor", + "somethingWentWrong": "Bir sorun oluştu", + "statusConvertingModel": "Model Dönüştürülüyor", + "statusDisconnected": "Bağlantı Kesildi", + "statusError": "Hata", + "statusGeneratingImageToImage": "Resimden Resim Oluşturuluyor", + "statusGeneratingInpainting": "İçboyama Oluşturuluyor", + "statusRestoringFaces": "Yüzler İyileştiriliyor", + "statusUpscaling": "Büyütme", + "statusUpscalingESRGAN": "Büyütme (ESRGAN)", + "training": "Eğitim", + "statusGeneratingTextToImage": "Yazıdan Resim Oluşturuluyor" + }, + "accordions": { + "generation": { + "title": "Oluşturma", + "modelTab": "Model", + "conceptsTab": "Konseptler" + }, + "image": { + "title": "Resim" + }, + "advanced": { + "title": "Gelişmiş" + }, + "compositing": { + "title": "Birleştirme", + "coherenceTab": "Uyum Geçişi", + "infillTab": "Doldurma" + } + }, + "boards": { + "autoAddBoard": "Panoya Otomatik Ekleme", + "cancel": "İptal et", + "clearSearch": "Aramayı Sıfırla", + "deleteBoard": "Panoyu Sil", + "loading": "Yükleniyor...", + "myBoard": "Panom", + "selectBoard": "Bir Pano Seç", + "addBoard": "Pano Ekle", + "deleteBoardAndImages": "Panoyu ve Resimleri Sil", + "deleteBoardOnly": "Sadece Panoyu Sil", + "deletedBoardsCannotbeRestored": "Silinen panolar geri getirilemez", + "menuItemAutoAdd": "Bu panoya otomatik olarak ekle", + "move": "Taşı", + "movingImagesToBoard_one": "{{count}} resmi şu panoya taşı:", + "movingImagesToBoard_other": "{{count}} resmi şu panoya taşı:", + "noMatching": "Eşleşen pano yok", + "searchBoard": "Pano Ara...", + "topMessage": "Bu pano, şu özelliklerde kullanılan resimler içeriyor:", + "downloadBoard": "Panoyu İndir", + "uncategorized": "Kategorisiz", + "changeBoard": "Panoyu Değiştir", + "bottomMessage": "Bu panoyu ve resimlerini silmek, bunları kullanan özelliklerin sıfırlanmasına neden olacaktır." } } diff --git a/invokeai/frontend/web/scripts/typegen.js b/invokeai/frontend/web/scripts/typegen.js index ce78e3e5ba..78ea6150cd 100644 --- a/invokeai/frontend/web/scripts/typegen.js +++ b/invokeai/frontend/web/scripts/typegen.js @@ -6,9 +6,7 @@ const OPENAPI_URL = 'http://127.0.0.1:9090/openapi.json'; const OUTPUT_FILE = 'src/services/api/schema.ts'; async function main() { - process.stdout.write( - `Generating types "${OPENAPI_URL}" --> "${OUTPUT_FILE}"...` - ); + process.stdout.write(`Generating types "${OPENAPI_URL}" --> "${OUTPUT_FILE}"...`); const types = await openapiTS(OPENAPI_URL, { exportType: true, transform: (schemaObject) => { diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index ecd3c829d1..3474be5227 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -1,4 +1,4 @@ -import { Box, useGlobalModifiersInit } from '@invoke-ai/ui'; +import { Box, useGlobalModifiersInit } from '@invoke-ai/ui-library'; import { useSocketIO } from 'app/hooks/useSocketIO'; import { useLogger } from 'app/logging/useLogger'; import { appStarted } from 'app/store/middleware/listenerMiddleware/listeners/appStarted'; @@ -45,8 +45,7 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => { useGlobalModifiersInit(); useGlobalHotkeys(); - const { dropzone, isHandlingUpload, setIsHandlingUpload } = - useFullscreenDropzone(); + const { dropzone, isHandlingUpload, setIsHandlingUpload } = useFullscreenDropzone(); const handleReset = useCallback(() => { clearStorage(); @@ -70,10 +69,7 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => { }, [dispatch]); return ( - + { {dropzone.isDragActive && isHandlingUpload && ( - + )} diff --git a/invokeai/frontend/web/src/app/components/AppErrorBoundaryFallback.tsx b/invokeai/frontend/web/src/app/components/AppErrorBoundaryFallback.tsx index 8ee59e6648..d2992a8cd9 100644 --- a/invokeai/frontend/web/src/app/components/AppErrorBoundaryFallback.tsx +++ b/invokeai/frontend/web/src/app/components/AppErrorBoundaryFallback.tsx @@ -1,12 +1,8 @@ -import { Button, Flex, Heading, Link, Text, useToast } from '@invoke-ai/ui'; +import { Button, Flex, Heading, Link, Text, useToast } from '@invoke-ai/ui-library'; import newGithubIssueUrl from 'new-github-issue-url'; import { memo, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { - PiArrowCounterClockwiseBold, - PiArrowSquareOutBold, - PiCopyBold, -} from 'react-icons/pi'; +import { PiArrowCounterClockwiseBold, PiArrowSquareOutBold, PiCopyBold } from 'react-icons/pi'; import { serializeError } from 'serialize-error'; type Props = { @@ -37,22 +33,8 @@ const AppErrorBoundaryFallback = ({ error, resetErrorBoundary }: Props) => { [error.message, error.name] ); return ( - - + + {t('common.somethingWentWrong')} { - - + diff --git a/invokeai/frontend/web/src/app/components/ThemeLocaleProvider.tsx b/invokeai/frontend/web/src/app/components/ThemeLocaleProvider.tsx index 15b4cf28fc..0b4ca90933 100644 --- a/invokeai/frontend/web/src/app/components/ThemeLocaleProvider.tsx +++ b/invokeai/frontend/web/src/app/components/ThemeLocaleProvider.tsx @@ -1,13 +1,7 @@ import '@fontsource-variable/inter'; import 'overlayscrollbars/overlayscrollbars.css'; -import { - ChakraProvider, - DarkMode, - extendTheme, - theme as _theme, - TOAST_OPTIONS, -} from '@invoke-ai/ui'; +import { ChakraProvider, DarkMode, extendTheme, theme as _theme, TOAST_OPTIONS } from '@invoke-ai/ui-library'; import type { ReactNode } from 'react'; import { memo, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/invokeai/frontend/web/src/app/components/Toaster.ts b/invokeai/frontend/web/src/app/components/Toaster.ts index 6bb2592ba4..c86fd5060d 100644 --- a/invokeai/frontend/web/src/app/components/Toaster.ts +++ b/invokeai/frontend/web/src/app/components/Toaster.ts @@ -1,4 +1,4 @@ -import { useToast } from '@invoke-ai/ui'; +import { useToast } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { addToast, clearToastQueue } from 'features/system/store/systemSlice'; import type { MakeToastArg } from 'features/system/util/makeToast'; @@ -36,10 +36,7 @@ const Toaster = () => { */ export const useAppToaster = () => { const dispatch = useAppDispatch(); - const toaster = useCallback( - (arg: MakeToastArg) => dispatch(addToast(makeToast(arg))), - [dispatch] - ); + const toaster = useCallback((arg: MakeToastArg) => dispatch(addToast(makeToast(arg))), [dispatch]); return toaster; }; diff --git a/invokeai/frontend/web/src/app/hooks/useSocketIO.ts b/invokeai/frontend/web/src/app/hooks/useSocketIO.ts index 7b6d05b7a1..058a607261 100644 --- a/invokeai/frontend/web/src/app/hooks/useSocketIO.ts +++ b/invokeai/frontend/web/src/app/hooks/useSocketIO.ts @@ -6,10 +6,7 @@ import { useAppDispatch } from 'app/store/storeHooks'; import type { MapStore } from 'nanostores'; import { atom, map } from 'nanostores'; import { useEffect, useMemo } from 'react'; -import type { - ClientToServerEvents, - ServerToClientEvents, -} from 'services/events/types'; +import type { ClientToServerEvents, ServerToClientEvents } from 'services/events/types'; import { setEventListeners } from 'services/events/util/setEventListeners'; import type { ManagerOptions, Socket, SocketOptions } from 'socket.io-client'; import { io } from 'socket.io-client'; @@ -45,9 +42,7 @@ export const useSocketIO = () => { const socketOptions = useMemo(() => { const options: Partial = { timeout: 60000, - path: baseUrl - ? '/ws/socket.io' - : `${window.location.pathname}ws/socket.io`, + path: baseUrl ? '/ws/socket.io' : `${window.location.pathname}ws/socket.io`, autoConnect: false, // achtung! removing this breaks the dynamic middleware forceNew: true, }; @@ -66,10 +61,7 @@ export const useSocketIO = () => { return; } - const socket: Socket = io( - socketUrl, - socketOptions - ); + const socket: Socket = io(socketUrl, socketOptions); setEventListeners({ dispatch, socket }); socket.connect(); diff --git a/invokeai/frontend/web/src/app/logging/logger.ts b/invokeai/frontend/web/src/app/logging/logger.ts index c68fe64d39..491fc27688 100644 --- a/invokeai/frontend/web/src/app/logging/logger.ts +++ b/invokeai/frontend/web/src/app/logging/logger.ts @@ -30,20 +30,11 @@ export type LoggerNamespace = | 'queue' | 'dnd'; -export const logger = (namespace: LoggerNamespace) => - $logger.get().child({ namespace }); +export const logger = (namespace: LoggerNamespace) => $logger.get().child({ namespace }); -export const zLogLevel = z.enum([ - 'trace', - 'debug', - 'info', - 'warn', - 'error', - 'fatal', -]); +export const zLogLevel = z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']); export type LogLevel = z.infer; -export const isLogLevel = (v: unknown): v is LogLevel => - zLogLevel.safeParse(v).success; +export const isLogLevel = (v: unknown): v is LogLevel => zLogLevel.safeParse(v).success; // Translate human-readable log levels to numbers, used for log filtering export const LOG_LEVEL_MAP: Record = { diff --git a/invokeai/frontend/web/src/app/logging/useLogger.ts b/invokeai/frontend/web/src/app/logging/useLogger.ts index de60852c1b..6e170ca376 100644 --- a/invokeai/frontend/web/src/app/logging/useLogger.ts +++ b/invokeai/frontend/web/src/app/logging/useLogger.ts @@ -17,10 +17,7 @@ export const useLogger = (namespace: LoggerNamespace) => { localStorage.setItem('ROARR_LOG', 'true'); // Use a filter to show only logs of the given level - localStorage.setItem( - 'ROARR_FILTER', - `context.logLevel:>=${LOG_LEVEL_MAP[consoleLogLevel]}` - ); + localStorage.setItem('ROARR_FILTER', `context.logLevel:>=${LOG_LEVEL_MAP[consoleLogLevel]}`); } else { // Disable console log output localStorage.setItem('ROARR_LOG', 'false'); diff --git a/invokeai/frontend/web/src/app/store/createMemoizedSelector.ts b/invokeai/frontend/web/src/app/store/createMemoizedSelector.ts index b4d46a4ef8..8e6142ce1d 100644 --- a/invokeai/frontend/web/src/app/store/createMemoizedSelector.ts +++ b/invokeai/frontend/web/src/app/store/createMemoizedSelector.ts @@ -1,8 +1,4 @@ -import { - createDraftSafeSelectorCreator, - createSelectorCreator, - lruMemoize, -} from '@reduxjs/toolkit'; +import { createDraftSafeSelectorCreator, createSelectorCreator, lruMemoize } from '@reduxjs/toolkit'; import type { GetSelectorsOptions } from '@reduxjs/toolkit/dist/entities/state_selectors'; import { isEqual } from 'lodash-es'; diff --git a/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts b/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts index 465199002b..61fbd015f8 100644 --- a/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts +++ b/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts @@ -1,19 +1,12 @@ import { StorageError } from 'app/store/enhancers/reduxRemember/errors'; import { $projectId } from 'app/store/nanostores/projectId'; import type { UseStore } from 'idb-keyval'; -import { - clear, - createStore as createIDBKeyValStore, - get, - set, -} from 'idb-keyval'; +import { clear, createStore as createIDBKeyValStore, get, set } from 'idb-keyval'; import { action, atom } from 'nanostores'; import type { Driver } from 'redux-remember'; // Create a custom idb-keyval store (just needed to customize the name) -export const $idbKeyValStore = atom( - createIDBKeyValStore('invoke', 'invoke-store') -); +export const $idbKeyValStore = atom(createIDBKeyValStore('invoke', 'invoke-store')); export const clearIdbKeyValStore = action($idbKeyValStore, 'clear', (store) => { clear(store.get()); diff --git a/invokeai/frontend/web/src/app/store/middleware/debugLoggerMiddleware.ts b/invokeai/frontend/web/src/app/store/middleware/debugLoggerMiddleware.ts index 501a8146ec..b6df6dab94 100644 --- a/invokeai/frontend/web/src/app/store/middleware/debugLoggerMiddleware.ts +++ b/invokeai/frontend/web/src/app/store/middleware/debugLoggerMiddleware.ts @@ -4,13 +4,12 @@ import { diff } from 'jsondiffpatch'; /** * Super simple logger middleware. Useful for debugging when the redux devtools are awkward. */ -export const debugLoggerMiddleware: Middleware = - (api: MiddlewareAPI) => (next) => (action) => { - const originalState = api.getState(); - console.log('REDUX: dispatching', action); - const result = next(action); - const nextState = api.getState(); - console.log('REDUX: next state', nextState); - console.log('REDUX: diff', diff(originalState, nextState)); - return result; - }; +export const debugLoggerMiddleware: Middleware = (api: MiddlewareAPI) => (next) => (action) => { + const originalState = api.getState(); + console.log('REDUX: dispatching', action); + const result = next(action); + const nextState = api.getState(); + console.log('REDUX: next state', nextState); + console.log('REDUX: diff', diff(originalState, nextState)); + return result; +}; diff --git a/invokeai/frontend/web/src/app/store/middleware/devtools/actionSanitizer.ts b/invokeai/frontend/web/src/app/store/middleware/devtools/actionSanitizer.ts index 9c7bae725b..f4fa2766e6 100644 --- a/invokeai/frontend/web/src/app/store/middleware/devtools/actionSanitizer.ts +++ b/invokeai/frontend/web/src/app/store/middleware/devtools/actionSanitizer.ts @@ -35,8 +35,7 @@ export const actionSanitizer = (action: A): A => { if (socketGeneratorProgress.match(action)) { const sanitized = cloneDeep(action); if (sanitized.payload.data.progress_image) { - sanitized.payload.data.progress_image.dataURL = - ''; + sanitized.payload.data.progress_image.dataURL = ''; } return sanitized; } diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts index 0b3accfd4d..1d21215d9d 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts @@ -1,9 +1,4 @@ -import type { - ListenerEffect, - TypedAddListener, - TypedStartListening, - UnknownAction, -} from '@reduxjs/toolkit'; +import type { ListenerEffect, TypedAddListener, TypedStartListening, UnknownAction } from '@reduxjs/toolkit'; import { addListener, createListenerMiddleware } from '@reduxjs/toolkit'; import { addGalleryImageClickedListener } from 'app/store/middleware/listenerMiddleware/listeners/galleryImageClicked'; import type { AppDispatch, RootState } from 'app/store/store'; @@ -47,10 +42,7 @@ import { import { addImagesStarredListener } from './listeners/imagesStarred'; import { addImagesUnstarredListener } from './listeners/imagesUnstarred'; import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected'; -import { - addImageUploadedFulfilledListener, - addImageUploadedRejectedListener, -} from './listeners/imageUploaded'; +import { addImageUploadedFulfilledListener, addImageUploadedRejectedListener } from './listeners/imageUploaded'; import { addInitialImageSelectedListener } from './listeners/initialImageSelected'; import { addModelSelectedListener } from './listeners/modelSelected'; import { addModelsLoadedListener } from './listeners/modelsLoaded'; @@ -78,19 +70,11 @@ export const listenerMiddleware = createListenerMiddleware(); export type AppStartListening = TypedStartListening; -export const startAppListening = - listenerMiddleware.startListening as AppStartListening; +export const startAppListening = listenerMiddleware.startListening as AppStartListening; -export const addAppListener = addListener as TypedAddListener< - RootState, - AppDispatch ->; +export const addAppListener = addListener as TypedAddListener; -export type AppListenerEffect = ListenerEffect< - UnknownAction, - RootState, - AppDispatch ->; +export type AppListenerEffect = ListenerEffect; /** * The RTK listener middleware is a lightweight alternative sagas/observables. diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addCommitStagingAreaImageListener.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addCommitStagingAreaImageListener.ts index 2dbf68a837..2c5fbfbbe4 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addCommitStagingAreaImageListener.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addCommitStagingAreaImageListener.ts @@ -1,10 +1,6 @@ import { isAnyOf } from '@reduxjs/toolkit'; import { logger } from 'app/logging/logger'; -import { - canvasBatchIdsReset, - commitStagingAreaImage, - discardStagedImages, -} from 'features/canvas/store/canvasSlice'; +import { canvasBatchIdsReset, commitStagingAreaImage, discardStagedImages } from 'features/canvas/store/canvasSlice'; import { addToast } from 'features/system/store/systemSlice'; import { t } from 'i18next'; import { queueApi } from 'services/api/endpoints/queue'; @@ -23,10 +19,7 @@ export const addCommitStagingAreaImageListener = () => { try { const req = dispatch( - queueApi.endpoints.cancelByBatchIds.initiate( - { batch_ids: batchIds }, - { fixedCacheKey: 'cancelByBatchIds' } - ) + queueApi.endpoints.cancelByBatchIds.initiate({ batch_ids: batchIds }, { fixedCacheKey: 'cancelByBatchIds' }) ); const { canceled } = await req.unwrap(); req.reset(); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts index ed85aa2714..3c9b245b11 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts @@ -12,15 +12,9 @@ export const appStarted = createAction('app/appStarted'); export const addFirstListImagesListener = () => { startAppListening({ matcher: imagesApi.endpoints.listImages.matchFulfilled, - effect: async ( - action, - { dispatch, unsubscribe, cancelActiveListeners } - ) => { + effect: async (action, { dispatch, unsubscribe, cancelActiveListeners }) => { // Only run this listener on the first listImages request for no-board images - if ( - action.meta.arg.queryCacheKey !== - getListImagesUrl({ board_id: 'none', categories: IMAGE_CATEGORIES }) - ) { + if (action.meta.arg.queryCacheKey !== getListImagesUrl({ board_id: 'none', categories: IMAGE_CATEGORIES })) { return; } diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts index 52090f7ab7..3fc9cdda44 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts @@ -1,8 +1,5 @@ import { setInfillMethod } from 'features/parameters/store/generationSlice'; -import { - shouldUseNSFWCheckerChanged, - shouldUseWatermarkerChanged, -} from 'features/system/store/systemSlice'; +import { shouldUseNSFWCheckerChanged, shouldUseWatermarkerChanged } from 'features/system/store/systemSlice'; import { appInfoApi } from 'services/api/endpoints/appInfo'; import { startAppListening } from '..'; @@ -11,11 +8,7 @@ export const addAppConfigReceivedListener = () => { startAppListening({ matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled, effect: async (action, { getState, dispatch }) => { - const { - infill_methods = [], - nsfw_methods = [], - watermarking_methods = [], - } = action.payload; + const { infill_methods = [], nsfw_methods = [], watermarking_methods = [] } = action.payload; const infillMethod = getState().generation.infillMethod; if (!infill_methods.includes(infillMethod)) { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts index d848434df9..6419f840ec 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts @@ -1,4 +1,4 @@ -import { createStandaloneToast, theme, TOAST_OPTIONS } from '@invoke-ai/ui'; +import { createStandaloneToast, theme, TOAST_OPTIONS } from '@invoke-ai/ui-library'; import { logger } from 'app/logging/logger'; import { parseify } from 'common/util/serialize'; import { zPydanticValidationError } from 'features/system/store/zodSchemas'; @@ -20,10 +20,7 @@ export const addBatchEnqueuedListener = () => { effect: async (action) => { const response = action.payload; const arg = action.meta.arg.originalArgs; - logger('queue').debug( - { enqueueResult: parseify(response) }, - 'Batch enqueued' - ); + logger('queue').debug({ enqueueResult: parseify(response) }, 'Batch enqueued'); if (!toast.isActive('batch-queued')) { toast({ @@ -53,10 +50,7 @@ export const addBatchEnqueuedListener = () => { status: 'error', description: 'Unknown Error', }); - logger('queue').error( - { batchConfig: parseify(arg), error: parseify(response) }, - t('queue.batchFailedToQueue') - ); + logger('queue').error({ batchConfig: parseify(arg), error: parseify(response) }, t('queue.batchFailedToQueue')); return; } @@ -81,10 +75,7 @@ export const addBatchEnqueuedListener = () => { status: 'error', }); } - logger('queue').error( - { batchConfig: parseify(arg), error: parseify(response) }, - t('queue.batchFailedToQueue') - ); + logger('queue').error({ batchConfig: parseify(arg), error: parseify(response) }, t('queue.batchFailedToQueue')); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts index 83fab1df54..2e77896ad3 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts @@ -22,13 +22,7 @@ export const addDeleteBoardAndImagesFulfilledListener = () => { const { generation, canvas, nodes, controlAdapters } = getState(); deleted_images.forEach((image_name) => { - const imageUsage = getImageUsage( - generation, - canvas, - nodes, - controlAdapters, - image_name - ); + const imageUsage = getImageUsage(generation, canvas, nodes, controlAdapters, image_name); if (imageUsage.isInitialImage && !wasInitialImageReset) { dispatch(clearInitialImage()); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardIdSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardIdSelected.ts index 0bf5e9e264..c93381f0f2 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardIdSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardIdSelected.ts @@ -1,13 +1,6 @@ import { isAnyOf } from '@reduxjs/toolkit'; -import { - boardIdSelected, - galleryViewChanged, - imageSelected, -} from 'features/gallery/store/gallerySlice'; -import { - ASSETS_CATEGORIES, - IMAGE_CATEGORIES, -} from 'features/gallery/store/types'; +import { boardIdSelected, galleryViewChanged, imageSelected } from 'features/gallery/store/gallerySlice'; +import { ASSETS_CATEGORIES, IMAGE_CATEGORIES } from 'features/gallery/store/types'; import { imagesApi } from 'services/api/endpoints/images'; import { imagesSelectors } from 'services/api/util'; @@ -16,53 +9,35 @@ import { startAppListening } from '..'; export const addBoardIdSelectedListener = () => { startAppListening({ matcher: isAnyOf(boardIdSelected, galleryViewChanged), - effect: async ( - action, - { getState, dispatch, condition, cancelActiveListeners } - ) => { + effect: async (action, { getState, dispatch, condition, cancelActiveListeners }) => { // Cancel any in-progress instances of this listener, we don't want to select an image from a previous board cancelActiveListeners(); const state = getState(); - const board_id = boardIdSelected.match(action) - ? action.payload.boardId - : state.gallery.selectedBoardId; + const board_id = boardIdSelected.match(action) ? action.payload.boardId : state.gallery.selectedBoardId; - const galleryView = galleryViewChanged.match(action) - ? action.payload - : state.gallery.galleryView; + const galleryView = galleryViewChanged.match(action) ? action.payload : state.gallery.galleryView; // when a board is selected, we need to wait until the board has loaded *some* images, then select the first one - const categories = - galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES; + const categories = galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES; const queryArgs = { board_id: board_id ?? 'none', categories }; // wait until the board has some images - maybe it already has some from a previous fetch // must use getState() to ensure we do not have stale state const isSuccess = await condition( - () => - imagesApi.endpoints.listImages.select(queryArgs)(getState()) - .isSuccess, + () => imagesApi.endpoints.listImages.select(queryArgs)(getState()).isSuccess, 5000 ); if (isSuccess) { // the board was just changed - we can select the first image - const { data: boardImagesData } = - imagesApi.endpoints.listImages.select(queryArgs)(getState()); + const { data: boardImagesData } = imagesApi.endpoints.listImages.select(queryArgs)(getState()); - if ( - boardImagesData && - boardIdSelected.match(action) && - action.payload.selectedImageName - ) { + if (boardImagesData && boardIdSelected.match(action) && action.payload.selectedImageName) { const firstImage = imagesSelectors.selectAll(boardImagesData)[0]; - const selectedImage = imagesSelectors.selectById( - boardImagesData, - action.payload.selectedImageName - ); + const selectedImage = imagesSelectors.selectById(boardImagesData, action.payload.selectedImageName); dispatch(imageSelected(selectedImage || firstImage || null)); } else { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts index ec2c2388e5..a4ae936ada 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts @@ -11,9 +11,7 @@ export const addCanvasCopiedToClipboardListener = () => { startAppListening({ actionCreator: canvasCopiedToClipboard, effect: async (action, { dispatch, getState }) => { - const moduleLog = $logger - .get() - .child({ namespace: 'canvasCopiedToClipboardListener' }); + const moduleLog = $logger.get().child({ namespace: 'canvasCopiedToClipboardListener' }); const state = getState(); try { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts index 0cbdb8bfcc..af37afa8d5 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts @@ -11,9 +11,7 @@ export const addCanvasDownloadedAsImageListener = () => { startAppListening({ actionCreator: canvasDownloadedAsImage, effect: async (action, { dispatch, getState }) => { - const moduleLog = $logger - .get() - .child({ namespace: 'canvasSavedToGalleryListener' }); + const moduleLog = $logger.get().child({ namespace: 'canvasSavedToGalleryListener' }); const state = getState(); let blob; @@ -32,9 +30,7 @@ export const addCanvasDownloadedAsImageListener = () => { } downloadBlob(blob, 'canvas.png'); - dispatch( - addToast({ title: t('toast.canvasDownloaded'), status: 'success' }) - ); + dispatch(addToast({ title: t('toast.canvasDownloaded'), status: 'success' })); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts index 946f413d34..f29a095c1f 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts @@ -13,9 +13,7 @@ export const addCanvasMergedListener = () => { startAppListening({ actionCreator: canvasMerged, effect: async (action, { dispatch }) => { - const moduleLog = $logger - .get() - .child({ namespace: 'canvasCopiedToClipboardListener' }); + const moduleLog = $logger.get().child({ namespace: 'canvasCopiedToClipboardListener' }); const blob = await getFullBaseLayerBlob(); if (!blob) { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts index 78e69d71c1..d194195665 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts @@ -21,11 +21,7 @@ type AnyControlAdapterParamChangeAction = | ReturnType | ReturnType; -const predicate: AnyListenerPredicate = ( - action, - state, - prevState -) => { +const predicate: AnyListenerPredicate = (action, state, prevState) => { const isActionMatched = controlAdapterProcessorParamsChanged.match(action) || controlAdapterModelChanged.match(action) || @@ -40,12 +36,7 @@ const predicate: AnyListenerPredicate = ( const { id } = action.payload; const prevCA = selectControlAdapterById(prevState.controlAdapters, id); const ca = selectControlAdapterById(state.controlAdapters, id); - if ( - !prevCA || - !isControlNetOrT2IAdapter(prevCA) || - !ca || - !isControlNetOrT2IAdapter(ca) - ) { + if (!prevCA || !isControlNetOrT2IAdapter(prevCA) || !ca || !isControlNetOrT2IAdapter(ca)) { return false; } diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts index 61316231cc..fba274beb8 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts @@ -64,37 +64,28 @@ export const addControlNetImageProcessedListener = () => { ); const enqueueResult = await req.unwrap(); req.reset(); - log.debug( - { enqueueResult: parseify(enqueueResult) }, - t('queue.graphQueued') - ); + log.debug({ enqueueResult: parseify(enqueueResult) }, t('queue.graphQueued')); const [invocationCompleteAction] = await take( (action): action is ReturnType => socketInvocationComplete.match(action) && - action.payload.data.queue_batch_id === - enqueueResult.batch.batch_id && + action.payload.data.queue_batch_id === enqueueResult.batch.batch_id && action.payload.data.source_node_id === nodeId ); // We still have to check the output type if (isImageOutput(invocationCompleteAction.payload.data.result)) { - const { image_name } = - invocationCompleteAction.payload.data.result.image; + const { image_name } = invocationCompleteAction.payload.data.result.image; // Wait for the ImageDTO to be received const [{ payload }] = await take( (action) => - imagesApi.endpoints.getImageDTO.matchFulfilled(action) && - action.payload.image_name === image_name + imagesApi.endpoints.getImageDTO.matchFulfilled(action) && action.payload.image_name === image_name ); const processedControlImage = payload as ImageDTO; - log.debug( - { controlNetId: action.payload, processedControlImage }, - 'ControlNet image processed' - ); + log.debug({ controlNetId: action.payload, processedControlImage }, 'ControlNet image processed'); // Update the processed image in the store dispatch( @@ -105,10 +96,7 @@ export const addControlNetImageProcessedListener = () => { ); } } catch (error) { - log.error( - { enqueueBatchArg: parseify(enqueueBatchArg) }, - t('queue.graphFailedToQueue') - ); + log.error({ enqueueBatchArg: parseify(enqueueBatchArg) }, t('queue.graphFailedToQueue')); if (error instanceof Object) { if ('data' in error && 'status' in error) { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedCanvas.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedCanvas.ts index a803441c59..7847448d3e 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedCanvas.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedCanvas.ts @@ -2,10 +2,7 @@ import { logger } from 'app/logging/logger'; import { enqueueRequested } from 'app/store/actions'; import openBase64ImageInTab from 'common/util/openBase64ImageInTab'; import { parseify } from 'common/util/serialize'; -import { - canvasBatchIdAdded, - stagingAreaInitialized, -} from 'features/canvas/store/canvasSlice'; +import { canvasBatchIdAdded, stagingAreaInitialized } from 'features/canvas/store/canvasSlice'; import { blobToDataURL } from 'features/canvas/util/blobToDataURL'; import { getCanvasData } from 'features/canvas/util/getCanvasData'; import { getCanvasGenerationMode } from 'features/canvas/util/getCanvasGenerationMode'; @@ -34,20 +31,14 @@ import { startAppListening } from '..'; export const addEnqueueRequestedCanvasListener = () => { startAppListening({ predicate: (action): action is ReturnType => - enqueueRequested.match(action) && - action.payload.tabName === 'unifiedCanvas', + enqueueRequested.match(action) && action.payload.tabName === 'unifiedCanvas', effect: async (action, { getState, dispatch }) => { const log = logger('queue'); const { prepend } = action.payload; const state = getState(); - const { - layerState, - boundingBoxCoordinates, - boundingBoxDimensions, - isMaskEnabled, - shouldPreserveMaskedArea, - } = state.canvas; + const { layerState, boundingBoxCoordinates, boundingBoxDimensions, isMaskEnabled, shouldPreserveMaskedArea } = + state.canvas; // Build canvas blobs const canvasBlobsAndImageData = await getCanvasData( @@ -63,14 +54,10 @@ export const addEnqueueRequestedCanvasListener = () => { return; } - const { baseBlob, baseImageData, maskBlob, maskImageData } = - canvasBlobsAndImageData; + const { baseBlob, baseImageData, maskBlob, maskImageData } = canvasBlobsAndImageData; // Determine the generation mode - const generationMode = getCanvasGenerationMode( - baseImageData, - maskImageData - ); + const generationMode = getCanvasGenerationMode(baseImageData, maskImageData); if (state.system.enableImageDebugging) { const baseDataURL = await blobToDataURL(baseBlob); @@ -115,12 +102,7 @@ export const addEnqueueRequestedCanvasListener = () => { ).unwrap(); } - const graph = buildCanvasGraph( - state, - generationMode, - canvasInitImage, - canvasMaskImage - ); + const graph = buildCanvasGraph(state, generationMode, canvasInitImage, canvasMaskImage); log.debug({ graph: parseify(graph) }, `Canvas graph built`); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts index 547f5e5948..e1e13fadbe 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts @@ -11,9 +11,7 @@ import { startAppListening } from '..'; export const addEnqueueRequestedLinear = () => { startAppListening({ predicate: (action): action is ReturnType => - enqueueRequested.match(action) && - (action.payload.tabName === 'txt2img' || - action.payload.tabName === 'img2img'), + enqueueRequested.match(action) && (action.payload.tabName === 'txt2img' || action.payload.tabName === 'img2img'), effect: async (action, { getState, dispatch }) => { const state = getState(); const model = state.generation.model; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/galleryImageClicked.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/galleryImageClicked.ts index 4287f3ec16..cc810a2517 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/galleryImageClicked.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/galleryImageClicked.ts @@ -32,8 +32,7 @@ export const addGalleryImageClickedListener = () => { const { imageDTO, shiftKey, ctrlKey, metaKey } = action.payload; const state = getState(); const queryArgs = selectListImagesQueryArgs(state); - const { data: listImagesData } = - imagesApi.endpoints.listImages.select(queryArgs)(state); + const { data: listImagesData } = imagesApi.endpoints.listImages.select(queryArgs)(state); if (!listImagesData) { // Should never happen if we have clicked a gallery image @@ -46,12 +45,8 @@ export const addGalleryImageClickedListener = () => { if (shiftKey) { const rangeEndImageName = imageDTO.image_name; const lastSelectedImage = selection[selection.length - 1]?.image_name; - const lastClickedIndex = imageDTOs.findIndex( - (n) => n.image_name === lastSelectedImage - ); - const currentClickedIndex = imageDTOs.findIndex( - (n) => n.image_name === rangeEndImageName - ); + const lastClickedIndex = imageDTOs.findIndex((n) => n.image_name === lastSelectedImage); + const currentClickedIndex = imageDTOs.findIndex((n) => n.image_name === rangeEndImageName); if (lastClickedIndex > -1 && currentClickedIndex > -1) { // We have a valid range! const start = Math.min(lastClickedIndex, currentClickedIndex); @@ -60,15 +55,8 @@ export const addGalleryImageClickedListener = () => { dispatch(selectionChanged(selection.concat(imagesToSelect))); } } else if (ctrlKey || metaKey) { - if ( - selection.some((i) => i.image_name === imageDTO.image_name) && - selection.length > 1 - ) { - dispatch( - selectionChanged( - selection.filter((n) => n.image_name !== imageDTO.image_name) - ) - ); + if (selection.some((i) => i.image_name === imageDTO.image_name) && selection.length > 1) { + dispatch(selectionChanged(selection.filter((n) => n.image_name !== imageDTO.image_name))); } else { dispatch(selectionChanged(selection.concat(imageDTO))); } diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts index ccc6130cff..1312e54891 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts @@ -43,31 +43,21 @@ export const addRequestedSingleImageDeletionListener = () => { dispatch(isModalOpenChanged(false)); const state = getState(); - const lastSelectedImage = - state.gallery.selection[state.gallery.selection.length - 1]?.image_name; + const lastSelectedImage = state.gallery.selection[state.gallery.selection.length - 1]?.image_name; if (imageDTO && imageDTO?.image_name === lastSelectedImage) { const { image_name } = imageDTO; const baseQueryArgs = selectListImagesQueryArgs(state); - const { data } = - imagesApi.endpoints.listImages.select(baseQueryArgs)(state); + const { data } = imagesApi.endpoints.listImages.select(baseQueryArgs)(state); const cachedImageDTOs = data ? imagesSelectors.selectAll(data) : []; - const deletedImageIndex = cachedImageDTOs.findIndex( - (i) => i.image_name === image_name - ); + const deletedImageIndex = cachedImageDTOs.findIndex((i) => i.image_name === image_name); - const filteredImageDTOs = cachedImageDTOs.filter( - (i) => i.image_name !== image_name - ); + const filteredImageDTOs = cachedImageDTOs.filter((i) => i.image_name !== image_name); - const newSelectedImageIndex = clamp( - deletedImageIndex, - 0, - filteredImageDTOs.length - 1 - ); + const newSelectedImageIndex = clamp(deletedImageIndex, 0, filteredImageDTOs.length - 1); const newSelectedImageDTO = filteredImageDTOs[newSelectedImageIndex]; @@ -85,9 +75,7 @@ export const addRequestedSingleImageDeletionListener = () => { imageDTOs.forEach((imageDTO) => { // reset init image if we deleted it - if ( - getState().generation.initialImage?.imageName === imageDTO.image_name - ) { + if (getState().generation.initialImage?.imageName === imageDTO.image_name) { dispatch(clearInitialImage()); } @@ -95,8 +83,7 @@ export const addRequestedSingleImageDeletionListener = () => { forEach(selectControlAdapterAll(getState().controlAdapters), (ca) => { if ( ca.controlImage === imageDTO.image_name || - (isControlNetOrT2IAdapter(ca) && - ca.processedControlImage === imageDTO.image_name) + (isControlNetOrT2IAdapter(ca) && ca.processedControlImage === imageDTO.image_name) ) { dispatch( controlAdapterImageChanged({ @@ -120,10 +107,7 @@ export const addRequestedSingleImageDeletionListener = () => { } forEach(node.data.inputs, (input) => { - if ( - isImageFieldInputInstance(input) && - input.value?.image_name === imageDTO.image_name - ) { + if (isImageFieldInputInstance(input) && input.value?.image_name === imageDTO.image_name) { dispatch( fieldImageValueChanged({ nodeId: node.data.id, @@ -137,24 +121,16 @@ export const addRequestedSingleImageDeletionListener = () => { }); // Delete from server - const { requestId } = dispatch( - imagesApi.endpoints.deleteImage.initiate(imageDTO) - ); + const { requestId } = dispatch(imagesApi.endpoints.deleteImage.initiate(imageDTO)); // Wait for successful deletion, then trigger boards to re-fetch const wasImageDeleted = await condition( - (action) => - imagesApi.endpoints.deleteImage.matchFulfilled(action) && - action.meta.requestId === requestId, + (action) => imagesApi.endpoints.deleteImage.matchFulfilled(action) && action.meta.requestId === requestId, 30000 ); if (wasImageDeleted) { - dispatch( - api.util.invalidateTags([ - { type: 'Board', id: imageDTO.board_id ?? 'none' }, - ]) - ); + dispatch(api.util.invalidateTags([{ type: 'Board', id: imageDTO.board_id ?? 'none' }])); } }, }); @@ -176,17 +152,12 @@ export const addRequestedMultipleImageDeletionListener = () => { try { // Delete from server - await dispatch( - imagesApi.endpoints.deleteImages.initiate({ imageDTOs }) - ).unwrap(); + await dispatch(imagesApi.endpoints.deleteImages.initiate({ imageDTOs })).unwrap(); const state = getState(); const queryArgs = selectListImagesQueryArgs(state); - const { data } = - imagesApi.endpoints.listImages.select(queryArgs)(state); + const { data } = imagesApi.endpoints.listImages.select(queryArgs)(state); - const newSelectedImageDTO = data - ? imagesSelectors.selectAll(data)[0] - : undefined; + const newSelectedImageDTO = data ? imagesSelectors.selectAll(data)[0] : undefined; if (newSelectedImageDTO) { dispatch(imageSelected(newSelectedImageDTO)); @@ -204,10 +175,7 @@ export const addRequestedMultipleImageDeletionListener = () => { imageDTOs.forEach((imageDTO) => { // reset init image if we deleted it - if ( - getState().generation.initialImage?.imageName === - imageDTO.image_name - ) { + if (getState().generation.initialImage?.imageName === imageDTO.image_name) { dispatch(clearInitialImage()); } @@ -215,8 +183,7 @@ export const addRequestedMultipleImageDeletionListener = () => { forEach(selectControlAdapterAll(getState().controlAdapters), (ca) => { if ( ca.controlImage === imageDTO.image_name || - (isControlNetOrT2IAdapter(ca) && - ca.processedControlImage === imageDTO.image_name) + (isControlNetOrT2IAdapter(ca) && ca.processedControlImage === imageDTO.image_name) ) { dispatch( controlAdapterImageChanged({ @@ -240,10 +207,7 @@ export const addRequestedMultipleImageDeletionListener = () => { } forEach(node.data.inputs, (input) => { - if ( - isImageFieldInputInstance(input) && - input.value?.image_name === imageDTO.image_name - ) { + if (isImageFieldInputInstance(input) && input.value?.image_name === imageDTO.image_name) { dispatch( fieldImageValueChanged({ nodeId: node.data.id, @@ -295,10 +259,7 @@ export const addImageDeletedRejectedListener = () => { matcher: imagesApi.endpoints.deleteImage.matchRejected, effect: (action) => { const log = logger('images'); - log.debug( - { imageDTO: action.meta.arg.originalArgs }, - 'Unable to delete image' - ); + log.debug({ imageDTO: action.meta.arg.originalArgs }, 'Unable to delete image'); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts index fdd5b45907..268aac25d9 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts @@ -6,16 +6,10 @@ import { controlAdapterImageChanged, controlAdapterIsEnabledChanged, } from 'features/controlAdapters/store/controlAdaptersSlice'; -import type { - TypesafeDraggableData, - TypesafeDroppableData, -} from 'features/dnd/types'; +import type { TypesafeDraggableData, TypesafeDroppableData } from 'features/dnd/types'; import { imageSelected } from 'features/gallery/store/gallerySlice'; import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice'; -import { - initialImageChanged, - selectOptimalDimension, -} from 'features/parameters/store/generationSlice'; +import { initialImageChanged, selectOptimalDimension } from 'features/parameters/store/generationSlice'; import { imagesApi } from 'services/api/endpoints/images'; import { startAppListening } from '../'; @@ -35,15 +29,9 @@ export const addImageDroppedListener = () => { if (activeData.payloadType === 'IMAGE_DTO') { log.debug({ activeData, overData }, 'Image dropped'); } else if (activeData.payloadType === 'GALLERY_SELECTION') { - log.debug( - { activeData, overData }, - `Images (${getState().gallery.selection.length}) dropped` - ); + log.debug({ activeData, overData }, `Images (${getState().gallery.selection.length}) dropped`); } else if (activeData.payloadType === 'NODE_FIELD') { - log.debug( - { activeData: parseify(activeData), overData: parseify(overData) }, - 'Node field dropped' - ); + log.debug({ activeData: parseify(activeData), overData: parseify(overData) }, 'Node field dropped'); } else { log.debug({ activeData, overData }, `Unknown payload dropped`); } @@ -104,12 +92,7 @@ export const addImageDroppedListener = () => { activeData.payloadType === 'IMAGE_DTO' && activeData.payload.imageDTO ) { - dispatch( - setInitialCanvasImage( - activeData.payload.imageDTO, - selectOptimalDimension(getState()) - ) - ); + dispatch(setInitialCanvasImage(activeData.payload.imageDTO, selectOptimalDimension(getState()))); return; } @@ -191,10 +174,7 @@ export const addImageDroppedListener = () => { /** * Multiple images dropped on user board */ - if ( - overData.actionType === 'ADD_TO_BOARD' && - activeData.payloadType === 'GALLERY_SELECTION' - ) { + if (overData.actionType === 'ADD_TO_BOARD' && activeData.payloadType === 'GALLERY_SELECTION') { const imageDTOs = getState().gallery.selection; const { boardId } = overData.context; dispatch( @@ -209,10 +189,7 @@ export const addImageDroppedListener = () => { /** * Multiple images dropped on 'none' board */ - if ( - overData.actionType === 'REMOVE_FROM_BOARD' && - activeData.payloadType === 'GALLERY_SELECTION' - ) { + if (overData.actionType === 'REMOVE_FROM_BOARD' && activeData.payloadType === 'GALLERY_SELECTION') { const imageDTOs = getState().gallery.selection; dispatch( imagesApi.endpoints.removeImagesFromBoard.initiate({ diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts index ccc14165a3..03921264a2 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts @@ -1,9 +1,6 @@ import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions'; import { selectImageUsage } from 'features/deleteImageModal/store/selectors'; -import { - imagesToDeleteSelected, - isModalOpenChanged, -} from 'features/deleteImageModal/store/slice'; +import { imagesToDeleteSelected, isModalOpenChanged } from 'features/deleteImageModal/store/slice'; import { startAppListening } from '..'; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts index fdcfc7b360..d17727fcdc 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts @@ -1,4 +1,4 @@ -import type { UseToastOptions } from '@invoke-ai/ui'; +import type { UseToastOptions } from '@invoke-ai/ui-library'; import { logger } from 'app/logging/logger'; import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice'; import { @@ -6,10 +6,7 @@ import { controlAdapterIsEnabledChanged, } from 'features/controlAdapters/store/controlAdaptersSlice'; import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice'; -import { - initialImageChanged, - selectOptimalDimension, -} from 'features/parameters/store/generationSlice'; +import { initialImageChanged, selectOptimalDimension } from 'features/parameters/store/generationSlice'; import { addToast } from 'features/system/store/systemSlice'; import { t } from 'i18next'; import { omit } from 'lodash-es'; @@ -79,9 +76,7 @@ export const addImageUploadedFulfilledListener = () => { } if (postUploadAction?.type === 'SET_CANVAS_INITIAL_IMAGE') { - dispatch( - setInitialCanvasImage(imageDTO, selectOptimalDimension(state)) - ); + dispatch(setInitialCanvasImage(imageDTO, selectOptimalDimension(state))); dispatch( addToast({ ...DEFAULT_UPLOADED_TOAST, @@ -127,9 +122,7 @@ export const addImageUploadedFulfilledListener = () => { if (postUploadAction?.type === 'SET_NODES_IMAGE') { const { nodeId, fieldName } = postUploadAction; - dispatch( - fieldImageValueChanged({ nodeId, fieldName, value: imageDTO }) - ); + dispatch(fieldImageValueChanged({ nodeId, fieldName, value: imageDTO })); dispatch( addToast({ ...DEFAULT_UPLOADED_TOAST, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts index 09598440a5..93e921e911 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts @@ -11,11 +11,7 @@ export const addInitialImageSelectedListener = () => { actionCreator: initialImageSelected, effect: (action, { dispatch }) => { if (!action.payload) { - dispatch( - addToast( - makeToast({ title: t('toast.imageNotLoadedDesc'), status: 'error' }) - ) - ); + dispatch(addToast(makeToast({ title: t('toast.imageNotLoadedDesc'), status: 'error' }))); return; } diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts index fae6925ad5..7638c5522a 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts @@ -5,10 +5,7 @@ import { } from 'features/controlAdapters/store/controlAdaptersSlice'; import { loraRemoved } from 'features/lora/store/loraSlice'; import { modelSelected } from 'features/parameters/store/actions'; -import { - modelChanged, - vaeSelected, -} from 'features/parameters/store/generationSlice'; +import { modelChanged, vaeSelected } from 'features/parameters/store/generationSlice'; import { zParameterModel } from 'features/parameters/types/parameterSchemas'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; @@ -27,18 +24,14 @@ export const addModelSelectedListener = () => { const result = zParameterModel.safeParse(action.payload); if (!result.success) { - log.error( - { error: result.error.format() }, - 'Failed to parse main model' - ); + log.error({ error: result.error.format() }, 'Failed to parse main model'); return; } const newModel = result.data; const newBaseModel = newModel.base_model; - const didBaseModelChange = - state.generation.model?.base_model !== newBaseModel; + const didBaseModelChange = state.generation.model?.base_model !== newBaseModel; if (didBaseModelChange) { // we may need to reset some incompatible submodels @@ -62,9 +55,7 @@ export const addModelSelectedListener = () => { // handle incompatible controlnets selectControlAdapterAll(state.controlAdapters).forEach((ca) => { if (ca.model?.base_model !== newBaseModel) { - dispatch( - controlAdapterIsEnabledChanged({ id: ca.id, isEnabled: false }) - ); + dispatch(controlAdapterIsEnabledChanged({ id: ca.id, isEnabled: false })); modelsCleared += 1; } }); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts index 1e50d3578b..0ffe88cd07 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts @@ -6,41 +6,24 @@ import { selectAllT2IAdapters, } from 'features/controlAdapters/store/controlAdaptersSlice'; import { loraRemoved } from 'features/lora/store/loraSlice'; -import { - modelChanged, - vaeSelected, -} from 'features/parameters/store/generationSlice'; -import { - zParameterModel, - zParameterVAEModel, -} from 'features/parameters/types/parameterSchemas'; +import { modelChanged, vaeSelected } from 'features/parameters/store/generationSlice'; +import { zParameterModel, zParameterVAEModel } from 'features/parameters/types/parameterSchemas'; import { refinerModelChanged } from 'features/sdxl/store/sdxlSlice'; import { forEach, some } from 'lodash-es'; -import { - mainModelsAdapterSelectors, - modelsApi, - vaeModelsAdapterSelectors, -} from 'services/api/endpoints/models'; +import { mainModelsAdapterSelectors, modelsApi, vaeModelsAdapterSelectors } from 'services/api/endpoints/models'; import type { TypeGuardFor } from 'services/api/types'; import { startAppListening } from '..'; export const addModelsLoadedListener = () => { startAppListening({ - predicate: ( - action - ): action is TypeGuardFor< - typeof modelsApi.endpoints.getMainModels.matchFulfilled - > => + predicate: (action): action is TypeGuardFor => modelsApi.endpoints.getMainModels.matchFulfilled(action) && !action.meta.arg.originalArgs.includes('sdxl-refiner'), effect: async (action, { getState, dispatch }) => { // models loaded, we need to ensure the selected model is available and if not, select the first one const log = logger('models'); - log.info( - { models: action.payload.entities }, - `Main models loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `Main models loaded (${action.payload.ids.length})`); const currentModel = getState().generation.model; const models = mainModelsAdapterSelectors.selectAll(action.payload); @@ -67,10 +50,7 @@ export const addModelsLoadedListener = () => { const result = zParameterModel.safeParse(models[0]); if (!result.success) { - log.error( - { error: result.error.format() }, - 'Failed to parse main model' - ); + log.error({ error: result.error.format() }, 'Failed to parse main model'); return; } @@ -78,20 +58,12 @@ export const addModelsLoadedListener = () => { }, }); startAppListening({ - predicate: ( - action - ): action is TypeGuardFor< - typeof modelsApi.endpoints.getMainModels.matchFulfilled - > => - modelsApi.endpoints.getMainModels.matchFulfilled(action) && - action.meta.arg.originalArgs.includes('sdxl-refiner'), + predicate: (action): action is TypeGuardFor => + modelsApi.endpoints.getMainModels.matchFulfilled(action) && action.meta.arg.originalArgs.includes('sdxl-refiner'), effect: async (action, { getState, dispatch }) => { // models loaded, we need to ensure the selected model is available and if not, select the first one const log = logger('models'); - log.info( - { models: action.payload.entities }, - `SDXL Refiner models loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `SDXL Refiner models loaded (${action.payload.ids.length})`); const currentModel = getState().sdxl.refinerModel; const models = mainModelsAdapterSelectors.selectAll(action.payload); @@ -122,10 +94,7 @@ export const addModelsLoadedListener = () => { effect: async (action, { getState, dispatch }) => { // VAEs loaded, need to reset the VAE is it's no longer available const log = logger('models'); - log.info( - { models: action.payload.entities }, - `VAEs loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `VAEs loaded (${action.payload.ids.length})`); const currentVae = getState().generation.vae; @@ -136,9 +105,7 @@ export const addModelsLoadedListener = () => { const isCurrentVAEAvailable = some( action.payload.entities, - (m) => - m?.model_name === currentVae?.model_name && - m?.base_model === currentVae?.base_model + (m) => m?.model_name === currentVae?.model_name && m?.base_model === currentVae?.base_model ); if (isCurrentVAEAvailable) { @@ -156,10 +123,7 @@ export const addModelsLoadedListener = () => { const result = zParameterVAEModel.safeParse(firstModel); if (!result.success) { - log.error( - { error: result.error.format() }, - 'Failed to parse VAE model' - ); + log.error({ error: result.error.format() }, 'Failed to parse VAE model'); return; } @@ -171,19 +135,14 @@ export const addModelsLoadedListener = () => { effect: async (action, { getState, dispatch }) => { // LoRA models loaded - need to remove missing LoRAs from state const log = logger('models'); - log.info( - { models: action.payload.entities }, - `LoRAs loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `LoRAs loaded (${action.payload.ids.length})`); const loras = getState().lora.loras; forEach(loras, (lora, id) => { const isLoRAAvailable = some( action.payload.entities, - (m) => - m?.model_name === lora?.model_name && - m?.base_model === lora?.base_model + (m) => m?.model_name === lora?.model_name && m?.base_model === lora?.base_model ); if (isLoRAAvailable) { @@ -199,17 +158,12 @@ export const addModelsLoadedListener = () => { effect: async (action, { getState, dispatch }) => { // ControlNet models loaded - need to remove missing ControlNets from state const log = logger('models'); - log.info( - { models: action.payload.entities }, - `ControlNet models loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `ControlNet models loaded (${action.payload.ids.length})`); selectAllControlNets(getState().controlAdapters).forEach((ca) => { const isModelAvailable = some( action.payload.entities, - (m) => - m?.model_name === ca?.model?.model_name && - m?.base_model === ca?.model?.base_model + (m) => m?.model_name === ca?.model?.model_name && m?.base_model === ca?.model?.base_model ); if (isModelAvailable) { @@ -225,17 +179,12 @@ export const addModelsLoadedListener = () => { effect: async (action, { getState, dispatch }) => { // ControlNet models loaded - need to remove missing ControlNets from state const log = logger('models'); - log.info( - { models: action.payload.entities }, - `T2I Adapter models loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `T2I Adapter models loaded (${action.payload.ids.length})`); selectAllT2IAdapters(getState().controlAdapters).forEach((ca) => { const isModelAvailable = some( action.payload.entities, - (m) => - m?.model_name === ca?.model?.model_name && - m?.base_model === ca?.model?.base_model + (m) => m?.model_name === ca?.model?.model_name && m?.base_model === ca?.model?.base_model ); if (isModelAvailable) { @@ -251,17 +200,12 @@ export const addModelsLoadedListener = () => { effect: async (action, { getState, dispatch }) => { // ControlNet models loaded - need to remove missing ControlNets from state const log = logger('models'); - log.info( - { models: action.payload.entities }, - `IP Adapter models loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `IP Adapter models loaded (${action.payload.ids.length})`); selectAllIPAdapters(getState().controlAdapters).forEach((ca) => { const isModelAvailable = some( action.payload.entities, - (m) => - m?.model_name === ca?.model?.model_name && - m?.base_model === ca?.model?.base_model + (m) => m?.model_name === ca?.model?.model_name && m?.base_model === ca?.model?.base_model ); if (isModelAvailable) { @@ -276,10 +220,7 @@ export const addModelsLoadedListener = () => { matcher: modelsApi.endpoints.getTextualInversionModels.matchFulfilled, effect: async (action) => { const log = logger('models'); - log.info( - { models: action.payload.entities }, - `Embeddings loaded (${action.payload.ids.length})` - ); + log.info({ models: action.payload.entities }, `Embeddings loaded (${action.payload.ids.length})`); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts index 2dd36690a0..bd6cd502f6 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts @@ -15,21 +15,12 @@ import { socketConnected } from 'services/events/actions'; import { startAppListening } from '..'; -const matcher = isAnyOf( - setPositivePrompt, - combinatorialToggled, - maxPromptsChanged, - maxPromptsReset, - socketConnected -); +const matcher = isAnyOf(setPositivePrompt, combinatorialToggled, maxPromptsChanged, maxPromptsReset, socketConnected); export const addDynamicPromptsListener = () => { startAppListening({ matcher, - effect: async ( - action, - { dispatch, getState, cancelActiveListeners, delay } - ) => { + effect: async (action, { dispatch, getState, cancelActiveListeners, delay }) => { cancelActiveListeners(); const state = getState(); const { positivePrompt } = state.generation; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts index a11c49d069..4ab175cfba 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts @@ -17,16 +17,9 @@ export const addReceivedOpenAPISchemaListener = () => { log.debug({ schemaJSON }, 'Received OpenAPI schema'); const { nodesAllowlist, nodesDenylist } = getState().config; - const nodeTemplates = parseSchema( - schemaJSON, - nodesAllowlist, - nodesDenylist - ); + const nodeTemplates = parseSchema(schemaJSON, nodesAllowlist, nodesDenylist); - log.debug( - { nodeTemplates: parseify(nodeTemplates) }, - `Built ${size(nodeTemplates)} node templates` - ); + log.debug({ nodeTemplates: parseify(nodeTemplates) }, `Built ${size(nodeTemplates)} node templates`); dispatch(nodeTemplatesBuilt(nodeTemplates)); }, @@ -36,10 +29,7 @@ export const addReceivedOpenAPISchemaListener = () => { actionCreator: receivedOpenAPISchema.rejected, effect: (action) => { const log = logger('system'); - log.error( - { error: parseify(action.error) }, - 'Problem retrieving OpenAPI Schema' - ); + log.error({ error: parseify(action.error) }, 'Problem retrieving OpenAPI Schema'); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketConnected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketConnected.ts index e8e36d026c..05cb0d64b3 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketConnected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketConnected.ts @@ -16,10 +16,7 @@ const $isFirstConnection = atom(true); export const addSocketConnectedEventListener = () => { startAppListening({ actionCreator: socketConnected, - effect: async ( - action, - { dispatch, getState, cancelActiveListeners, delay } - ) => { + effect: async (action, { dispatch, getState, cancelActiveListeners, delay }) => { log.debug('Connected'); /** @@ -86,10 +83,7 @@ export const addSocketConnectedEventListener = () => { effect: async (action, { dispatch, getState }) => { const { nodeTemplates, config } = getState(); // We only want to re-fetch the schema if we don't have any node templates - if ( - !size(nodeTemplates.templates) && - !config.disabledTabs.includes('nodes') - ) { + if (!size(nodeTemplates.templates) && !config.disabledTabs.includes('nodes')) { // This request is a createAsyncThunk - resetting API state as in the above listener // will not trigger this request, so we need to manually do it. dispatch(receivedOpenAPISchema()); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts index d59ac3fb11..d49f35cd2a 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts @@ -1,17 +1,10 @@ import { logger } from 'app/logging/logger'; import { parseify } from 'common/util/serialize'; import { addImageToStagingArea } from 'features/canvas/store/canvasSlice'; -import { - boardIdSelected, - galleryViewChanged, - imageSelected, -} from 'features/gallery/store/gallerySlice'; +import { boardIdSelected, galleryViewChanged, imageSelected } from 'features/gallery/store/gallerySlice'; import { IMAGE_CATEGORIES } from 'features/gallery/store/types'; import { isImageOutput } from 'features/nodes/types/common'; -import { - LINEAR_UI_OUTPUT, - nodeIDDenyList, -} from 'features/nodes/util/graph/constants'; +import { LINEAR_UI_OUTPUT, nodeIDDenyList } from 'features/nodes/util/graph/constants'; import { boardsApi } from 'services/api/endpoints/boards'; import { imagesApi } from 'services/api/endpoints/images'; import { imagesAdapter } from 'services/api/util'; @@ -29,19 +22,12 @@ export const addInvocationCompleteEventListener = () => { actionCreator: socketInvocationComplete, effect: async (action, { dispatch, getState }) => { const { data } = action.payload; - log.debug( - { data: parseify(data) }, - `Invocation complete (${action.payload.data.node.type})` - ); + log.debug({ data: parseify(data) }, `Invocation complete (${action.payload.data.node.type})`); const { result, node, queue_batch_id, source_node_id } = data; // This complete event has an associated image output - if ( - isImageOutput(result) && - !nodeTypeDenylist.includes(node.type) && - !nodeIDDenyList.includes(source_node_id) - ) { + if (isImageOutput(result) && !nodeTypeDenylist.includes(node.type) && !nodeIDDenyList.includes(source_node_id)) { const { image_name } = result.image; const { canvas, gallery } = getState(); @@ -56,10 +42,7 @@ export const addInvocationCompleteEventListener = () => { imageDTORequest.unsubscribe(); // Add canvas images to the staging area - if ( - canvas.batchIds.includes(queue_batch_id) && - [LINEAR_UI_OUTPUT].includes(data.source_node_id) - ) { + if (canvas.batchIds.includes(queue_batch_id) && [LINEAR_UI_OUTPUT].includes(data.source_node_id)) { dispatch(addImageToStagingArea(imageDTO)); } @@ -84,21 +67,13 @@ export const addInvocationCompleteEventListener = () => { // update the total images for the board dispatch( - boardsApi.util.updateQueryData( - 'getBoardImagesTotal', - imageDTO.board_id ?? 'none', - (draft) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - draft.total += 1; - } - ) + boardsApi.util.updateQueryData('getBoardImagesTotal', imageDTO.board_id ?? 'none', (draft) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + draft.total += 1; + }) ); - dispatch( - imagesApi.util.invalidateTags([ - { type: 'Board', id: imageDTO.board_id ?? 'none' }, - ]) - ); + dispatch(imagesApi.util.invalidateTags([{ type: 'Board', id: imageDTO.board_id ?? 'none' }])); const { shouldAutoSwitch } = gallery; @@ -109,10 +84,7 @@ export const addInvocationCompleteEventListener = () => { dispatch(galleryViewChanged('images')); } - if ( - imageDTO.board_id && - imageDTO.board_id !== gallery.selectedBoardId - ) { + if (imageDTO.board_id && imageDTO.board_id !== gallery.selectedBoardId) { dispatch( boardIdSelected({ boardId: imageDTO.board_id, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts index a13a9011c5..dfc1f0dd58 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts @@ -9,10 +9,7 @@ export const addInvocationErrorEventListener = () => { startAppListening({ actionCreator: socketInvocationError, effect: (action) => { - log.error( - action.payload, - `Invocation error (${action.payload.data.node.type})` - ); + log.error(action.payload, `Invocation error (${action.payload.data.node.type})`); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationRetrievalError.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationRetrievalError.ts index 394c67dbc9..f02317c236 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationRetrievalError.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationRetrievalError.ts @@ -9,10 +9,7 @@ export const addInvocationRetrievalErrorEventListener = () => { startAppListening({ actionCreator: socketInvocationRetrievalError, effect: (action) => { - log.error( - action.payload, - `Invocation retrieval error (${action.payload.data.graph_execution_state_id})` - ); + log.error(action.payload, `Invocation retrieval error (${action.payload.data.graph_execution_state_id})`); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationStarted.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationStarted.ts index 6b293132a2..12766b2707 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationStarted.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationStarted.ts @@ -9,10 +9,7 @@ export const addInvocationStartedEventListener = () => { startAppListening({ actionCreator: socketInvocationStarted, effect: (action) => { - log.debug( - action.payload, - `Invocation started (${action.payload.data.node.type})` - ); + log.debug(action.payload, `Invocation started (${action.payload.data.node.type})`); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts index 828102bfa9..aa91c69d75 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts @@ -1,8 +1,5 @@ import { logger } from 'app/logging/logger'; -import { - socketModelLoadCompleted, - socketModelLoadStarted, -} from 'services/events/actions'; +import { socketModelLoadCompleted, socketModelLoadStarted } from 'services/events/actions'; import { startAppListening } from '../..'; @@ -12,8 +9,7 @@ export const addModelLoadEventListener = () => { startAppListening({ actionCreator: socketModelLoadStarted, effect: (action) => { - const { base_model, model_name, model_type, submodel } = - action.payload.data; + const { base_model, model_name, model_type, submodel } = action.payload.data; let message = `Model load started: ${base_model}/${model_type}/${model_name}`; @@ -28,8 +24,7 @@ export const addModelLoadEventListener = () => { startAppListening({ actionCreator: socketModelLoadCompleted, effect: (action) => { - const { base_model, model_name, model_type, submodel } = - action.payload.data; + const { base_model, model_name, model_type, submodel } = action.payload.data; let message = `Model load complete: ${base_model}/${model_type}/${model_name}`; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketQueueItemStatusChanged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketQueueItemStatusChanged.ts index a766437f15..bd5471b299 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketQueueItemStatusChanged.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketQueueItemStatusChanged.ts @@ -13,10 +13,7 @@ export const addSocketQueueItemStatusChangedEventListener = () => { // we've got new status for the queue item, batch and queue const { queue_item, batch_status, queue_status } = action.payload.data; - log.debug( - action.payload, - `Queue item ${queue_item.item_id} status updated: ${queue_item.status}` - ); + log.debug(action.payload, `Queue item ${queue_item.item_id} status updated: ${queue_item.status}`); // Update this specific queue item in the list of queue items (this is the queue item DTO, without the session) dispatch( @@ -40,35 +37,23 @@ export const addSocketQueueItemStatusChangedEventListener = () => { // Update the batch status dispatch( - queueApi.util.updateQueryData( - 'getBatchStatus', - { batch_id: batch_status.batch_id }, - () => batch_status - ) + queueApi.util.updateQueryData('getBatchStatus', { batch_id: batch_status.batch_id }, () => batch_status) ); // Update the queue item status (this is the full queue item, including the session) dispatch( - queueApi.util.updateQueryData( - 'getQueueItem', - queue_item.item_id, - (draft) => { - if (!draft) { - return; - } - Object.assign(draft, queue_item); + queueApi.util.updateQueryData('getQueueItem', queue_item.item_id, (draft) => { + if (!draft) { + return; } - ) + Object.assign(draft, queue_item); + }) ); // Invalidate caches for things we cannot update // TODO: technically, we could possibly update the current session queue item, but feels safer to just request it again dispatch( - queueApi.util.invalidateTags([ - 'CurrentSessionQueueItem', - 'NextSessionQueueItem', - 'InvocationCacheStatus', - ]) + queueApi.util.invalidateTags(['CurrentSessionQueueItem', 'NextSessionQueueItem', 'InvocationCacheStatus']) ); }, }); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSessionRetrievalError.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSessionRetrievalError.ts index e20a8cf6cb..b655a686de 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSessionRetrievalError.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSessionRetrievalError.ts @@ -9,10 +9,7 @@ export const addSessionRetrievalErrorEventListener = () => { startAppListening({ actionCreator: socketSessionRetrievalError, effect: (action) => { - log.error( - action.payload, - `Session retrieval error (${action.payload.data.graph_execution_state_id})` - ); + log.error(action.payload, `Session retrieval error (${action.payload.data.graph_execution_state_id})`); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/updateAllNodesRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/updateAllNodesRequested.ts index 371983c781..752c3b09df 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/updateAllNodesRequested.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/updateAllNodesRequested.ts @@ -3,10 +3,7 @@ import { updateAllNodesRequested } from 'features/nodes/store/actions'; import { nodeReplaced } from 'features/nodes/store/nodesSlice'; import { NodeUpdateError } from 'features/nodes/types/error'; import { isInvocationNode } from 'features/nodes/types/invocation'; -import { - getNeedsUpdate, - updateNode, -} from 'features/nodes/util/node/nodeUpdate'; +import { getNeedsUpdate, updateNode } from 'features/nodes/util/node/nodeUpdate'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; import { t } from 'i18next'; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts index 75c67a08cc..46f55ef21f 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts @@ -10,9 +10,7 @@ import type { BatchConfig, ImageDTO } from 'services/api/types'; import { startAppListening } from '..'; -export const upscaleRequested = createAction<{ imageDTO: ImageDTO }>( - `upscale/upscaleRequested` -); +export const upscaleRequested = createAction<{ imageDTO: ImageDTO }>(`upscale/upscaleRequested`); export const addUpscaleRequestedListener = () => { startAppListening({ @@ -24,8 +22,7 @@ export const addUpscaleRequestedListener = () => { const { image_name } = imageDTO; const state = getState(); - const { isAllowedToUpscale, detailTKey } = - createIsAllowedToUpscaleSelector(imageDTO)(state); + const { isAllowedToUpscale, detailTKey } = createIsAllowedToUpscaleSelector(imageDTO)(state); // if we can't upscale, show a toast and return if (!isAllowedToUpscale) { @@ -66,21 +63,11 @@ export const addUpscaleRequestedListener = () => { const enqueueResult = await req.unwrap(); req.reset(); - log.debug( - { enqueueResult: parseify(enqueueResult) }, - t('queue.graphQueued') - ); + log.debug({ enqueueResult: parseify(enqueueResult) }, t('queue.graphQueued')); } catch (error) { - log.error( - { enqueueBatchArg: parseify(enqueueBatchArg) }, - t('queue.graphFailedToQueue') - ); + log.error({ enqueueBatchArg: parseify(enqueueBatchArg) }, t('queue.graphFailedToQueue')); - if ( - error instanceof Object && - 'status' in error && - error.status === 403 - ) { + if (error instanceof Object && 'status' in error && error.status === 403) { return; } else { dispatch( diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts index 1e26ea7a0c..0b37271be7 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested.ts @@ -1,14 +1,8 @@ import { logger } from 'app/logging/logger'; import { parseify } from 'common/util/serialize'; -import { - workflowLoaded, - workflowLoadRequested, -} from 'features/nodes/store/actions'; +import { workflowLoaded, workflowLoadRequested } from 'features/nodes/store/actions'; import { $flow } from 'features/nodes/store/reactFlowInstance'; -import { - WorkflowMigrationError, - WorkflowVersionError, -} from 'features/nodes/types/error'; +import { WorkflowMigrationError, WorkflowVersionError } from 'features/nodes/types/error'; import { validateWorkflow } from 'features/nodes/util/workflow/validateWorkflow'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; @@ -28,10 +22,7 @@ export const addWorkflowLoadRequestedListener = () => { const nodeTemplates = getState().nodeTemplates.templates; try { - const { workflow: validatedWorkflow, warnings } = validateWorkflow( - workflow, - nodeTemplates - ); + const { workflow: validatedWorkflow, warnings } = validateWorkflow(workflow, nodeTemplates); if (asCopy) { // If we're loading a copy, we need to remove the ID so that the backend will create a new workflow @@ -108,10 +99,7 @@ export const addWorkflowLoadRequestedListener = () => { ); } else { // Some other error occurred - log.error( - { error: parseify(e) }, - t('nodes.unknownErrorValidatingWorkflow') - ); + log.error({ error: parseify(e) }, t('nodes.unknownErrorValidatingWorkflow')); dispatch( addToast( makeToast({ diff --git a/invokeai/frontend/web/src/app/store/nanostores/customStarUI.ts b/invokeai/frontend/web/src/app/store/nanostores/customStarUI.ts index 71a8fc4017..9f6628ac9c 100644 --- a/invokeai/frontend/web/src/app/store/nanostores/customStarUI.ts +++ b/invokeai/frontend/web/src/app/store/nanostores/customStarUI.ts @@ -1,4 +1,4 @@ -import type { MenuItemProps } from '@invoke-ai/ui'; +import type { MenuItemProps } from '@invoke-ai/ui-library'; import { atom } from 'nanostores'; export type CustomStarUi = { diff --git a/invokeai/frontend/web/src/app/store/nanostores/store.ts b/invokeai/frontend/web/src/app/store/nanostores/store.ts index 59eba50e87..aee0f0e6ef 100644 --- a/invokeai/frontend/web/src/app/store/nanostores/store.ts +++ b/invokeai/frontend/web/src/app/store/nanostores/store.ts @@ -8,6 +8,4 @@ declare global { } } -export const $store = atom< - Readonly> | undefined ->(); +export const $store = atom> | undefined>(); diff --git a/invokeai/frontend/web/src/app/store/nanostores/workflowCategories.ts b/invokeai/frontend/web/src/app/store/nanostores/workflowCategories.ts index a643219c66..e0d6107129 100644 --- a/invokeai/frontend/web/src/app/store/nanostores/workflowCategories.ts +++ b/invokeai/frontend/web/src/app/store/nanostores/workflowCategories.ts @@ -1,7 +1,4 @@ import type { WorkflowCategory } from 'features/nodes/types/workflow'; import { atom } from 'nanostores'; -export const $workflowCategories = atom([ - 'user', - 'default', -]); +export const $workflowCategories = atom(['user', 'default']); diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index 567b70786f..81088ffcbb 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -1,17 +1,10 @@ import type { ThunkDispatch, UnknownAction } from '@reduxjs/toolkit'; -import { - autoBatchEnhancer, - combineReducers, - configureStore, -} from '@reduxjs/toolkit'; +import { autoBatchEnhancer, combineReducers, configureStore } from '@reduxjs/toolkit'; import { logger } from 'app/logging/logger'; import { idbKeyValDriver } from 'app/store/enhancers/reduxRemember/driver'; import { errorHandler } from 'app/store/enhancers/reduxRemember/errors'; import { canvasPersistDenylist } from 'features/canvas/store/canvasPersistDenylist'; -import canvasReducer, { - initialCanvasState, - migrateCanvasState, -} from 'features/canvas/store/canvasSlice'; +import canvasReducer, { initialCanvasState, migrateCanvasState } from 'features/canvas/store/canvasSlice'; import changeBoardModalReducer from 'features/changeBoardModal/store/slice'; import { controlAdaptersPersistDenylist } from 'features/controlAdapters/store/controlAdaptersPersistDenylist'; import controlAdaptersReducer, { @@ -25,32 +18,17 @@ import dynamicPromptsReducer, { migrateDynamicPromptsState, } from 'features/dynamicPrompts/store/dynamicPromptsSlice'; import { galleryPersistDenylist } from 'features/gallery/store/galleryPersistDenylist'; -import galleryReducer, { - initialGalleryState, - migrateGalleryState, -} from 'features/gallery/store/gallerySlice'; -import hrfReducer, { - initialHRFState, - migrateHRFState, -} from 'features/hrf/store/hrfSlice'; -import loraReducer, { - initialLoraState, - migrateLoRAState, -} from 'features/lora/store/loraSlice'; +import galleryReducer, { initialGalleryState, migrateGalleryState } from 'features/gallery/store/gallerySlice'; +import hrfReducer, { initialHRFState, migrateHRFState } from 'features/hrf/store/hrfSlice'; +import loraReducer, { initialLoraState, migrateLoRAState } from 'features/lora/store/loraSlice'; import modelmanagerReducer, { initialModelManagerState, migrateModelManagerState, } from 'features/modelManager/store/modelManagerSlice'; import { nodesPersistDenylist } from 'features/nodes/store/nodesPersistDenylist'; -import nodesReducer, { - initialNodesState, - migrateNodesState, -} from 'features/nodes/store/nodesSlice'; +import nodesReducer, { initialNodesState, migrateNodesState } from 'features/nodes/store/nodesSlice'; import nodeTemplatesReducer from 'features/nodes/store/nodeTemplatesSlice'; -import workflowReducer, { - initialWorkflowState, - migrateWorkflowState, -} from 'features/nodes/store/workflowSlice'; +import workflowReducer, { initialWorkflowState, migrateWorkflowState } from 'features/nodes/store/workflowSlice'; import { generationPersistDenylist } from 'features/parameters/store/generationPersistDenylist'; import generationReducer, { initialGenerationState, @@ -62,21 +40,12 @@ import postprocessingReducer, { migratePostprocessingState, } from 'features/parameters/store/postprocessingSlice'; import queueReducer from 'features/queue/store/queueSlice'; -import sdxlReducer, { - initialSDXLState, - migrateSDXLState, -} from 'features/sdxl/store/sdxlSlice'; +import sdxlReducer, { initialSDXLState, migrateSDXLState } from 'features/sdxl/store/sdxlSlice'; import configReducer from 'features/system/store/configSlice'; import { systemPersistDenylist } from 'features/system/store/systemPersistDenylist'; -import systemReducer, { - initialSystemState, - migrateSystemState, -} from 'features/system/store/systemSlice'; +import systemReducer, { initialSystemState, migrateSystemState } from 'features/system/store/systemSlice'; import { uiPersistDenylist } from 'features/ui/store/uiPersistDenylist'; -import uiReducer, { - initialUIState, - migrateUIState, -} from 'features/ui/store/uiSlice'; +import uiReducer, { initialUIState, migrateUIState } from 'features/ui/store/uiSlice'; import { diff } from 'jsondiffpatch'; import { defaultsDeep, keys, omit, pick } from 'lodash-es'; import dynamicMiddlewares from 'redux-dynamic-middlewares'; @@ -206,10 +175,7 @@ const unserialize: UnserializeFunction = (data, key) => { ); return transformed; } catch (err) { - log.warn( - { error: serializeError(err) }, - `Error rehydrating slice "${key}", falling back to default initial state` - ); + log.warn({ error: serializeError(err) }, `Error rehydrating slice "${key}", falling back to default initial state`); return config.initialState; } }; @@ -229,10 +195,7 @@ const serializationDenylist: { }; export const serialize: SerializeFunction = (data, key) => { - const result = omit( - data, - serializationDenylist[key as keyof typeof serializationDenylist] ?? [] - ); + const result = omit(data, serializationDenylist[key as keyof typeof serializationDenylist] ?? []); return JSON.stringify(result); }; @@ -256,9 +219,7 @@ export const createStore = (uniqueStoreKey?: string, persist = true) => persistDebounce: 300, serialize, unserialize, - prefix: uniqueStoreKey - ? `${STORAGE_PREFIX}${uniqueStoreKey}-` - : STORAGE_PREFIX, + prefix: uniqueStoreKey ? `${STORAGE_PREFIX}${uniqueStoreKey}-` : STORAGE_PREFIX, errorHandler, }) ); @@ -278,9 +239,7 @@ export const createStore = (uniqueStoreKey?: string, persist = true) => }, }); -export type AppGetState = ReturnType< - ReturnType['getState'] ->; +export type AppGetState = ReturnType['getState']>; export type RootState = ReturnType['getState']>; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type AppThunkDispatch = ThunkDispatch; diff --git a/invokeai/frontend/web/src/common/components/IAIColorPicker.tsx b/invokeai/frontend/web/src/common/components/IAIColorPicker.tsx index bacfcff880..8c3b329f2f 100644 --- a/invokeai/frontend/web/src/common/components/IAIColorPicker.tsx +++ b/invokeai/frontend/web/src/common/components/IAIColorPicker.tsx @@ -1,17 +1,9 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { - CompositeNumberInput, - Flex, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { CompositeNumberInput, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library'; import type { CSSProperties } from 'react'; import { memo, useCallback } from 'react'; import { RgbaColorPicker } from 'react-colorful'; -import type { - ColorPickerBaseProps, - RgbaColor, -} from 'react-colorful/dist/types'; +import type { ColorPickerBaseProps, RgbaColor } from 'react-colorful/dist/types'; import { useTranslation } from 'react-i18next'; type IAIColorPickerProps = ColorPickerBaseProps & { @@ -39,30 +31,13 @@ const numberInputWidth: ChakraProps['w'] = '4.2rem'; const IAIColorPicker = (props: IAIColorPickerProps) => { const { color, onChange, withNumberInput, ...rest } = props; const { t } = useTranslation(); - const handleChangeR = useCallback( - (r: number) => onChange({ ...color, r }), - [color, onChange] - ); - const handleChangeG = useCallback( - (g: number) => onChange({ ...color, g }), - [color, onChange] - ); - const handleChangeB = useCallback( - (b: number) => onChange({ ...color, b }), - [color, onChange] - ); - const handleChangeA = useCallback( - (a: number) => onChange({ ...color, a }), - [color, onChange] - ); + const handleChangeR = useCallback((r: number) => onChange({ ...color, r }), [color, onChange]); + const handleChangeG = useCallback((g: number) => onChange({ ...color, g }), [color, onChange]); + const handleChangeB = useCallback((b: number) => onChange({ ...color, b }), [color, onChange]); + const handleChangeA = useCallback((a: number) => onChange({ ...color, a }), [color, onChange]); return ( - + {withNumberInput && ( diff --git a/invokeai/frontend/web/src/common/components/IAIDndImage.tsx b/invokeai/frontend/web/src/common/components/IAIDndImage.tsx index 500ccdfb7b..01107c21b4 100644 --- a/invokeai/frontend/web/src/common/components/IAIDndImage.tsx +++ b/invokeai/frontend/web/src/common/components/IAIDndImage.tsx @@ -1,22 +1,11 @@ -import type { ChakraProps, FlexProps, SystemStyleObject } from '@invoke-ai/ui'; -import { Flex, Icon, Image } from '@invoke-ai/ui'; -import { - IAILoadingImageFallback, - IAINoContentFallback, -} from 'common/components/IAIImageFallback'; +import type { ChakraProps, FlexProps, SystemStyleObject } from '@invoke-ai/ui-library'; +import { Flex, Icon, Image } from '@invoke-ai/ui-library'; +import { IAILoadingImageFallback, IAINoContentFallback } from 'common/components/IAIImageFallback'; import ImageMetadataOverlay from 'common/components/ImageMetadataOverlay'; import { useImageUploadButton } from 'common/hooks/useImageUploadButton'; -import type { - TypesafeDraggableData, - TypesafeDroppableData, -} from 'features/dnd/types'; +import type { TypesafeDraggableData, TypesafeDroppableData } from 'features/dnd/types'; import ImageContextMenu from 'features/gallery/components/ImageContextMenu/ImageContextMenu'; -import type { - MouseEvent, - ReactElement, - ReactNode, - SyntheticEvent, -} from 'react'; +import type { MouseEvent, ReactElement, ReactNode, SyntheticEvent } from 'react'; import { memo, useCallback, useMemo, useState } from 'react'; import { PiImageBold, PiUploadSimpleBold } from 'react-icons/pi'; import type { ImageDTO, PostUploadAction } from 'services/api/types'; @@ -161,14 +150,8 @@ const IAIDndImage = (props: IAIDndImageProps) => { - ) - } + fallbackSrc={useThumbailFallback ? imageDTO.thumbnail_url : undefined} + fallback={useThumbailFallback ? undefined : } onError={onError} draggable={false} w={imageDTO.width} @@ -179,13 +162,8 @@ const IAIDndImage = (props: IAIDndImageProps) => { sx={imageSx} data-testid={dataTestId} /> - {withMetadataOverlay && ( - - )} - + {withMetadataOverlay && } + )} {!imageDTO && !isUploadDisabled && ( @@ -198,20 +176,10 @@ const IAIDndImage = (props: IAIDndImageProps) => { )} {!imageDTO && isUploadDisabled && noContentFallback} {imageDTO && !isDragDisabled && ( - + )} {children} - {!isDropDisabled && ( - - )} + {!isDropDisabled && } )} diff --git a/invokeai/frontend/web/src/common/components/IAIDndImageIcon.tsx b/invokeai/frontend/web/src/common/components/IAIDndImageIcon.tsx index 1df0cb527a..650a0b6a14 100644 --- a/invokeai/frontend/web/src/common/components/IAIDndImageIcon.tsx +++ b/invokeai/frontend/web/src/common/components/IAIDndImageIcon.tsx @@ -1,5 +1,5 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { IconButton } from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { IconButton } from '@invoke-ai/ui-library'; import type { MouseEvent, ReactElement } from 'react'; import { memo, useMemo } from 'react'; diff --git a/invokeai/frontend/web/src/common/components/IAIDraggable.tsx b/invokeai/frontend/web/src/common/components/IAIDraggable.tsx index 678f60415d..9e0b5206bc 100644 --- a/invokeai/frontend/web/src/common/components/IAIDraggable.tsx +++ b/invokeai/frontend/web/src/common/components/IAIDraggable.tsx @@ -1,5 +1,5 @@ -import type { BoxProps } from '@invoke-ai/ui'; -import { Box } from '@invoke-ai/ui'; +import type { BoxProps } from '@invoke-ai/ui-library'; +import { Box } from '@invoke-ai/ui-library'; import { useDraggableTypesafe } from 'features/dnd/hooks/typesafeHooks'; import type { TypesafeDraggableData } from 'features/dnd/types'; import { memo, useRef } from 'react'; diff --git a/invokeai/frontend/web/src/common/components/IAIDropOverlay.tsx b/invokeai/frontend/web/src/common/components/IAIDropOverlay.tsx index a6b654a947..cd3e0cbee1 100644 --- a/invokeai/frontend/web/src/common/components/IAIDropOverlay.tsx +++ b/invokeai/frontend/web/src/common/components/IAIDropOverlay.tsx @@ -1,4 +1,4 @@ -import { Box, Flex } from '@invoke-ai/ui'; +import { Box, Flex } from '@invoke-ai/ui-library'; import type { AnimationProps } from 'framer-motion'; import { motion } from 'framer-motion'; import type { ReactNode } from 'react'; @@ -27,12 +27,7 @@ const IAIDropOverlay = (props: Props) => { const { isOver, label = t('gallery.drop') } = props; const motionId = useRef(uuidv4()); return ( - + { pointerEvents={active ? 'auto' : 'none'} > - {isValidDrop(data, active) && ( - - )} + {isValidDrop(data, active) && } ); diff --git a/invokeai/frontend/web/src/common/components/IAIFillSkeleton.tsx b/invokeai/frontend/web/src/common/components/IAIFillSkeleton.tsx index c1e51226fd..20e9fa2c68 100644 --- a/invokeai/frontend/web/src/common/components/IAIFillSkeleton.tsx +++ b/invokeai/frontend/web/src/common/components/IAIFillSkeleton.tsx @@ -1,5 +1,5 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { Box, Skeleton } from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Box, Skeleton } from '@invoke-ai/ui-library'; import { memo } from 'react'; const skeletonStyles: SystemStyleObject = { @@ -16,13 +16,7 @@ const skeletonStyles: SystemStyleObject = { const IAIFillSkeleton = () => { return ( - + ); }; diff --git a/invokeai/frontend/web/src/common/components/IAIImageFallback.tsx b/invokeai/frontend/web/src/common/components/IAIImageFallback.tsx index 4ed3aa814b..1a23c458cf 100644 --- a/invokeai/frontend/web/src/common/components/IAIImageFallback.tsx +++ b/invokeai/frontend/web/src/common/components/IAIImageFallback.tsx @@ -1,5 +1,5 @@ -import type { As, ChakraProps, FlexProps } from '@invoke-ai/ui'; -import { Flex, Icon, Skeleton, Spinner, Text } from '@invoke-ai/ui'; +import type { As, ChakraProps, FlexProps } from '@invoke-ai/ui-library'; +import { Flex, Icon, Skeleton, Spinner, Text } from '@invoke-ai/ui-library'; import { memo, useMemo } from 'react'; import { PiImageBold } from 'react-icons/pi'; import type { ImageDTO } from 'services/api/types'; @@ -19,15 +19,7 @@ export const IAILoadingImageFallback = memo((props: Props) => { } return ( - + ); @@ -77,32 +69,30 @@ type IAINoImageFallbackWithSpinnerProps = FlexProps & { label?: string; }; -export const IAINoContentFallbackWithSpinner = memo( - (props: IAINoImageFallbackWithSpinnerProps) => { - const { sx, ...rest } = props; - const styles = useMemo( - () => ({ - w: 'full', - h: 'full', - alignItems: 'center', - justifyContent: 'center', - borderRadius: 'base', - flexDir: 'column', - gap: 2, - userSelect: 'none', - opacity: 0.7, - color: 'base.500', - ...sx, - }), - [sx] - ); +export const IAINoContentFallbackWithSpinner = memo((props: IAINoImageFallbackWithSpinnerProps) => { + const { sx, ...rest } = props; + const styles = useMemo( + () => ({ + w: 'full', + h: 'full', + alignItems: 'center', + justifyContent: 'center', + borderRadius: 'base', + flexDir: 'column', + gap: 2, + userSelect: 'none', + opacity: 0.7, + color: 'base.500', + ...sx, + }), + [sx] + ); - return ( - - - {props.label && {props.label}} - - ); - } -); + return ( + + + {props.label && {props.label}} + + ); +}); IAINoContentFallbackWithSpinner.displayName = 'IAINoContentFallbackWithSpinner'; diff --git a/invokeai/frontend/web/src/common/components/ImageMetadataOverlay.tsx b/invokeai/frontend/web/src/common/components/ImageMetadataOverlay.tsx index 003ace0d1c..531b2b4298 100644 --- a/invokeai/frontend/web/src/common/components/ImageMetadataOverlay.tsx +++ b/invokeai/frontend/web/src/common/components/ImageMetadataOverlay.tsx @@ -1,4 +1,4 @@ -import { Badge, Flex } from '@invoke-ai/ui'; +import { Badge, Flex } from '@invoke-ai/ui-library'; import { memo } from 'react'; import type { ImageDTO } from 'services/api/types'; diff --git a/invokeai/frontend/web/src/common/components/ImageUploadOverlay.tsx b/invokeai/frontend/web/src/common/components/ImageUploadOverlay.tsx index dd0b250110..abd68e72cb 100644 --- a/invokeai/frontend/web/src/common/components/ImageUploadOverlay.tsx +++ b/invokeai/frontend/web/src/common/components/ImageUploadOverlay.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, Heading } from '@invoke-ai/ui'; +import { Box, Flex, Heading } from '@invoke-ai/ui-library'; import type { AnimationProps } from 'framer-motion'; import { motion } from 'framer-motion'; import { memo } from 'react'; @@ -91,9 +91,7 @@ const ImageUploadOverlay = (props: ImageUploadOverlayProps) => { ) : ( <> {t('toast.invalidUpload')} - - {t('toast.uploadFailedInvalidUploadDesc')} - + {t('toast.uploadFailedInvalidUploadDesc')} )} diff --git a/invokeai/frontend/web/src/common/components/InformationalPopover/InformationalPopover.tsx b/invokeai/frontend/web/src/common/components/InformationalPopover/InformationalPopover.tsx index cd2b320155..935212ee58 100644 --- a/invokeai/frontend/web/src/common/components/InformationalPopover/InformationalPopover.tsx +++ b/invokeai/frontend/web/src/common/components/InformationalPopover/InformationalPopover.tsx @@ -11,7 +11,7 @@ import { PopoverTrigger, Portal, Text, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { merge, omit } from 'lodash-es'; import type { ReactElement } from 'react'; @@ -28,46 +28,39 @@ type Props = { children: ReactElement; }; -export const InformationalPopover = memo( - ({ feature, children, inPortal = true, ...rest }: Props) => { - const shouldEnableInformationalPopovers = useAppSelector( - (s) => s.system.shouldEnableInformationalPopovers - ); +export const InformationalPopover = memo(({ feature, children, inPortal = true, ...rest }: Props) => { + const shouldEnableInformationalPopovers = useAppSelector((s) => s.system.shouldEnableInformationalPopovers); - const data = useMemo(() => POPOVER_DATA[feature], [feature]); + const data = useMemo(() => POPOVER_DATA[feature], [feature]); - const popoverProps = useMemo( - () => merge(omit(data, ['image', 'href', 'buttonLabel']), rest), - [data, rest] - ); + const popoverProps = useMemo(() => merge(omit(data, ['image', 'href', 'buttonLabel']), rest), [data, rest]); - if (!shouldEnableInformationalPopovers) { - return children; - } - - return ( - - {children} - {inPortal ? ( - - - - ) : ( - - )} - - ); + if (!shouldEnableInformationalPopovers) { + return children; } -); + + return ( + + {children} + {inPortal ? ( + + + + ) : ( + + )} + + ); +}); InformationalPopover.displayName = 'InformationalPopover'; @@ -79,10 +72,7 @@ type ContentProps = { const Content = ({ data, feature }: ContentProps) => { const { t } = useTranslation(); - const heading = useMemo( - () => t(`popovers.${feature}.heading`), - [feature, t] - ); + const heading = useMemo(() => t(`popovers.${feature}.heading`), [feature, t]); const paragraphs = useMemo( () => diff --git a/invokeai/frontend/web/src/common/components/InformationalPopover/constants.ts b/invokeai/frontend/web/src/common/components/InformationalPopover/constants.ts index 09d4e9c132..bdcd1ca9a4 100644 --- a/invokeai/frontend/web/src/common/components/InformationalPopover/constants.ts +++ b/invokeai/frontend/web/src/common/components/InformationalPopover/constants.ts @@ -1,4 +1,4 @@ -import type { PopoverProps } from '@invoke-ai/ui'; +import type { PopoverProps } from '@invoke-ai/ui-library'; export type Feature = | 'clipSkip' @@ -95,6 +95,4 @@ export const POPOVER_DATA: { [key in Feature]?: PopoverData } = { export const OPEN_DELAY = 1000; // in milliseconds -export const POPPER_MODIFIERS: PopoverProps['modifiers'] = [ - { name: 'preventOverflow', options: { padding: 10 } }, -]; +export const POPPER_MODIFIERS: PopoverProps['modifiers'] = [{ name: 'preventOverflow', options: { padding: 10 } }]; diff --git a/invokeai/frontend/web/src/common/components/Loading/Loading.tsx b/invokeai/frontend/web/src/common/components/Loading/Loading.tsx index 024936ebd8..dae5b40e8c 100644 --- a/invokeai/frontend/web/src/common/components/Loading/Loading.tsx +++ b/invokeai/frontend/web/src/common/components/Loading/Loading.tsx @@ -1,4 +1,4 @@ -import { Flex, Image, Spinner } from '@invoke-ai/ui'; +import { Flex, Image, Spinner } from '@invoke-ai/ui-library'; import InvokeLogoWhite from 'public/assets/images/invoke-symbol-wht-lrg.svg'; import { memo } from 'react'; @@ -6,14 +6,7 @@ import { memo } from 'react'; const Loading = () => { return ( - + { +const ScrollableContent = ({ children, maxHeight, overflowX = 'hidden', overflowY = 'scroll' }: Props) => { const overlayscrollbarsOptions = useMemo( () => getOverlayScrollbarsParams(overflowX, overflowY).options, [overflowX, overflowY] @@ -26,11 +21,7 @@ const ScrollableContent = ({ return ( - + {children} diff --git a/invokeai/frontend/web/src/common/components/SelectionOverlay.tsx b/invokeai/frontend/web/src/common/components/SelectionOverlay.tsx index 9eb1af0b99..eb50a6b9d4 100644 --- a/invokeai/frontend/web/src/common/components/SelectionOverlay.tsx +++ b/invokeai/frontend/web/src/common/components/SelectionOverlay.tsx @@ -1,4 +1,4 @@ -import { Box } from '@invoke-ai/ui'; +import { Box } from '@invoke-ai/ui-library'; import { memo, useMemo } from 'react'; type Props = { diff --git a/invokeai/frontend/web/src/common/hooks/useChakraThemeTokens.ts b/invokeai/frontend/web/src/common/hooks/useChakraThemeTokens.ts index 06090b3dbd..93345f6a4c 100644 --- a/invokeai/frontend/web/src/common/hooks/useChakraThemeTokens.ts +++ b/invokeai/frontend/web/src/common/hooks/useChakraThemeTokens.ts @@ -1,4 +1,4 @@ -import { useToken } from '@invoke-ai/ui'; +import { useToken } from '@invoke-ai/ui-library'; export const useChakraThemeTokens = () => { const [ diff --git a/invokeai/frontend/web/src/common/hooks/useFullscreenDropzone.ts b/invokeai/frontend/web/src/common/hooks/useFullscreenDropzone.ts index 2894414bb3..350e09b6e5 100644 --- a/invokeai/frontend/web/src/common/hooks/useFullscreenDropzone.ts +++ b/invokeai/frontend/web/src/common/hooks/useFullscreenDropzone.ts @@ -14,22 +14,19 @@ const accept: Accept = { 'image/jpeg': ['.jpg', '.jpeg', '.png'], }; -const selectPostUploadAction = createMemoizedSelector( - activeTabNameSelector, - (activeTabName) => { - let postUploadAction: PostUploadAction = { type: 'TOAST' }; +const selectPostUploadAction = createMemoizedSelector(activeTabNameSelector, (activeTabName) => { + let postUploadAction: PostUploadAction = { type: 'TOAST' }; - if (activeTabName === 'unifiedCanvas') { - postUploadAction = { type: 'SET_CANVAS_INITIAL_IMAGE' }; - } - - if (activeTabName === 'img2img') { - postUploadAction = { type: 'SET_INITIAL_IMAGE' }; - } - - return postUploadAction; + if (activeTabName === 'unifiedCanvas') { + postUploadAction = { type: 'SET_CANVAS_INITIAL_IMAGE' }; } -); + + if (activeTabName === 'img2img') { + postUploadAction = { type: 'SET_INITIAL_IMAGE' }; + } + + return postUploadAction; +}); export const useFullscreenDropzone = () => { const { t } = useTranslation(); @@ -112,9 +109,7 @@ export const useFullscreenDropzone = () => { // Set the files on the dropzone.inputRef dropzone.inputRef.current.files = e.clipboardData.files; // Dispatch the change event, dropzone catches this and we get to use its own validation - dropzone.inputRef.current?.dispatchEvent( - new Event('change', { bubbles: true }) - ); + dropzone.inputRef.current?.dispatchEvent(new Event('change', { bubbles: true })); } }; diff --git a/invokeai/frontend/web/src/common/hooks/useGlobalHotkeys.ts b/invokeai/frontend/web/src/common/hooks/useGlobalHotkeys.ts index 4416480f0e..372452ce99 100644 --- a/invokeai/frontend/web/src/common/hooks/useGlobalHotkeys.ts +++ b/invokeai/frontend/web/src/common/hooks/useGlobalHotkeys.ts @@ -9,13 +9,8 @@ import { useHotkeys } from 'react-hotkeys-hook'; export const useGlobalHotkeys = () => { const dispatch = useAppDispatch(); - const isModelManagerEnabled = - useFeatureStatus('modelManager').isFeatureEnabled; - const { - queueBack, - isDisabled: isDisabledQueueBack, - isLoading: isLoadingQueueBack, - } = useQueueBack(); + const isModelManagerEnabled = useFeatureStatus('modelManager').isFeatureEnabled; + const { queueBack, isDisabled: isDisabledQueueBack, isLoading: isLoadingQueueBack } = useQueueBack(); useHotkeys( ['ctrl+enter', 'meta+enter'], @@ -28,11 +23,7 @@ export const useGlobalHotkeys = () => { [queueBack, isDisabledQueueBack, isLoadingQueueBack] ); - const { - queueFront, - isDisabled: isDisabledQueueFront, - isLoading: isLoadingQueueFront, - } = useQueueFront(); + const { queueFront, isDisabled: isDisabledQueueFront, isLoading: isLoadingQueueFront } = useQueueFront(); useHotkeys( ['ctrl+shift+enter', 'meta+shift+enter'], @@ -61,11 +52,7 @@ export const useGlobalHotkeys = () => { [cancelQueueItem, isDisabledCancelQueueItem, isLoadingCancelQueueItem] ); - const { - clearQueue, - isDisabled: isDisabledClearQueue, - isLoading: isLoadingClearQueue, - } = useClearQueue(); + const { clearQueue, isDisabled: isDisabledClearQueue, isLoading: isLoadingClearQueue } = useClearQueue(); useHotkeys( ['ctrl+shift+x', 'meta+shift+x'], diff --git a/invokeai/frontend/web/src/common/hooks/useGroupedModelCombobox.ts b/invokeai/frontend/web/src/common/hooks/useGroupedModelCombobox.ts index d76eab4a53..eb55db79ca 100644 --- a/invokeai/frontend/web/src/common/hooks/useGroupedModelCombobox.ts +++ b/invokeai/frontend/web/src/common/hooks/useGroupedModelCombobox.ts @@ -1,4 +1,4 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; import type { EntityState } from '@reduxjs/toolkit'; import { useAppSelector } from 'app/store/storeHooks'; import type { GroupBase } from 'chakra-react-select'; @@ -28,11 +28,8 @@ export const useGroupedModelCombobox = ( arg: UseGroupedModelComboboxArg ): UseGroupedModelComboboxReturn => { const { t } = useTranslation(); - const base_model = useAppSelector( - (s) => s.generation.model?.base_model ?? 'sdxl' - ); - const { modelEntities, selectedModel, getIsDisabled, onChange, isLoading } = - arg; + const base_model = useAppSelector((s) => s.generation.model?.base_model ?? 'sdxl'); + const { modelEntities, selectedModel, getIsDisabled, onChange, isLoading } = arg; const options = useMemo[]>(() => { if (!modelEntities) { return []; @@ -60,11 +57,8 @@ export const useGroupedModelCombobox = ( const value = useMemo( () => - options - .flatMap((o) => o.options) - .find((m) => - selectedModel ? m.value === getModelId(selectedModel) : false - ) ?? null, + options.flatMap((o) => o.options).find((m) => (selectedModel ? m.value === getModelId(selectedModel) : false)) ?? + null, [options, selectedModel] ); diff --git a/invokeai/frontend/web/src/common/hooks/useImageUploadButton.tsx b/invokeai/frontend/web/src/common/hooks/useImageUploadButton.tsx index 085c98cb38..011f49ec26 100644 --- a/invokeai/frontend/web/src/common/hooks/useImageUploadButton.tsx +++ b/invokeai/frontend/web/src/common/hooks/useImageUploadButton.tsx @@ -28,10 +28,7 @@ type UseImageUploadButtonArgs = { * { const isStaging = useAppSelector(isStagingSelector); const isMaskEnabled = useAppSelector((s) => s.canvas.isMaskEnabled); - const shouldShowBoundingBox = useAppSelector( - (s) => s.canvas.shouldShowBoundingBox - ); + const shouldShowBoundingBox = useAppSelector((s) => s.canvas.shouldShowBoundingBox); const shouldShowGrid = useAppSelector((s) => s.canvas.shouldShowGrid); const stageScale = useAppSelector((s) => s.canvas.stageScale); - const shouldShowIntermediates = useAppSelector( - (s) => s.canvas.shouldShowIntermediates - ); + const shouldShowIntermediates = useAppSelector((s) => s.canvas.shouldShowIntermediates); const shouldAntialias = useAppSelector((s) => s.canvas.shouldAntialias); - const shouldRestrictStrokesToBox = useAppSelector( - (s) => s.canvas.shouldRestrictStrokesToBox - ); + const shouldRestrictStrokesToBox = useAppSelector((s) => s.canvas.shouldRestrictStrokesToBox); const { stageCoordinates, stageDimensions } = useAppSelector(selector); const dispatch = useAppDispatch(); const containerRef = useRef(null); @@ -95,22 +86,12 @@ const IAICanvas = () => { return 'default'; } return 'none'; - }, [ - isMouseOverBoundingBox, - isMovingStage, - isStaging, - isTransformingBoundingBox, - shouldRestrictStrokesToBox, - tool, - ]); + }, [isMouseOverBoundingBox, isMovingStage, isStaging, isTransformingBoundingBox, shouldRestrictStrokesToBox, tool]); - const canvasBaseLayerRefCallback = useCallback( - (layerElement: Konva.Layer) => { - $canvasBaseLayer.set(layerElement); - canvasBaseLayerRef.current = layerElement; - }, - [] - ); + const canvasBaseLayerRefCallback = useCallback((layerElement: Konva.Layer) => { + $canvasBaseLayer.set(layerElement); + canvasBaseLayerRef.current = layerElement; + }, []); const lastCursorPositionRef = useRef({ x: 0, y: 0 }); @@ -120,18 +101,10 @@ const IAICanvas = () => { const handleWheel = useCanvasWheel(stageRef); const handleMouseDown = useCanvasMouseDown(stageRef); const handleMouseUp = useCanvasMouseUp(stageRef, didMouseMoveRef); - const handleMouseMove = useCanvasMouseMove( - stageRef, - didMouseMoveRef, - lastCursorPositionRef - ); - const { handleDragStart, handleDragMove, handleDragEnd } = - useCanvasDragMove(); + const handleMouseMove = useCanvasMouseMove(stageRef, didMouseMoveRef, lastCursorPositionRef); + const { handleDragStart, handleDragMove, handleDragEnd } = useCanvasDragMove(); const handleMouseOut = useCanvasMouseOut(); - const handleContextMenu = useCallback( - (e: KonvaEventObject) => e.evt.preventDefault(), - [] - ); + const handleContextMenu = useCallback((e: KonvaEventObject) => e.evt.preventDefault(), []); useEffect(() => { if (!containerRef.current) { @@ -169,14 +142,7 @@ const IAICanvas = () => { const scale = useMemo(() => ({ x: stageScale, y: stageScale }), [stageScale]); return ( - + { - + - + @@ -225,17 +182,10 @@ const IAICanvas = () => { - {!isStaging && ( - - )} + {!isStaging && } {shouldShowIntermediates && } - + diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasBoundingBoxOverlay.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasBoundingBoxOverlay.tsx index 8d364a91ab..3cb75c09c6 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasBoundingBoxOverlay.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasBoundingBoxOverlay.tsx @@ -5,12 +5,7 @@ import { memo } from 'react'; import { Group, Rect } from 'react-konva'; const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { - const { - boundingBoxCoordinates, - boundingBoxDimensions, - stageDimensions, - stageCoordinates, - } = canvas; + const { boundingBoxCoordinates, boundingBoxDimensions, stageDimensions, stageCoordinates } = canvas; return { boundingBoxCoordinates, @@ -21,15 +16,8 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { }); const IAICanvasBoundingBoxOverlay = () => { - const { - boundingBoxCoordinates, - boundingBoxDimensions, - stageCoordinates, - stageDimensions, - } = useAppSelector(selector); - const shouldDarkenOutsideBoundingBox = useAppSelector( - (s) => s.canvas.shouldDarkenOutsideBoundingBox - ); + const { boundingBoxCoordinates, boundingBoxDimensions, stageCoordinates, stageDimensions } = useAppSelector(selector); + const shouldDarkenOutsideBoundingBox = useAppSelector((s) => s.canvas.shouldDarkenOutsideBoundingBox); const stageScale = useAppSelector((s) => s.canvas.stageScale); return ( diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasGrid.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasGrid.tsx index a049714037..b9105ce9dd 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasGrid.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasGrid.tsx @@ -1,5 +1,5 @@ // Grid drawing adapted from https://longviewcoder.com/2021/12/08/konva-a-better-grid/ -import { getArbitraryBaseColor } from '@invoke-ai/ui'; +import { getArbitraryBaseColor } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import { selectCanvasSlice } from 'features/canvas/store/canvasSlice'; @@ -76,11 +76,11 @@ const IAICanvasGrid = () => { }; const // find the x & y size of the grid - xSize = gridFullRect.x2 - gridFullRect.x1, - ySize = gridFullRect.y2 - gridFullRect.y1, - // compute the number of steps required on each axis. - xSteps = Math.round(xSize / gridSpacing) + 1, - ySteps = Math.round(ySize / gridSpacing) + 1; + xSize = gridFullRect.x2 - gridFullRect.x1; + const ySize = gridFullRect.y2 - gridFullRect.y1; + // compute the number of steps required on each axis. + const xSteps = Math.round(xSize / gridSpacing) + 1; + const ySteps = Math.round(ySize / gridSpacing) + 1; const strokeWidth = unscale(1); diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasImage.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasImage.tsx index 437f1d7d9d..75ae983f23 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasImage.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasImage.tsx @@ -13,13 +13,8 @@ type IAICanvasImageProps = { }; const IAICanvasImage = (props: IAICanvasImageProps) => { const { x, y, imageName } = props.canvasImage; - const { currentData: imageDTO, isError } = useGetImageDTOQuery( - imageName ?? skipToken - ); - const [image, status] = useImage( - imageDTO?.image_url ?? '', - $authToken.get() ? 'use-credentials' : 'anonymous' - ); + const { currentData: imageDTO, isError } = useGetImageDTOQuery(imageName ?? skipToken); + const [image, status] = useImage(imageDTO?.image_url ?? '', $authToken.get() ? 'use-credentials' : 'anonymous'); if (isError || status === 'failed') { return ; diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasImageErrorFallback.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasImageErrorFallback.tsx index ef23a55cd2..1606dfa844 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasImageErrorFallback.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasImageErrorFallback.tsx @@ -1,4 +1,4 @@ -import { useToken } from '@invoke-ai/ui'; +import { useToken } from '@invoke-ai/ui-library'; import type { CanvasImage } from 'features/canvas/store/canvasTypes'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -7,9 +7,7 @@ import { Group, Rect, Text } from 'react-konva'; type IAICanvasImageErrorFallbackProps = { canvasImage: CanvasImage; }; -const IAICanvasImageErrorFallback = ({ - canvasImage, -}: IAICanvasImageErrorFallbackProps) => { +const IAICanvasImageErrorFallback = ({ canvasImage }: IAICanvasImageErrorFallbackProps) => { const [rectFill, textFill] = useToken('colors', ['base.500', 'base.900']); const { t } = useTranslation(); return ( diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasIntermediateImage.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasIntermediateImage.tsx index 966017a814..bd9b93997e 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasIntermediateImage.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasIntermediateImage.tsx @@ -5,26 +5,20 @@ import { selectSystemSlice } from 'features/system/store/systemSlice'; import { memo, useEffect, useState } from 'react'; import { Image as KonvaImage } from 'react-konva'; -const progressImageSelector = createMemoizedSelector( - [selectSystemSlice, selectCanvasSlice], - (system, canvas) => { - const { denoiseProgress } = system; - const { batchIds } = canvas; +const progressImageSelector = createMemoizedSelector([selectSystemSlice, selectCanvasSlice], (system, canvas) => { + const { denoiseProgress } = system; + const { batchIds } = canvas; - return { - progressImage: - denoiseProgress && batchIds.includes(denoiseProgress.batch_id) - ? denoiseProgress.progress_image - : undefined, - boundingBox: canvas.layerState.stagingArea.boundingBox, - }; - } -); + return { + progressImage: + denoiseProgress && batchIds.includes(denoiseProgress.batch_id) ? denoiseProgress.progress_image : undefined, + boundingBox: canvas.layerState.stagingArea.boundingBox, + }; +}); const IAICanvasIntermediateImage = () => { const { progressImage, boundingBox } = useAppSelector(progressImageSelector); - const [loadedImageElement, setLoadedImageElement] = - useState(null); + const [loadedImageElement, setLoadedImageElement] = useState(null); useEffect(() => { if (!progressImage) { diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskCompositer.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskCompositer.tsx index 1a0aaa62d2..6098d85359 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskCompositer.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskCompositer.tsx @@ -9,30 +9,22 @@ import { isNumber } from 'lodash-es'; import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Rect } from 'react-konva'; -export const canvasMaskCompositerSelector = createMemoizedSelector( - selectCanvasSlice, - (canvas) => { - return { - stageCoordinates: canvas.stageCoordinates, - stageDimensions: canvas.stageDimensions, - }; - } -); +export const canvasMaskCompositerSelector = createMemoizedSelector(selectCanvasSlice, (canvas) => { + return { + stageCoordinates: canvas.stageCoordinates, + stageDimensions: canvas.stageDimensions, + }; +}); type IAICanvasMaskCompositerProps = RectConfig; const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => { const { ...rest } = props; - const { stageCoordinates, stageDimensions } = useAppSelector( - canvasMaskCompositerSelector - ); + const { stageCoordinates, stageDimensions } = useAppSelector(canvasMaskCompositerSelector); const stageScale = useAppSelector((s) => s.canvas.stageScale); - const maskColorString = useAppSelector((s) => - rgbaColorToString(s.canvas.maskColor) - ); - const [fillPatternImage, setFillPatternImage] = - useState(null); + const maskColorString = useAppSelector((s) => rgbaColorToString(s.canvas.maskColor)); + const [fillPatternImage, setFillPatternImage] = useState(null); const [offset, setOffset] = useState(0); @@ -66,10 +58,7 @@ const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => { return () => clearInterval(timer); }, []); - const fillPatternScale = useMemo( - () => ({ x: 1 / stageScale, y: 1 / stageScale }), - [stageScale] - ); + const fillPatternScale = useMemo(() => ({ x: 1 / stageScale, y: 1 / stageScale }), [stageScale]); if ( !fillPatternImage || diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx index 5511652e8d..27a733cb5e 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx @@ -27,9 +27,7 @@ const IAICanvasLines = (props: InpaintingCanvasLinesProps) => { lineJoin="round" shadowForStrokeEnabled={false} listening={false} - globalCompositeOperation={ - line.tool === 'brush' ? 'source-over' : 'destination-out' - } + globalCompositeOperation={line.tool === 'brush' ? 'source-over' : 'destination-out'} /> ))} diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx index bc089fe28a..23005a9d24 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx @@ -31,9 +31,7 @@ const IAICanvasObjectRenderer = () => { lineJoin="round" shadowForStrokeEnabled={false} listening={false} - globalCompositeOperation={ - obj.tool === 'brush' ? 'source-over' : 'destination-out' - } + globalCompositeOperation={obj.tool === 'brush' ? 'source-over' : 'destination-out'} /> ); if (obj.clip) { diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx index 361da7658c..8b9b580e63 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx @@ -22,9 +22,7 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { return { currentStagingAreaImage: - images.length > 0 && selectedImageIndex !== undefined - ? images[selectedImageIndex] - : undefined, + images.length > 0 && selectedImageIndex !== undefined ? images[selectedImageIndex] : undefined, isOnFirstImage: selectedImageIndex === 0, isOnLastImage: selectedImageIndex === images.length - 1, shouldShowStagingImage, @@ -39,21 +37,12 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { type Props = GroupConfig; const IAICanvasStagingArea = (props: Props) => { - const { - currentStagingAreaImage, - shouldShowStagingImage, - shouldShowStagingOutline, - x, - y, - width, - height, - } = useAppSelector(selector); + const { currentStagingAreaImage, shouldShowStagingImage, shouldShowStagingOutline, x, y, width, height } = + useAppSelector(selector); return ( - {shouldShowStagingImage && currentStagingAreaImage && ( - - )} + {shouldShowStagingImage && currentStagingAreaImage && } {shouldShowStagingOutline && ( { return { currentIndex: selectedImageIndex, total: images.length, - currentStagingAreaImage: - images.length > 0 ? images[selectedImageIndex] : undefined, + currentStagingAreaImage: images.length > 0 ? images[selectedImageIndex] : undefined, shouldShowStagingImage, shouldShowStagingOutline, }; @@ -47,12 +46,7 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { const IAICanvasStagingAreaToolbar = () => { const dispatch = useAppDispatch(); - const { - currentStagingAreaImage, - shouldShowStagingImage, - currentIndex, - total, - } = useAppSelector(selector); + const { currentStagingAreaImage, shouldShowStagingImage, currentIndex, total } = useAppSelector(selector); const { t } = useTranslation(); @@ -64,20 +58,11 @@ const IAICanvasStagingAreaToolbar = () => { dispatch(setShouldShowStagingOutline(false)); }, [dispatch]); - const handlePrevImage = useCallback( - () => dispatch(prevStagingAreaImage()), - [dispatch] - ); + const handlePrevImage = useCallback(() => dispatch(prevStagingAreaImage()), [dispatch]); - const handleNextImage = useCallback( - () => dispatch(nextStagingAreaImage()), - [dispatch] - ); + const handleNextImage = useCallback(() => dispatch(nextStagingAreaImage()), [dispatch]); - const handleAccept = useCallback( - () => dispatch(commitStagingAreaImage()), - [dispatch] - ); + const handleAccept = useCallback(() => dispatch(commitStagingAreaImage()), [dispatch]); useHotkeys(['left'], handlePrevImage, { enabled: () => true, @@ -94,9 +79,7 @@ const IAICanvasStagingAreaToolbar = () => { preventDefault: true, }); - const { data: imageDTO } = useGetImageDTOQuery( - currentStagingAreaImage?.imageName ?? skipToken - ); + const { data: imageDTO } = useGetImageDTOQuery(currentStagingAreaImage?.imageName ?? skipToken); const handleToggleShouldShowStagingImage = useCallback(() => { dispatch(setShouldShowStagingImage(!shouldShowStagingImage)); @@ -166,16 +149,8 @@ const IAICanvasStagingAreaToolbar = () => { colorScheme="invokeBlue" /> : } onClick={handleToggleShouldShowStagingImage} diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText.tsx index 8e99ffb65a..4c8153b83f 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText.tsx @@ -1,4 +1,4 @@ -import { Box, Flex } from '@invoke-ai/ui'; +import { Box, Flex } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import { selectCanvasSlice } from 'features/canvas/store/canvasSlice'; @@ -16,10 +16,7 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { stageDimensions: { width: stageWidth, height: stageHeight }, stageCoordinates: { x: stageX, y: stageY }, boundingBoxDimensions: { width: boxWidth, height: boxHeight }, - scaledBoundingBoxDimensions: { - width: scaledBoxWidth, - height: scaledBoxHeight, - }, + scaledBoundingBoxDimensions: { width: scaledBoxWidth, height: scaledBoxHeight }, boundingBoxCoordinates: { x: boxX, y: boxY }, stageScale, shouldShowCanvasDebugInfo, @@ -31,10 +28,8 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { let boundingBoxColor = 'inherit'; if ( - (boundingBoxScaleMethod === 'none' && - (boxWidth < 512 || boxHeight < 512)) || - (boundingBoxScaleMethod === 'manual' && - scaledBoxWidth * scaledBoxHeight < 512 * 512) + (boundingBoxScaleMethod === 'none' && (boxWidth < 512 || boxHeight < 512)) || + (boundingBoxScaleMethod === 'manual' && scaledBoxWidth * scaledBoxHeight < 512 * 512) ) { boundingBoxColor = warningColor; } @@ -45,14 +40,10 @@ const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => { activeLayerColor, layer, boundingBoxColor, - boundingBoxCoordinatesString: `(${roundToHundreth(boxX)}, ${roundToHundreth( - boxY - )})`, + boundingBoxCoordinatesString: `(${roundToHundreth(boxX)}, ${roundToHundreth(boxY)})`, boundingBoxDimensionsString: `${boxWidth}×${boxHeight}`, scaledBoundingBoxDimensionsString: `${scaledBoxWidth}×${scaledBoxHeight}`, - canvasCoordinatesString: `${roundToHundreth(stageX)}×${roundToHundreth( - stageY - )}`, + canvasCoordinatesString: `${roundToHundreth(stageX)}×${roundToHundreth(stageY)}`, canvasDimensionsString: `${stageWidth}×${stageHeight}`, canvasScaleString: Math.round(stageScale * 100), shouldShowCanvasDebugInfo, @@ -99,9 +90,7 @@ const IAICanvasStatusText = () => { bg="base.800" > - {`${t('unifiedCanvas.activeLayer')}: ${t( - `unifiedCanvas.${layer}` - )}`} + {`${t('unifiedCanvas.activeLayer')}: ${t(`unifiedCanvas.${layer}`)}`} {`${t('unifiedCanvas.canvasScale')}: ${canvasScaleString}%`} {shouldPreserveMaskedArea && ( @@ -109,9 +98,7 @@ const IAICanvasStatusText = () => { )} {shouldShowBoundingBox && ( - {`${t( - 'unifiedCanvas.boundingBox' - )}: ${boundingBoxDimensionsString}`} + {`${t('unifiedCanvas.boundingBox')}: ${boundingBoxDimensionsString}`} )} {shouldShowScaledBoundingBox && ( {`${t( @@ -120,15 +107,9 @@ const IAICanvasStatusText = () => { )} {shouldShowCanvasDebugInfo && ( <> - {`${t( - 'unifiedCanvas.boundingBoxPosition' - )}: ${boundingBoxCoordinatesString}`} - {`${t( - 'unifiedCanvas.canvasDimensions' - )}: ${canvasDimensionsString}`} - {`${t( - 'unifiedCanvas.canvasPosition' - )}: ${canvasCoordinatesString}`} + {`${t('unifiedCanvas.boundingBoxPosition')}: ${boundingBoxCoordinatesString}`} + {`${t('unifiedCanvas.canvasDimensions')}: ${canvasDimensionsString}`} + {`${t('unifiedCanvas.canvasPosition')}: ${canvasCoordinatesString}`} )} diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText/IAICanvasStatusTextCursorPos.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText/IAICanvasStatusTextCursorPos.tsx index dd24ea34a1..a7e9ecb157 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText/IAICanvasStatusTextCursorPos.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStatusText/IAICanvasStatusTextCursorPos.tsx @@ -1,4 +1,4 @@ -import { Box } from '@invoke-ai/ui'; +import { Box } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { $cursorPosition } from 'features/canvas/store/canvasNanostore'; import roundToHundreth from 'features/canvas/util/roundToHundreth'; @@ -14,11 +14,7 @@ const IAICanvasStatusTextCursorPos = () => { return `(${roundToHundreth(x)}, ${roundToHundreth(y)})`; }, [cursorPosition?.x, cursorPosition?.y]); - return ( - {`${t( - 'unifiedCanvas.cursorPosition' - )}: ${cursorCoordinatesString}`} - ); + return {`${t('unifiedCanvas.cursorPosition')}: ${cursorCoordinatesString}`}; }; export default memo(IAICanvasStatusTextCursorPos); diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx index 97ad0c6073..be1a4c2d4c 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx @@ -9,104 +9,84 @@ import { } from 'features/canvas/store/canvasNanostore'; import { selectCanvasSlice } from 'features/canvas/store/canvasSlice'; import { rgbaColorToString } from 'features/canvas/util/colorToString'; -import { - COLOR_PICKER_SIZE, - COLOR_PICKER_STROKE_RADIUS, -} from 'features/canvas/util/constants'; +import { COLOR_PICKER_SIZE, COLOR_PICKER_STROKE_RADIUS } from 'features/canvas/util/constants'; import type { GroupConfig } from 'konva/lib/Group'; import { memo, useMemo } from 'react'; import { Circle, Group } from 'react-konva'; -const canvasBrushPreviewSelector = createMemoizedSelector( - selectCanvasSlice, - (canvas) => { - const { - stageDimensions, - boundingBoxCoordinates, - boundingBoxDimensions, - shouldRestrictStrokesToBox, - } = canvas; +const canvasBrushPreviewSelector = createMemoizedSelector(selectCanvasSlice, (canvas) => { + const { stageDimensions, boundingBoxCoordinates, boundingBoxDimensions, shouldRestrictStrokesToBox } = canvas; - const clip = shouldRestrictStrokesToBox - ? { - clipX: boundingBoxCoordinates.x, - clipY: boundingBoxCoordinates.y, - clipWidth: boundingBoxDimensions.width, - clipHeight: boundingBoxDimensions.height, - } - : {}; + const clip = shouldRestrictStrokesToBox + ? { + clipX: boundingBoxCoordinates.x, + clipY: boundingBoxCoordinates.y, + clipWidth: boundingBoxDimensions.width, + clipHeight: boundingBoxDimensions.height, + } + : {}; - // // big brain time; this is the *inverse* of the clip that is needed for shouldRestrictStrokesToBox - // // it took some fiddling to work out, so I am leaving it here in case it is needed for something else... - // const clipFunc = shouldRestrictStrokesToBox - // ? (ctx: SceneContext) => { - // console.log( - // stageCoordinates.x / stageScale, - // stageCoordinates.y / stageScale, - // stageDimensions.height / stageScale, - // stageDimensions.width / stageScale - // ); - // ctx.fillStyle = 'red'; - // ctx.rect( - // -stageCoordinates.x / stageScale, - // -stageCoordinates.y / stageScale, - // stageDimensions.width / stageScale, - // stageCoordinates.y / stageScale + boundingBoxCoordinates.y - // ); - // ctx.rect( - // -stageCoordinates.x / stageScale, - // boundingBoxCoordinates.y + boundingBoxDimensions.height, - // stageDimensions.width / stageScale, - // stageDimensions.height / stageScale - // ); - // ctx.rect( - // -stageCoordinates.x / stageScale, - // -stageCoordinates.y / stageScale, - // stageCoordinates.x / stageScale + boundingBoxCoordinates.x, - // stageDimensions.height / stageScale - // ); - // ctx.rect( - // boundingBoxCoordinates.x + boundingBoxDimensions.width, - // -stageCoordinates.y / stageScale, - // stageDimensions.width / stageScale - - // (boundingBoxCoordinates.x + boundingBoxDimensions.width), - // stageDimensions.height / stageScale - // ); - // } - // : undefined; + // // big brain time; this is the *inverse* of the clip that is needed for shouldRestrictStrokesToBox + // // it took some fiddling to work out, so I am leaving it here in case it is needed for something else... + // const clipFunc = shouldRestrictStrokesToBox + // ? (ctx: SceneContext) => { + // console.log( + // stageCoordinates.x / stageScale, + // stageCoordinates.y / stageScale, + // stageDimensions.height / stageScale, + // stageDimensions.width / stageScale + // ); + // ctx.fillStyle = 'red'; + // ctx.rect( + // -stageCoordinates.x / stageScale, + // -stageCoordinates.y / stageScale, + // stageDimensions.width / stageScale, + // stageCoordinates.y / stageScale + boundingBoxCoordinates.y + // ); + // ctx.rect( + // -stageCoordinates.x / stageScale, + // boundingBoxCoordinates.y + boundingBoxDimensions.height, + // stageDimensions.width / stageScale, + // stageDimensions.height / stageScale + // ); + // ctx.rect( + // -stageCoordinates.x / stageScale, + // -stageCoordinates.y / stageScale, + // stageCoordinates.x / stageScale + boundingBoxCoordinates.x, + // stageDimensions.height / stageScale + // ); + // ctx.rect( + // boundingBoxCoordinates.x + boundingBoxDimensions.width, + // -stageCoordinates.y / stageScale, + // stageDimensions.width / stageScale - + // (boundingBoxCoordinates.x + boundingBoxDimensions.width), + // stageDimensions.height / stageScale + // ); + // } + // : undefined; - return { - clip, - stageDimensions, - }; - } -); + return { + clip, + stageDimensions, + }; +}); /** * Draws a black circle around the canvas brush preview. */ const IAICanvasToolPreview = (props: GroupConfig) => { const radius = useAppSelector((s) => s.canvas.brushSize / 2); - const maskColorString = useAppSelector((s) => - rgbaColorToString({ ...s.canvas.maskColor, a: 0.5 }) - ); + const maskColorString = useAppSelector((s) => rgbaColorToString({ ...s.canvas.maskColor, a: 0.5 })); const tool = useStore($tool); const layer = useAppSelector((s) => s.canvas.layer); const dotRadius = useAppSelector((s) => 1.5 / s.canvas.stageScale); const strokeWidth = useAppSelector((s) => 1.5 / s.canvas.stageScale); - const brushColorString = useAppSelector((s) => - rgbaColorToString(s.canvas.brushColor) - ); - const colorPickerColorString = useAppSelector((s) => - rgbaColorToString(s.canvas.colorPickerColor) - ); + const brushColorString = useAppSelector((s) => rgbaColorToString(s.canvas.brushColor)); + const colorPickerColorString = useAppSelector((s) => rgbaColorToString(s.canvas.colorPickerColor)); const colorPickerInnerRadius = useAppSelector( - (s) => - (COLOR_PICKER_SIZE - COLOR_PICKER_STROKE_RADIUS + 1) / s.canvas.stageScale - ); - const colorPickerOuterRadius = useAppSelector( - (s) => COLOR_PICKER_SIZE / s.canvas.stageScale + (s) => (COLOR_PICKER_SIZE - COLOR_PICKER_STROKE_RADIUS + 1) / s.canvas.stageScale ); + const colorPickerOuterRadius = useAppSelector((s) => COLOR_PICKER_SIZE / s.canvas.stageScale); const { clip, stageDimensions } = useAppSelector(canvasBrushPreviewSelector); const cursorPosition = useStore($cursorPosition); @@ -123,8 +103,7 @@ const IAICanvasToolPreview = (props: GroupConfig) => { ); const shouldDrawBrushPreview = useMemo( - () => - !(isMovingBoundingBox || isTransformingBoundingBox || !cursorPosition), + () => !(isMovingBoundingBox || isTransformingBoundingBox || !cursorPosition), [cursorPosition, isMovingBoundingBox, isTransformingBoundingBox] ); @@ -162,9 +141,7 @@ const IAICanvasToolPreview = (props: GroupConfig) => { y={brushY} radius={radius} fill={layer === 'mask' ? maskColorString : brushColorString} - globalCompositeOperation={ - tool === 'eraser' ? 'destination-out' : 'source-out' - } + globalCompositeOperation={tool === 'eraser' ? 'destination-out' : 'source-out'} listening={false} /> { /> )} - - + + ); }; diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasBoundingBox.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasBoundingBox.tsx index bc7bc6fa4c..98ca55351c 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasBoundingBox.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasBoundingBox.tsx @@ -1,11 +1,7 @@ -import { useShiftModifier } from '@invoke-ai/ui'; +import { useShiftModifier } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - roundDownToMultiple, - roundDownToMultipleMin, - roundToMultiple, -} from 'common/util/roundDownToMultiple'; +import { roundDownToMultiple, roundDownToMultipleMin, roundToMultiple } from 'common/util/roundDownToMultiple'; import { $isDrawing, $isMouseOverBoundingBox, @@ -20,10 +16,7 @@ import { setBoundingBoxDimensions, setShouldSnapToGrid, } from 'features/canvas/store/canvasSlice'; -import { - CANVAS_GRID_SIZE_COARSE, - CANVAS_GRID_SIZE_FINE, -} from 'features/canvas/store/constants'; +import { CANVAS_GRID_SIZE_COARSE, CANVAS_GRID_SIZE_FINE } from 'features/canvas/store/constants'; import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; import type Konva from 'konva'; @@ -41,12 +34,8 @@ type IAICanvasBoundingBoxPreviewProps = GroupConfig; const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { const { ...rest } = props; const dispatch = useAppDispatch(); - const boundingBoxCoordinates = useAppSelector( - (s) => s.canvas.boundingBoxCoordinates - ); - const boundingBoxDimensions = useAppSelector( - (s) => s.canvas.boundingBoxDimensions - ); + const boundingBoxCoordinates = useAppSelector((s) => s.canvas.boundingBoxCoordinates); + const boundingBoxDimensions = useAppSelector((s) => s.canvas.boundingBoxDimensions); const stageScale = useAppSelector((s) => s.canvas.stageScale); const shouldSnapToGrid = useAppSelector((s) => s.canvas.shouldSnapToGrid); const hitStrokeWidth = useAppSelector((s) => 20 / s.canvas.stageScale); @@ -59,9 +48,7 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { const isDrawing = useStore($isDrawing); const isMovingBoundingBox = useStore($isMovingBoundingBox); const isTransformingBoundingBox = useStore($isTransformingBoundingBox); - const isMouseOverBoundingBoxOutline = useStore( - $isMouseOverBoundingBoxOutline - ); + const isMouseOverBoundingBoxOutline = useStore($isMouseOverBoundingBoxOutline); useEffect(() => { if (!transformerRef.current || !shapeRef.current) { @@ -71,14 +58,8 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { transformerRef.current.getLayer()?.batchDraw(); }, []); - const gridSize = useMemo( - () => (shift ? CANVAS_GRID_SIZE_FINE : CANVAS_GRID_SIZE_COARSE), - [shift] - ); - const scaledStep = useMemo( - () => gridSize * stageScale, - [gridSize, stageScale] - ); + const gridSize = useMemo(() => (shift ? CANVAS_GRID_SIZE_FINE : CANVAS_GRID_SIZE_COARSE), [shift]); + const scaledStep = useMemo(() => gridSize * stageScale, [gridSize, stageScale]); useHotkeys( 'N', @@ -143,10 +124,7 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { const y = Math.round(rect.y()); if (aspectRatio.isLocked) { - const newDimensions = calculateNewSize( - aspectRatio.value, - width * height - ); + const newDimensions = calculateNewSize(aspectRatio.value, width * height); dispatch( setBoundingBoxDimensions( { @@ -186,14 +164,7 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { rect.scaleX(1); rect.scaleY(1); }, - [ - aspectRatio.isLocked, - aspectRatio.value, - dispatch, - shouldSnapToGrid, - gridSize, - optimalDimension, - ] + [aspectRatio.isLocked, aspectRatio.value, dispatch, shouldSnapToGrid, gridSize, optimalDimension] ); const anchorDragBoundFunc = useCallback( @@ -255,9 +226,7 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { }, []); const handleMouseOut = useCallback(() => { - !isTransformingBoundingBox && - !isMovingBoundingBox && - $isMouseOverBoundingBoxOutline.set(false); + !isTransformingBoundingBox && !isMovingBoundingBox && $isMouseOverBoundingBoxOutline.set(false); }, [isMovingBoundingBox, isTransformingBoundingBox]); const handleMouseEnterBoundingBox = useCallback(() => { @@ -269,35 +238,18 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => { }, []); const stroke = useMemo(() => { - if ( - isMouseOverBoundingBoxOutline || - isMovingBoundingBox || - isTransformingBoundingBox - ) { + if (isMouseOverBoundingBoxOutline || isMovingBoundingBox || isTransformingBoundingBox) { return 'rgba(255,255,255,0.5)'; } return 'white'; - }, [ - isMouseOverBoundingBoxOutline, - isMovingBoundingBox, - isTransformingBoundingBox, - ]); + }, [isMouseOverBoundingBoxOutline, isMovingBoundingBox, isTransformingBoundingBox]); const strokeWidth = useMemo(() => { - if ( - isMouseOverBoundingBoxOutline || - isMovingBoundingBox || - isTransformingBoundingBox - ) { + if (isMouseOverBoundingBoxOutline || isMovingBoundingBox || isTransformingBoundingBox) { return 6 / stageScale; } return 1 / stageScale; - }, [ - isMouseOverBoundingBoxOutline, - isMovingBoundingBox, - isTransformingBoundingBox, - stageScale, - ]); + }, [isMouseOverBoundingBoxOutline, isMovingBoundingBox, isTransformingBoundingBox, stageScale]); const enabledAnchors = useMemo(() => { if (tool !== 'move') { diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx index 2e4fcccd85..6dacb7c59d 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx @@ -1,4 +1,4 @@ -import type { FormLabelProps } from '@invoke-ai/ui'; +import type { FormLabelProps } from '@invoke-ai/ui-library'; import { Box, Button, @@ -13,7 +13,7 @@ import { PopoverBody, PopoverContent, PopoverTrigger, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAIColorPicker from 'common/components/IAIColorPicker'; import { canvasMaskSavedToGallery } from 'features/canvas/store/actions'; @@ -30,11 +30,7 @@ import { memo, useCallback } from 'react'; import type { RgbaColor } from 'react-colorful'; import { useHotkeys } from 'react-hotkeys-hook'; import { useTranslation } from 'react-i18next'; -import { - PiExcludeBold, - PiFloppyDiskBackFill, - PiTrashSimpleFill, -} from 'react-icons/pi'; +import { PiExcludeBold, PiFloppyDiskBackFill, PiTrashSimpleFill } from 'react-icons/pi'; const formLabelProps: FormLabelProps = { flexGrow: 1, @@ -46,9 +42,7 @@ const IAICanvasMaskOptions = () => { const layer = useAppSelector((s) => s.canvas.layer); const maskColor = useAppSelector((s) => s.canvas.maskColor); const isMaskEnabled = useAppSelector((s) => s.canvas.isMaskEnabled); - const shouldPreserveMaskedArea = useAppSelector( - (s) => s.canvas.shouldPreserveMaskedArea - ); + const shouldPreserveMaskedArea = useAppSelector((s) => s.canvas.shouldPreserveMaskedArea); const isStaging = useAppSelector(isStagingSelector); useHotkeys( @@ -134,38 +128,21 @@ const IAICanvasMaskOptions = () => { {`${t('unifiedCanvas.enableMask')} (H)`} - + {t('unifiedCanvas.preserveMaskedArea')} - + - + - - diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx index 1fdffa0d3e..d156944a60 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx @@ -1,4 +1,4 @@ -import { IconButton } from '@invoke-ai/ui'; +import { IconButton } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { redo } from 'features/canvas/store/canvasSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx index bbdff781bf..1d3ccc52f9 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx @@ -1,4 +1,4 @@ -import type { FormLabelProps } from '@invoke-ai/ui'; +import type { FormLabelProps } from '@invoke-ai/ui-library'; import { Checkbox, Flex, @@ -10,7 +10,7 @@ import { PopoverBody, PopoverContent, PopoverTrigger, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import ClearCanvasHistoryButtonModal from 'features/canvas/components/ClearCanvasHistoryButtonModal'; import { @@ -38,23 +38,13 @@ const IAICanvasSettingsButtonPopover = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); const shouldAutoSave = useAppSelector((s) => s.canvas.shouldAutoSave); - const shouldCropToBoundingBoxOnSave = useAppSelector( - (s) => s.canvas.shouldCropToBoundingBoxOnSave - ); - const shouldDarkenOutsideBoundingBox = useAppSelector( - (s) => s.canvas.shouldDarkenOutsideBoundingBox - ); - const shouldShowCanvasDebugInfo = useAppSelector( - (s) => s.canvas.shouldShowCanvasDebugInfo - ); + const shouldCropToBoundingBoxOnSave = useAppSelector((s) => s.canvas.shouldCropToBoundingBoxOnSave); + const shouldDarkenOutsideBoundingBox = useAppSelector((s) => s.canvas.shouldDarkenOutsideBoundingBox); + const shouldShowCanvasDebugInfo = useAppSelector((s) => s.canvas.shouldShowCanvasDebugInfo); const shouldShowGrid = useAppSelector((s) => s.canvas.shouldShowGrid); - const shouldShowIntermediates = useAppSelector( - (s) => s.canvas.shouldShowIntermediates - ); + const shouldShowIntermediates = useAppSelector((s) => s.canvas.shouldShowIntermediates); const shouldSnapToGrid = useAppSelector((s) => s.canvas.shouldSnapToGrid); - const shouldRestrictStrokesToBox = useAppSelector( - (s) => s.canvas.shouldRestrictStrokesToBox - ); + const shouldRestrictStrokesToBox = useAppSelector((s) => s.canvas.shouldRestrictStrokesToBox); const shouldAntialias = useAppSelector((s) => s.canvas.shouldAntialias); useHotkeys( @@ -70,49 +60,40 @@ const IAICanvasSettingsButtonPopover = () => { ); const handleChangeShouldSnapToGrid = useCallback( - (e: ChangeEvent) => - dispatch(setShouldSnapToGrid(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldSnapToGrid(e.target.checked)), [dispatch] ); const handleChangeShouldShowIntermediates = useCallback( - (e: ChangeEvent) => - dispatch(setShouldShowIntermediates(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldShowIntermediates(e.target.checked)), [dispatch] ); const handleChangeShouldShowGrid = useCallback( - (e: ChangeEvent) => - dispatch(setShouldShowGrid(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldShowGrid(e.target.checked)), [dispatch] ); const handleChangeShouldDarkenOutsideBoundingBox = useCallback( - (e: ChangeEvent) => - dispatch(setShouldDarkenOutsideBoundingBox(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldDarkenOutsideBoundingBox(e.target.checked)), [dispatch] ); const handleChangeShouldAutoSave = useCallback( - (e: ChangeEvent) => - dispatch(setShouldAutoSave(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldAutoSave(e.target.checked)), [dispatch] ); const handleChangeShouldCropToBoundingBoxOnSave = useCallback( - (e: ChangeEvent) => - dispatch(setShouldCropToBoundingBoxOnSave(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldCropToBoundingBoxOnSave(e.target.checked)), [dispatch] ); const handleChangeShouldRestrictStrokesToBox = useCallback( - (e: ChangeEvent) => - dispatch(setShouldRestrictStrokesToBox(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldRestrictStrokesToBox(e.target.checked)), [dispatch] ); const handleChangeShouldShowCanvasDebugInfo = useCallback( - (e: ChangeEvent) => - dispatch(setShouldShowCanvasDebugInfo(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldShowCanvasDebugInfo(e.target.checked)), [dispatch] ); const handleChangeShouldAntialias = useCallback( - (e: ChangeEvent) => - dispatch(setShouldAntialias(e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldAntialias(e.target.checked)), [dispatch] ); @@ -131,29 +112,18 @@ const IAICanvasSettingsButtonPopover = () => { {t('unifiedCanvas.showIntermediates')} - + {t('unifiedCanvas.showGrid')} - + {t('unifiedCanvas.snapToGrid')} - + - - {t('unifiedCanvas.darkenOutsideSelection')} - + {t('unifiedCanvas.darkenOutsideSelection')} { {t('unifiedCanvas.autoSaveToGallery')} - + {t('unifiedCanvas.saveBoxRegionOnly')} @@ -175,24 +142,15 @@ const IAICanvasSettingsButtonPopover = () => { {t('unifiedCanvas.limitStrokesToBox')} - + {t('unifiedCanvas.showCanvasDebugInfo')} - + {t('unifiedCanvas.antialiasing')} - + diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx index 5584be9ed1..697434739e 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx @@ -11,21 +11,13 @@ import { PopoverBody, PopoverContent, PopoverTrigger, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAIColorPicker from 'common/components/IAIColorPicker'; -import { - $tool, - resetToolInteractionState, -} from 'features/canvas/store/canvasNanostore'; +import { $tool, resetToolInteractionState } from 'features/canvas/store/canvasNanostore'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; -import { - addEraseRect, - addFillRect, - setBrushColor, - setBrushSize, -} from 'features/canvas/store/canvasSlice'; +import { addEraseRect, addFillRect, setBrushColor, setBrushSize } from 'features/canvas/store/canvasSlice'; import { clamp } from 'lodash-es'; import { memo, useCallback } from 'react'; import type { RgbaColor } from 'react-colorful'; @@ -275,11 +267,7 @@ const IAICanvasToolChooserOptions = () => { - + diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx index 865e0d5767..65a46d580a 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx @@ -1,12 +1,5 @@ -import type { ComboboxOnChange } from '@invoke-ai/ui'; -import { - ButtonGroup, - Combobox, - Flex, - FormControl, - IconButton, - Tooltip, -} from '@invoke-ai/ui'; +import type { ComboboxOnChange } from '@invoke-ai/ui-library'; +import { ButtonGroup, Combobox, Flex, FormControl, IconButton, Tooltip } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useCopyImageToClipboard } from 'common/hooks/useCopyImageToClipboard'; @@ -20,12 +13,7 @@ import { } from 'features/canvas/store/actions'; import { $canvasBaseLayer, $tool } from 'features/canvas/store/canvasNanostore'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; -import { - resetCanvas, - resetCanvasView, - setIsMaskEnabled, - setLayer, -} from 'features/canvas/store/canvasSlice'; +import { resetCanvas, resetCanvasView, setIsMaskEnabled, setLayer } from 'features/canvas/store/canvasSlice'; import type { CanvasLayer } from 'features/canvas/store/canvasTypes'; import { LAYER_NAMES_DICT } from 'features/canvas/store/canvasTypes'; import { memo, useCallback, useMemo } from 'react'; @@ -203,20 +191,13 @@ const IAICanvasToolbar = () => { [dispatch, isMaskEnabled] ); - const value = useMemo( - () => LAYER_NAMES_DICT.filter((o) => o.value === layer)[0], - [layer] - ); + const value = useMemo(() => LAYER_NAMES_DICT.filter((o) => o.value === layer)[0], [layer]); return ( - + diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasUndoButton.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasUndoButton.tsx index a2b8feac23..f1fcdf96e5 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasUndoButton.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasUndoButton.tsx @@ -1,4 +1,4 @@ -import { IconButton } from '@invoke-ai/ui'; +import { IconButton } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { undo } from 'features/canvas/store/canvasSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasDragMove.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasDragMove.ts index 8f777ca39b..d47b1c6ccd 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasDragMove.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasDragMove.ts @@ -1,9 +1,5 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - $isMovingBoundingBox, - $isMovingStage, - $tool, -} from 'features/canvas/store/canvasNanostore'; +import { $isMovingBoundingBox, $isMovingStage, $tool } from 'features/canvas/store/canvasNanostore'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; import { setStageCoordinates } from 'features/canvas/store/canvasSlice'; import type { KonvaEventObject } from 'konva/lib/Node'; @@ -13,9 +9,7 @@ const useCanvasDrag = () => { const dispatch = useAppDispatch(); const isStaging = useAppSelector(isStagingSelector); const handleDragStart = useCallback(() => { - if ( - !(($tool.get() === 'move' || isStaging) && !$isMovingBoundingBox.get()) - ) { + if (!(($tool.get() === 'move' || isStaging) && !$isMovingBoundingBox.get())) { return; } $isMovingStage.set(true); @@ -36,9 +30,7 @@ const useCanvasDrag = () => { ); const handleDragEnd = useCallback(() => { - if ( - !(($tool.get() === 'move' || isStaging) && !$isMovingBoundingBox.get()) - ) { + if (!(($tool.get() === 'move' || isStaging) && !$isMovingBoundingBox.get())) { return; } $isMovingStage.set(false); diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasGenerationMode.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasGenerationMode.ts index a7d6a173ad..45852cd1bc 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasGenerationMode.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasGenerationMode.ts @@ -8,30 +8,16 @@ import { useDebounce } from 'react-use'; export const useCanvasGenerationMode = () => { const layerState = useAppSelector((s) => s.canvas.layerState); - const boundingBoxCoordinates = useAppSelector( - (s) => s.canvas.boundingBoxCoordinates - ); - const boundingBoxDimensions = useAppSelector( - (s) => s.canvas.boundingBoxDimensions - ); + const boundingBoxCoordinates = useAppSelector((s) => s.canvas.boundingBoxCoordinates); + const boundingBoxDimensions = useAppSelector((s) => s.canvas.boundingBoxDimensions); const isMaskEnabled = useAppSelector((s) => s.canvas.isMaskEnabled); - const shouldPreserveMaskedArea = useAppSelector( - (s) => s.canvas.shouldPreserveMaskedArea - ); - const [generationMode, setGenerationMode] = useState< - GenerationMode | undefined - >(); + const shouldPreserveMaskedArea = useAppSelector((s) => s.canvas.shouldPreserveMaskedArea); + const [generationMode, setGenerationMode] = useState(); useEffect(() => { setGenerationMode(undefined); - }, [ - layerState, - boundingBoxCoordinates, - boundingBoxDimensions, - isMaskEnabled, - shouldPreserveMaskedArea, - ]); + }, [layerState, boundingBoxCoordinates, boundingBoxDimensions, isMaskEnabled, shouldPreserveMaskedArea]); useDebounce( async () => { @@ -51,21 +37,12 @@ export const useCanvasGenerationMode = () => { const { baseImageData, maskImageData } = canvasBlobsAndImageData; // Determine the generation mode - const generationMode = getCanvasGenerationMode( - baseImageData, - maskImageData - ); + const generationMode = getCanvasGenerationMode(baseImageData, maskImageData); setGenerationMode(generationMode); }, 1000, - [ - layerState, - boundingBoxCoordinates, - boundingBoxDimensions, - isMaskEnabled, - shouldPreserveMaskedArea, - ] + [layerState, boundingBoxCoordinates, boundingBoxDimensions, isMaskEnabled, shouldPreserveMaskedArea] ); return generationMode; diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasHotkeys.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasHotkeys.ts index ed7434898e..05ed0d7119 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasHotkeys.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasHotkeys.ts @@ -22,9 +22,7 @@ import { useHotkeys } from 'react-hotkeys-hook'; const useInpaintingCanvasHotkeys = () => { const dispatch = useAppDispatch(); const activeTabName = useAppSelector(activeTabNameSelector); - const shouldShowBoundingBox = useAppSelector( - (s) => s.canvas.shouldShowBoundingBox - ); + const shouldShowBoundingBox = useAppSelector((s) => s.canvas.shouldShowBoundingBox); const isStaging = useAppSelector(isStagingSelector); const isMaskEnabled = useAppSelector((s) => s.canvas.isMaskEnabled); const shouldSnapToGrid = useAppSelector((s) => s.canvas.shouldSnapToGrid); @@ -44,8 +42,7 @@ const useInpaintingCanvasHotkeys = () => { [] ); - const handleToggleEnableMask = () => - dispatch(setIsMaskEnabled(!isMaskEnabled)); + const handleToggleEnableMask = () => dispatch(setIsMaskEnabled(!isMaskEnabled)); useHotkeys( ['h'], diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseDown.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseDown.ts index a208c17378..b392b72e3f 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseDown.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseDown.ts @@ -1,9 +1,5 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - $isDrawing, - $isMovingStage, - $tool, -} from 'features/canvas/store/canvasNanostore'; +import { $isDrawing, $isMovingStage, $tool } from 'features/canvas/store/canvasNanostore'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; import { addLine } from 'features/canvas/store/canvasSlice'; import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition'; diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseMove.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseMove.ts index 3bf0953967..6d0a97031b 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseMove.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseMove.ts @@ -1,9 +1,5 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - $cursorPosition, - $isDrawing, - $tool, -} from 'features/canvas/store/canvasNanostore'; +import { $cursorPosition, $isDrawing, $tool } from 'features/canvas/store/canvasNanostore'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; import { addPointToCurrentLine } from 'features/canvas/store/canvasSlice'; import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition'; @@ -49,17 +45,8 @@ const useCanvasMouseMove = ( } didMouseMoveRef.current = true; - dispatch( - addPointToCurrentLine([scaledCursorPosition.x, scaledCursorPosition.y]) - ); - }, [ - didMouseMoveRef, - dispatch, - isStaging, - lastCursorPositionRef, - stageRef, - updateColorUnderCursor, - ]); + dispatch(addPointToCurrentLine([scaledCursorPosition.x, scaledCursorPosition.y])); + }, [didMouseMoveRef, dispatch, isStaging, lastCursorPositionRef, stageRef, updateColorUnderCursor]); }; export default useCanvasMouseMove; diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseUp.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseUp.ts index 9c6b4c6186..e3c291f1e1 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseUp.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasMouseUp.ts @@ -1,10 +1,6 @@ import { useStore } from '@nanostores/react'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - $isDrawing, - $isMovingStage, - $tool, -} from 'features/canvas/store/canvasNanostore'; +import { $isDrawing, $isMovingStage, $tool } from 'features/canvas/store/canvasNanostore'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; import { addPointToCurrentLine } from 'features/canvas/store/canvasSlice'; import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition'; @@ -39,9 +35,7 @@ const useCanvasMouseUp = ( * the line's existing points. This allows the line to render as a circle * centered on that point. */ - dispatch( - addPointToCurrentLine([scaledCursorPosition.x, scaledCursorPosition.y]) - ); + dispatch(addPointToCurrentLine([scaledCursorPosition.x, scaledCursorPosition.y])); } else { didMouseMoveRef.current = false; } diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasZoom.ts b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasZoom.ts index 8c1ac9833b..fbcc133f7f 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useCanvasZoom.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useCanvasZoom.ts @@ -1,15 +1,8 @@ import { useStore } from '@nanostores/react'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { $isMoveStageKeyHeld } from 'features/canvas/store/canvasNanostore'; -import { - setStageCoordinates, - setStageScale, -} from 'features/canvas/store/canvasSlice'; -import { - CANVAS_SCALE_BY, - MAX_CANVAS_SCALE, - MIN_CANVAS_SCALE, -} from 'features/canvas/util/constants'; +import { setStageCoordinates, setStageScale } from 'features/canvas/store/canvasSlice'; +import { CANVAS_SCALE_BY, MAX_CANVAS_SCALE, MIN_CANVAS_SCALE } from 'features/canvas/util/constants'; import type Konva from 'konva'; import type { KonvaEventObject } from 'konva/lib/Node'; import { clamp } from 'lodash-es'; @@ -49,11 +42,7 @@ const useCanvasWheel = (stageRef: MutableRefObject) => { delta = -delta; } - const newScale = clamp( - stageScale * CANVAS_SCALE_BY ** delta, - MIN_CANVAS_SCALE, - MAX_CANVAS_SCALE - ); + const newScale = clamp(stageScale * CANVAS_SCALE_BY ** delta, MIN_CANVAS_SCALE, MAX_CANVAS_SCALE); const newCoordinates = { x: cursorPos.x - mousePointTo.x * newScale, diff --git a/invokeai/frontend/web/src/features/canvas/hooks/useColorUnderCursor.ts b/invokeai/frontend/web/src/features/canvas/hooks/useColorUnderCursor.ts index 913dd3c8f0..f07433a3de 100644 --- a/invokeai/frontend/web/src/features/canvas/hooks/useColorUnderCursor.ts +++ b/invokeai/frontend/web/src/features/canvas/hooks/useColorUnderCursor.ts @@ -1,13 +1,6 @@ import { useAppDispatch } from 'app/store/storeHooks'; -import { - $canvasBaseLayer, - $canvasStage, - $tool, -} from 'features/canvas/store/canvasNanostore'; -import { - commitColorPickerColor, - setColorPickerColor, -} from 'features/canvas/store/canvasSlice'; +import { $canvasBaseLayer, $canvasStage, $tool } from 'features/canvas/store/canvasNanostore'; +import { commitColorPickerColor, setColorPickerColor } from 'features/canvas/store/canvasSlice'; import Konva from 'konva'; import { useCallback } from 'react'; @@ -31,19 +24,9 @@ const useColorPicker = () => { const [r, g, b, a] = canvasBaseLayer .getContext() - .getImageData( - position.x * pixelRatio, - position.y * pixelRatio, - 1, - 1 - ).data; + .getImageData(position.x * pixelRatio, position.y * pixelRatio, 1, 1).data; - if ( - r === undefined || - g === undefined || - b === undefined || - a === undefined - ) { + if (r === undefined || g === undefined || b === undefined || a === undefined) { return; } diff --git a/invokeai/frontend/web/src/features/canvas/store/actions.ts b/invokeai/frontend/web/src/features/canvas/store/actions.ts index 058f853192..b6483b7f3a 100644 --- a/invokeai/frontend/web/src/features/canvas/store/actions.ts +++ b/invokeai/frontend/web/src/features/canvas/store/actions.ts @@ -3,28 +3,16 @@ import type { ImageDTO } from 'services/api/types'; export const canvasSavedToGallery = createAction('canvas/canvasSavedToGallery'); -export const canvasMaskSavedToGallery = createAction( - 'canvas/canvasMaskSavedToGallery' -); +export const canvasMaskSavedToGallery = createAction('canvas/canvasMaskSavedToGallery'); -export const canvasCopiedToClipboard = createAction( - 'canvas/canvasCopiedToClipboard' -); +export const canvasCopiedToClipboard = createAction('canvas/canvasCopiedToClipboard'); -export const canvasDownloadedAsImage = createAction( - 'canvas/canvasDownloadedAsImage' -); +export const canvasDownloadedAsImage = createAction('canvas/canvasDownloadedAsImage'); export const canvasMerged = createAction('canvas/canvasMerged'); -export const stagingAreaImageSaved = createAction<{ imageDTO: ImageDTO }>( - 'canvas/stagingAreaImageSaved' -); +export const stagingAreaImageSaved = createAction<{ imageDTO: ImageDTO }>('canvas/stagingAreaImageSaved'); -export const canvasMaskToControlAdapter = createAction<{ id: string }>( - 'canvas/canvasMaskToControlAdapter' -); +export const canvasMaskToControlAdapter = createAction<{ id: string }>('canvas/canvasMaskToControlAdapter'); -export const canvasImageToControlAdapter = createAction<{ id: string }>( - 'canvas/canvasImageToControlAdapter' -); +export const canvasImageToControlAdapter = createAction<{ id: string }>('canvas/canvasImageToControlAdapter'); diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasNanostore.ts b/invokeai/frontend/web/src/features/canvas/store/canvasNanostore.ts index d90f7942e8..81ed62addf 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasNanostore.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasNanostore.ts @@ -16,8 +16,7 @@ export const $isTransformingBoundingBox = atom(false); export const $isMouseOverBoundingBoxOutline = atom(false); export const $isModifyingBoundingBox = computed( [$isTransformingBoundingBox, $isMovingBoundingBox], - (isTransformingBoundingBox, isMovingBoundingBox) => - isTransformingBoundingBox || isMovingBoundingBox + (isTransformingBoundingBox, isMovingBoundingBox) => isTransformingBoundingBox || isMovingBoundingBox ); export const resetCanvasInteractionState = () => { diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasSelectors.ts b/invokeai/frontend/web/src/features/canvas/store/canvasSelectors.ts index 9158e3a137..a337cfaab1 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasSelectors.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasSelectors.ts @@ -6,12 +6,9 @@ import { isCanvasBaseImage } from './canvasTypes'; export const isStagingSelector = createSelector( selectCanvasSlice, - (canvas) => - canvas.batchIds.length > 0 || - canvas.layerState.stagingArea.images.length > 0 + (canvas) => canvas.batchIds.length > 0 || canvas.layerState.stagingArea.images.length > 0 ); -export const initialCanvasImageSelector = createMemoizedSelector( - selectCanvasSlice, - (canvas) => canvas.layerState.objects.find(isCanvasBaseImage) +export const initialCanvasImageSelector = createMemoizedSelector(selectCanvasSlice, (canvas) => + canvas.layerState.objects.find(isCanvasBaseImage) ); diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts index 16535ad34e..a049c13419 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts @@ -1,10 +1,7 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import type { RootState } from 'app/store/store'; -import { - roundDownToMultiple, - roundToMultiple, -} from 'common/util/roundDownToMultiple'; +import { roundDownToMultiple, roundToMultiple } from 'common/util/roundDownToMultiple'; import calculateCoordinates from 'features/canvas/util/calculateCoordinates'; import calculateScale from 'features/canvas/util/calculateScale'; import { STAGE_PADDING_PERCENTAGE } from 'features/canvas/util/constants'; @@ -14,10 +11,7 @@ import { initialAspectRatioState } from 'features/parameters/components/ImageSiz import type { AspectRatioState } from 'features/parameters/components/ImageSize/types'; import { modelChanged } from 'features/parameters/store/generationSlice'; import type { PayloadActionWithOptimalDimension } from 'features/parameters/store/types'; -import { - getIsSizeOptimal, - getOptimalDimension, -} from 'features/parameters/util/optimalDimension'; +import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension'; import type { IRect, Vector2d } from 'konva/lib/types'; import { clamp, cloneDeep } from 'lodash-es'; import type { RgbaColor } from 'react-colorful'; @@ -105,10 +99,7 @@ const setBoundingBoxDimensionsReducer = ( }; state.boundingBoxDimensions = newDimensions; if (state.boundingBoxScaleMethod === 'auto') { - const scaledDimensions = getScaledBoundingBoxDimensions( - newDimensions, - optimalDimension - ); + const scaledDimensions = getScaledBoundingBoxDimensions(newDimensions, optimalDimension); state.scaledBoundingBoxDimensions = scaledDimensions; } }; @@ -131,9 +122,7 @@ export const canvasSlice = createSlice({ }, clearMask: (state) => { state.pastLayerStates.push(cloneDeep(state.layerState)); - state.layerState.objects = state.layerState.objects.filter( - (obj) => !isCanvasMaskLine(obj) - ); + state.layerState.objects = state.layerState.objects.filter((obj) => !isCanvasMaskLine(obj)); state.futureLayerStates = []; state.shouldPreserveMaskedArea = false; }, @@ -157,32 +146,17 @@ export const canvasSlice = createSlice({ const { stageDimensions } = state; const newBoundingBoxDimensions = { - width: roundDownToMultiple( - clamp(width, CANVAS_GRID_SIZE_FINE, optimalDimension), - CANVAS_GRID_SIZE_FINE - ), - height: roundDownToMultiple( - clamp(height, CANVAS_GRID_SIZE_FINE, optimalDimension), - CANVAS_GRID_SIZE_FINE - ), + width: roundDownToMultiple(clamp(width, CANVAS_GRID_SIZE_FINE, optimalDimension), CANVAS_GRID_SIZE_FINE), + height: roundDownToMultiple(clamp(height, CANVAS_GRID_SIZE_FINE, optimalDimension), CANVAS_GRID_SIZE_FINE), }; const newBoundingBoxCoordinates = { - x: roundToMultiple( - width / 2 - newBoundingBoxDimensions.width / 2, - CANVAS_GRID_SIZE_FINE - ), - y: roundToMultiple( - height / 2 - newBoundingBoxDimensions.height / 2, - CANVAS_GRID_SIZE_FINE - ), + x: roundToMultiple(width / 2 - newBoundingBoxDimensions.width / 2, CANVAS_GRID_SIZE_FINE), + y: roundToMultiple(height / 2 - newBoundingBoxDimensions.height / 2, CANVAS_GRID_SIZE_FINE), }; if (state.boundingBoxScaleMethod === 'auto') { - const scaledDimensions = getScaledBoundingBoxDimensions( - newBoundingBoxDimensions, - optimalDimension - ); + const scaledDimensions = getScaledBoundingBoxDimensions(newBoundingBoxDimensions, optimalDimension); state.scaledBoundingBoxDimensions = scaledDimensions; } @@ -247,10 +221,7 @@ export const canvasSlice = createSlice({ setStageScale: (state, action: PayloadAction) => { state.stageScale = action.payload; }, - setShouldDarkenOutsideBoundingBox: ( - state, - action: PayloadAction - ) => { + setShouldDarkenOutsideBoundingBox: (state, action: PayloadAction) => { state.shouldDarkenOutsideBoundingBox = action.payload; }, clearCanvasHistory: (state) => { @@ -306,8 +277,7 @@ export const canvasSlice = createSlice({ imageName: image.image_name, }); - state.layerState.stagingArea.selectedImageIndex = - state.layerState.stagingArea.images.length - 1; + state.layerState.stagingArea.selectedImageIndex = state.layerState.stagingArea.images.length - 1; state.futureLayerStates = []; }, @@ -318,9 +288,7 @@ export const canvasSlice = createSlice({ state.pastLayerStates.shift(); } - state.layerState.stagingArea = cloneDeep( - cloneDeep(initialLayerState) - ).stagingArea; + state.layerState.stagingArea = cloneDeep(cloneDeep(initialLayerState)).stagingArea; state.futureLayerStates = []; state.shouldShowStagingOutline = true; @@ -328,8 +296,7 @@ export const canvasSlice = createSlice({ state.batchIds = []; }, addFillRect: (state) => { - const { boundingBoxCoordinates, boundingBoxDimensions, brushColor } = - state; + const { boundingBoxCoordinates, boundingBoxDimensions, brushColor } = state; state.pastLayerStates.push(cloneDeep(state.layerState)); @@ -365,12 +332,8 @@ export const canvasSlice = createSlice({ state.futureLayerStates = []; }, - addLine: ( - state, - action: PayloadAction<{ points: number[]; tool: CanvasTool }> - ) => { - const { layer, brushColor, brushSize, shouldRestrictStrokesToBox } = - state; + addLine: (state, action: PayloadAction<{ points: number[]; tool: CanvasTool }>) => { + const { layer, brushColor, brushSize, shouldRestrictStrokesToBox } = state; const { points, tool } = action.payload; if (tool === 'move' || tool === 'colorPicker') { @@ -380,8 +343,7 @@ export const canvasSlice = createSlice({ const newStrokeWidth = brushSize / 2; // set & then spread this to only conditionally add the "color" key - const newColor = - layer === 'base' && tool === 'brush' ? { color: brushColor } : {}; + const newColor = layer === 'base' && tool === 'brush' ? { color: brushColor } : {}; state.pastLayerStates.push(cloneDeep(state.layerState)); @@ -488,10 +450,7 @@ export const canvasSlice = createSlice({ 1 ); }, - canvasResized: ( - state, - action: PayloadAction<{ width: number; height: number }> - ) => { + canvasResized: (state, action: PayloadAction<{ width: number; height: number }>) => { state.stageDimensions = { width: Math.floor(action.payload.width), height: Math.floor(action.payload.height), @@ -540,8 +499,7 @@ export const canvasSlice = createSlice({ const nextIndex = state.layerState.stagingArea.selectedImageIndex + 1; const lastIndex = state.layerState.stagingArea.images.length - 1; - state.layerState.stagingArea.selectedImageIndex = - nextIndex > lastIndex ? 0 : nextIndex; + state.layerState.stagingArea.selectedImageIndex = nextIndex > lastIndex ? 0 : nextIndex; }, prevStagingAreaImage: (state) => { if (!state.layerState.stagingArea.images.length) { @@ -551,8 +509,7 @@ export const canvasSlice = createSlice({ const prevIndex = state.layerState.stagingArea.selectedImageIndex - 1; const lastIndex = state.layerState.stagingArea.images.length - 1; - state.layerState.stagingArea.selectedImageIndex = - prevIndex < 0 ? lastIndex : prevIndex; + state.layerState.stagingArea.selectedImageIndex = prevIndex < 0 ? lastIndex : prevIndex; }, commitStagingAreaImage: (state) => { if (!state.layerState.stagingArea.images.length) { @@ -582,19 +539,13 @@ export const canvasSlice = createSlice({ state.batchIds = []; }, setBoundingBoxScaleMethod: { - reducer: ( - state, - action: PayloadActionWithOptimalDimension - ) => { + reducer: (state, action: PayloadActionWithOptimalDimension) => { const boundingBoxScaleMethod = action.payload; const { optimalDimension } = action.meta; state.boundingBoxScaleMethod = boundingBoxScaleMethod; if (boundingBoxScaleMethod === 'auto') { - const scaledDimensions = getScaledBoundingBoxDimensions( - state.boundingBoxDimensions, - optimalDimension - ); + const scaledDimensions = getScaledBoundingBoxDimensions(state.boundingBoxDimensions, optimalDimension); state.scaledBoundingBoxDimensions = scaledDimensions; } }, @@ -605,25 +556,15 @@ export const canvasSlice = createSlice({ }, }), }, - setScaledBoundingBoxDimensions: ( - state, - action: PayloadAction> - ) => { + setScaledBoundingBoxDimensions: (state, action: PayloadAction>) => { state.scaledBoundingBoxDimensions = { ...state.scaledBoundingBoxDimensions, ...action.payload, }; }, setBoundingBoxDimensions: { - reducer: ( - state, - action: PayloadActionWithOptimalDimension> - ) => { - setBoundingBoxDimensionsReducer( - state, - action.payload, - action.meta.optimalDimension - ); + reducer: (state, action: PayloadActionWithOptimalDimension>) => { + setBoundingBoxDimensionsReducer(state, action.payload, action.meta.optimalDimension); }, prepare: (payload: Partial, optimalDimension: number) => ({ payload, @@ -660,10 +601,7 @@ export const canvasSlice = createSlice({ setShouldAntialias: (state, action: PayloadAction) => { state.shouldAntialias = action.payload; }, - setShouldCropToBoundingBoxOnSave: ( - state, - action: PayloadAction - ) => { + setShouldCropToBoundingBoxOnSave: (state, action: PayloadAction) => { state.shouldCropToBoundingBoxOnSave = action.payload; }, setColorPickerColor: (state, action: PayloadAction) => { @@ -688,9 +626,7 @@ export const canvasSlice = createSlice({ }, extraReducers: (builder) => { builder.addCase(modelChanged, (state, action) => { - if ( - action.meta.previousModel?.base_model === action.payload?.base_model - ) { + if (action.meta.previousModel?.base_model === action.payload?.base_model) { // The base model hasn't changed, we don't need to optimize the size return; } @@ -716,25 +652,15 @@ export const canvasSlice = createSlice({ } if (batch_status.in_progress === 0 && batch_status.pending === 0) { - state.batchIds = state.batchIds.filter( - (id) => id !== batch_status.batch_id - ); + state.batchIds = state.batchIds.filter((id) => id !== batch_status.batch_id); } }); - 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) - ); - } - ); + 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)); + }); }, }); diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts b/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts index 56bca50a77..dc6b764075 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts @@ -14,9 +14,8 @@ export const LAYER_NAMES = ['base', 'mask'] as const; export const zBoundingBoxScaleMethod = z.enum(['none', 'auto', 'manual']); export type BoundingBoxScaleMethod = z.infer; -export const isBoundingBoxScaleMethod = ( - v: unknown -): v is BoundingBoxScaleMethod => zBoundingBoxScaleMethod.safeParse(v).success; +export const isBoundingBoxScaleMethod = (v: unknown): v is BoundingBoxScaleMethod => + zBoundingBoxScaleMethod.safeParse(v).success; export type CanvasDrawingTool = 'brush' | 'eraser'; @@ -75,12 +74,7 @@ export type CanvasEraseRect = { height: number; }; -export type CanvasObject = - | CanvasImage - | CanvasBaseLine - | CanvasMaskLine - | CanvasFillRect - | CanvasEraseRect; +export type CanvasObject = CanvasImage | CanvasBaseLine | CanvasMaskLine | CanvasFillRect | CanvasEraseRect; export type CanvasLayerState = { objects: CanvasObject[]; @@ -112,9 +106,7 @@ export const isCanvasFillRect = (obj: CanvasObject): obj is CanvasFillRect => export const isCanvasEraseRect = (obj: CanvasObject): obj is CanvasEraseRect => obj.kind === 'eraseRect' && obj.layer === 'base'; -export const isCanvasAnyLine = ( - obj: CanvasObject -): obj is CanvasMaskLine | CanvasBaseLine => obj.kind === 'line'; +export const isCanvasAnyLine = (obj: CanvasObject): obj is CanvasMaskLine | CanvasBaseLine => obj.kind === 'line'; export interface CanvasState { _version: 1; diff --git a/invokeai/frontend/web/src/features/canvas/util/calculateCoordinates.ts b/invokeai/frontend/web/src/features/canvas/util/calculateCoordinates.ts index e6c935c95b..fe9c14b2ba 100644 --- a/invokeai/frontend/web/src/features/canvas/util/calculateCoordinates.ts +++ b/invokeai/frontend/web/src/features/canvas/util/calculateCoordinates.ts @@ -9,12 +9,8 @@ const calculateCoordinates = ( contentHeight: number, scale: number ): Vector2d => { - const x = Math.floor( - containerWidth / 2 - (containerX + contentWidth / 2) * scale - ); - const y = Math.floor( - containerHeight / 2 - (containerY + contentHeight / 2) * scale - ); + const x = Math.floor(containerWidth / 2 - (containerX + contentWidth / 2) * scale); + const y = Math.floor(containerHeight / 2 - (containerY + contentHeight / 2) * scale); return { x, y }; }; diff --git a/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts b/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts index 4a7ceb5d50..d0a71dee40 100644 --- a/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts +++ b/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts @@ -44,8 +44,7 @@ const createMaskStage = async ( lineCap: 'round', lineJoin: 'round', shadowForStrokeEnabled: false, - globalCompositeOperation: - line.tool === 'brush' ? 'source-over' : 'destination-out', + globalCompositeOperation: line.tool === 'brush' ? 'source-over' : 'destination-out', }) ) ); diff --git a/invokeai/frontend/web/src/features/canvas/util/dataURLToImageData.ts b/invokeai/frontend/web/src/features/canvas/util/dataURLToImageData.ts index 739240a79d..d19cbe4612 100644 --- a/invokeai/frontend/web/src/features/canvas/util/dataURLToImageData.ts +++ b/invokeai/frontend/web/src/features/canvas/util/dataURLToImageData.ts @@ -1,11 +1,7 @@ /** * Gets an ImageData object from an image dataURL by drawing it to a canvas. */ -export const dataURLToImageData = async ( - dataURL: string, - width: number, - height: number -): Promise => +export const dataURLToImageData = async (dataURL: string, width: number, height: number): Promise => new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); canvas.width = width; diff --git a/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts b/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts index ac6bed10a7..d37d644008 100644 --- a/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts +++ b/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts @@ -6,21 +6,14 @@ import { konvaNodeToBlob } from './konvaNodeToBlob'; /** * Get the canvas base layer blob, with or without bounding box according to `shouldCropToBoundingBoxOnSave` */ -export const getBaseLayerBlob = async ( - state: RootState, - alwaysUseBoundingBox: boolean = false -) => { +export const getBaseLayerBlob = async (state: RootState, alwaysUseBoundingBox: boolean = false) => { const canvasBaseLayer = $canvasBaseLayer.get(); if (!canvasBaseLayer) { throw new Error('Problem getting base layer blob'); } - const { - shouldCropToBoundingBoxOnSave, - boundingBoxCoordinates, - boundingBoxDimensions, - } = state.canvas; + const { shouldCropToBoundingBoxOnSave, boundingBoxCoordinates, boundingBoxDimensions } = state.canvas; const clonedBaseLayer = canvasBaseLayer.clone(); diff --git a/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts b/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts index e521cbe091..d17096cb71 100644 --- a/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts +++ b/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts @@ -1,12 +1,6 @@ import { logger } from 'app/logging/logger'; -import { - $canvasBaseLayer, - $canvasStage, -} from 'features/canvas/store/canvasNanostore'; -import type { - CanvasLayerState, - Dimensions, -} from 'features/canvas/store/canvasTypes'; +import { $canvasBaseLayer, $canvasStage } from 'features/canvas/store/canvasNanostore'; +import type { CanvasLayerState, Dimensions } from 'features/canvas/store/canvasTypes'; import { isCanvasMaskLine } from 'features/canvas/store/canvasTypes'; import { konvaNodeToImageData } from 'features/canvas/util/konvaNodeToImageData'; import type { Vector2d } from 'konva/lib/types'; @@ -57,10 +51,7 @@ export const getCanvasData = async ( // For the base layer, use the offset boundingBox const baseBlob = await konvaNodeToBlob(clonedBaseLayer, offsetBoundingBox); - const baseImageData = await konvaNodeToImageData( - clonedBaseLayer, - offsetBoundingBox - ); + const baseImageData = await konvaNodeToImageData(clonedBaseLayer, offsetBoundingBox); // For the mask layer, use the normal boundingBox const maskStage = await createMaskStage( diff --git a/invokeai/frontend/web/src/features/canvas/util/getCanvasGenerationMode.ts b/invokeai/frontend/web/src/features/canvas/util/getCanvasGenerationMode.ts index aa3b586869..f0a3464986 100644 --- a/invokeai/frontend/web/src/features/canvas/util/getCanvasGenerationMode.ts +++ b/invokeai/frontend/web/src/features/canvas/util/getCanvasGenerationMode.ts @@ -1,17 +1,9 @@ -import { - areAnyPixelsBlack, - getImageDataTransparency, -} from 'common/util/arrayBuffer'; +import { areAnyPixelsBlack, getImageDataTransparency } from 'common/util/arrayBuffer'; import type { GenerationMode } from 'features/canvas/store/canvasTypes'; -export const getCanvasGenerationMode = ( - baseImageData: ImageData, - maskImageData: ImageData -): GenerationMode => { - const { - isPartiallyTransparent: baseIsPartiallyTransparent, - isFullyTransparent: baseIsFullyTransparent, - } = getImageDataTransparency(baseImageData.data); +export const getCanvasGenerationMode = (baseImageData: ImageData, maskImageData: ImageData): GenerationMode => { + const { isPartiallyTransparent: baseIsPartiallyTransparent, isFullyTransparent: baseIsFullyTransparent } = + getImageDataTransparency(baseImageData.data); // check mask for black const doesMaskHaveBlackPixels = areAnyPixelsBlack(maskImageData.data); diff --git a/invokeai/frontend/web/src/features/canvas/util/getScaledBoundingBoxDimensions.ts b/invokeai/frontend/web/src/features/canvas/util/getScaledBoundingBoxDimensions.ts index 4f8f217701..de38d12cf5 100644 --- a/invokeai/frontend/web/src/features/canvas/util/getScaledBoundingBoxDimensions.ts +++ b/invokeai/frontend/web/src/features/canvas/util/getScaledBoundingBoxDimensions.ts @@ -2,10 +2,7 @@ import { roundToMultiple } from 'common/util/roundDownToMultiple'; import type { Dimensions } from 'features/canvas/store/canvasTypes'; import { CANVAS_GRID_SIZE_FINE } from 'features/canvas/store/constants'; -const getScaledBoundingBoxDimensions = ( - dimensions: Dimensions, - optimalDimension: number -) => { +const getScaledBoundingBoxDimensions = (dimensions: Dimensions, optimalDimension: number) => { const { width, height } = dimensions; const scaledDimensions = { width, height }; @@ -22,16 +19,10 @@ const getScaledBoundingBoxDimensions = ( } else { if (aspectRatio > 1) { scaledDimensions.width = maxDimension; - scaledDimensions.height = roundToMultiple( - maxDimension / aspectRatio, - CANVAS_GRID_SIZE_FINE - ); + scaledDimensions.height = roundToMultiple(maxDimension / aspectRatio, CANVAS_GRID_SIZE_FINE); } else if (aspectRatio < 1) { scaledDimensions.height = maxDimension; - scaledDimensions.width = roundToMultiple( - maxDimension * aspectRatio, - CANVAS_GRID_SIZE_FINE - ); + scaledDimensions.width = roundToMultiple(maxDimension * aspectRatio, CANVAS_GRID_SIZE_FINE); } currentArea = scaledDimensions.width * scaledDimensions.height; } diff --git a/invokeai/frontend/web/src/features/canvas/util/isElChildOfCanvasTab.tsx b/invokeai/frontend/web/src/features/canvas/util/isElChildOfCanvasTab.tsx index ea2b781e34..a59e780abc 100644 --- a/invokeai/frontend/web/src/features/canvas/util/isElChildOfCanvasTab.tsx +++ b/invokeai/frontend/web/src/features/canvas/util/isElChildOfCanvasTab.tsx @@ -7,8 +7,6 @@ import { CANVAS_TAB_TESTID } from 'features/canvas/store/constants'; * it's safer to check the canvas tab and grab its parent. */ export const isElChildOfCanvasTab = (el: HTMLElement) => { - const canvasContainerEl = document.querySelector( - `[data-testid="${CANVAS_TAB_TESTID}"]` - ); + const canvasContainerEl = document.querySelector(`[data-testid="${CANVAS_TAB_TESTID}"]`); return Boolean(canvasContainerEl?.parentElement?.contains(el)); }; diff --git a/invokeai/frontend/web/src/features/canvas/util/konvaNodeToBlob.ts b/invokeai/frontend/web/src/features/canvas/util/konvaNodeToBlob.ts index 40b9768e5a..e16988ea23 100644 --- a/invokeai/frontend/web/src/features/canvas/util/konvaNodeToBlob.ts +++ b/invokeai/frontend/web/src/features/canvas/util/konvaNodeToBlob.ts @@ -9,9 +9,6 @@ import { canvasToBlob } from './canvasToBlob'; * @param boundingBox - The bounding box to crop to * @returns A Promise that resolves with Blob of the node cropped to the bounding box */ -export const konvaNodeToBlob = async ( - node: Konva.Node, - boundingBox: IRect -): Promise => { +export const konvaNodeToBlob = async (node: Konva.Node, boundingBox: IRect): Promise => { return await canvasToBlob(node.toCanvas(boundingBox)); }; diff --git a/invokeai/frontend/web/src/features/canvas/util/konvaNodeToImageData.ts b/invokeai/frontend/web/src/features/canvas/util/konvaNodeToImageData.ts index e3c3c008fa..3b5780ae16 100644 --- a/invokeai/frontend/web/src/features/canvas/util/konvaNodeToImageData.ts +++ b/invokeai/frontend/web/src/features/canvas/util/konvaNodeToImageData.ts @@ -9,16 +9,9 @@ import { dataURLToImageData } from './dataURLToImageData'; * @param boundingBox - The bounding box to crop to * @returns A Promise that resolves with ImageData object of the node cropped to the bounding box */ -export const konvaNodeToImageData = async ( - node: Konva.Node, - boundingBox: IRect -): Promise => { +export const konvaNodeToImageData = async (node: Konva.Node, boundingBox: IRect): Promise => { // get a dataURL of the bbox'd region const dataURL = node.toDataURL(boundingBox); - return await dataURLToImageData( - dataURL, - boundingBox.width, - boundingBox.height - ); + return await dataURLToImageData(dataURL, boundingBox.width, boundingBox.height); }; diff --git a/invokeai/frontend/web/src/features/canvas/util/roundDimensionsToMultiple.ts b/invokeai/frontend/web/src/features/canvas/util/roundDimensionsToMultiple.ts index 18141d29a8..8e526a54e6 100644 --- a/invokeai/frontend/web/src/features/canvas/util/roundDimensionsToMultiple.ts +++ b/invokeai/frontend/web/src/features/canvas/util/roundDimensionsToMultiple.ts @@ -1,10 +1,7 @@ import { roundToMultiple } from 'common/util/roundDownToMultiple'; import type { Dimensions } from 'features/canvas/store/canvasTypes'; -const roundDimensionsToMultiple = ( - dimensions: Dimensions, - multiple: number -): Dimensions => { +const roundDimensionsToMultiple = (dimensions: Dimensions, multiple: number): Dimensions => { return { width: roundToMultiple(dimensions.width, multiple), height: roundToMultiple(dimensions.height, multiple), diff --git a/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx b/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx index d7e774c87f..218e297393 100644 --- a/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx +++ b/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx @@ -1,11 +1,5 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { - Combobox, - ConfirmationAlertDialog, - Flex, - FormControl, - Text, -} from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, ConfirmationAlertDialog, Flex, FormControl, Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { @@ -16,10 +10,7 @@ import { import { memo, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useListAllBoardsQuery } from 'services/api/endpoints/boards'; -import { - useAddImagesToBoardMutation, - useRemoveImagesFromBoardMutation, -} from 'services/api/endpoints/images'; +import { useAddImagesToBoardMutation, useRemoveImagesFromBoardMutation } from 'services/api/endpoints/images'; const selectImagesToChange = createMemoizedSelector( selectChangeBoardModalSlice, @@ -45,10 +36,7 @@ const ChangeBoardModal = () => { ); }, [boards, t]); - const value = useMemo( - () => options.find((o) => o.value === selectedBoard), - [options, selectedBoard] - ); + const value = useMemo(() => options.find((o) => o.value === selectedBoard), [options, selectedBoard]); const handleClose = useCallback(() => { dispatch(changeBoardReset()); @@ -70,13 +58,7 @@ const ChangeBoardModal = () => { } setSelectedBoard(null); dispatch(changeBoardReset()); - }, [ - addImagesToBoard, - dispatch, - imagesToChange, - removeImagesFromBoard, - selectedBoard, - ]); + }, [addImagesToBoard, dispatch, imagesToChange, removeImagesFromBoard, selectedBoard]); const onChange = useCallback((v) => { if (!v) { @@ -103,9 +85,7 @@ const ChangeBoardModal = () => { - state.changeBoardModal; +export const selectChangeBoardModalSlice = (state: RootState) => state.changeBoardModal; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterConfig.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterConfig.tsx index 8c40777714..6124823808 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterConfig.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterConfig.tsx @@ -1,12 +1,4 @@ -import { - Box, - Flex, - FormControl, - FormLabel, - Icon, - IconButton, - Switch, -} from '@invoke-ai/ui'; +import { Box, Flex, FormControl, FormLabel, Icon, IconButton, Switch } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled'; import { useControlAdapterType } from 'features/controlAdapters/hooks/useControlAdapterType'; @@ -68,19 +60,10 @@ const ControlAdapterConfig = (props: { id: string; number: number }) => { } return ( - + - - {t(`controlnet.${controlAdapterType}`, { number })} - + {t(`controlnet.${controlAdapterType}`, { number })} { - + - {activeTabName === 'unifiedCanvas' && ( - - )} + {activeTabName === 'unifiedCanvas' && } { /> { {!isExpanded && ( - + )} diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx index 8c4e96e799..32aca81185 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx @@ -1,5 +1,5 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { Box, Flex, Spinner } from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Box, Flex, Spinner } from '@invoke-ai/ui-library'; import { skipToken } from '@reduxjs/toolkit/query'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; @@ -13,23 +13,12 @@ import { controlAdapterImageChanged, selectControlAdaptersSlice, } from 'features/controlAdapters/store/controlAdaptersSlice'; -import type { - TypesafeDraggableData, - TypesafeDroppableData, -} from 'features/dnd/types'; -import { - heightChanged, - selectOptimalDimension, - widthChanged, -} from 'features/parameters/store/generationSlice'; +import type { TypesafeDraggableData, TypesafeDroppableData } from 'features/dnd/types'; +import { heightChanged, selectOptimalDimension, widthChanged } from 'features/parameters/store/generationSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { - PiArrowCounterClockwiseBold, - PiFloppyDiskBold, - PiRulerBold, -} from 'react-icons/pi'; +import { PiArrowCounterClockwiseBold, PiFloppyDiskBold, PiRulerBold } from 'react-icons/pi'; import { useAddImageToBoardMutation, useChangeImageIsIntermediateMutation, @@ -62,13 +51,13 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => { const [isMouseOverImage, setIsMouseOverImage] = useState(false); - const { currentData: controlImage, isError: isErrorControlImage } = - useGetImageDTOQuery(controlImageName ?? skipToken); + const { currentData: controlImage, isError: isErrorControlImage } = useGetImageDTOQuery( + controlImageName ?? skipToken + ); - const { - currentData: processedControlImage, - isError: isErrorProcessedControlImage, - } = useGetImageDTOQuery(processedControlImageName ?? skipToken); + const { currentData: processedControlImage, isError: isErrorProcessedControlImage } = useGetImageDTOQuery( + processedControlImageName ?? skipToken + ); const [changeIsIntermediate] = useChangeImageIsIntermediateMutation(); const [addToBoard] = useAddImageToBoardMutation(); @@ -95,13 +84,7 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => { } else { removeFromBoard({ imageDTO: processedControlImage }); } - }, [ - processedControlImage, - changeIsIntermediate, - autoAddBoardId, - addToBoard, - removeFromBoard, - ]); + }, [processedControlImage, changeIsIntermediate, autoAddBoardId, addToBoard, removeFromBoard]); const handleSetControlImageToDimensions = useCallback(() => { if (!controlImage) { @@ -151,10 +134,7 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => { [id] ); - const postUploadAction = useMemo( - () => ({ type: 'SET_CONTROL_ADAPTER_IMAGE', id }), - [id] - ); + const postUploadAction = useMemo(() => ({ type: 'SET_CONTROL_ADAPTER_IMAGE', id }), [id]); const shouldShowProcessedImage = controlImage && @@ -167,12 +147,7 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => { if (isConnected && (isErrorControlImage || isErrorProcessedControlImage)) { handleResetControlImage(); } - }, [ - handleResetControlImage, - isConnected, - isErrorControlImage, - isErrorProcessedControlImage, - ]); + }, [handleResetControlImage, isConnected, isErrorControlImage, isErrorProcessedControlImage]); return ( { <> : undefined - } + icon={controlImage ? : undefined} tooltip={t('controlnet.resetControlImage')} /> { } if (processorNode.type === 'canny_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'color_map_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'depth_anything_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'hed_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'lineart_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'content_shuffle_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'lineart_anime_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'mediapipe_face_processor') { - return ( - - ); + return ; } if (processorNode.type === 'midas_depth_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'mlsd_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'normalbae_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'openpose_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'pidi_image_processor') { - return ( - - ); + return ; } if (processorNode.type === 'zoe_depth_image_processor') { - return ( - - ); + return ; } return null; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterShouldAutoConfig.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterShouldAutoConfig.tsx index 073595cf38..7399febb2d 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterShouldAutoConfig.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterShouldAutoConfig.tsx @@ -1,4 +1,4 @@ -import { FormControl, FormLabel, Switch } from '@invoke-ai/ui'; +import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled'; import { useControlAdapterShouldAutoConfig } from 'features/controlAdapters/hooks/useControlAdapterShouldAutoConfig'; @@ -28,10 +28,7 @@ const ControlAdapterShouldAutoConfig = ({ id }: Props) => { return ( {t('controlnet.autoConfigure')} - + ); }; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/imports/ControlNetCanvasImageImports.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/imports/ControlNetCanvasImageImports.tsx index 4c94448cf5..fada3e3abf 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/imports/ControlNetCanvasImageImports.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/imports/ControlNetCanvasImageImports.tsx @@ -1,9 +1,6 @@ -import { Flex, IconButton } from '@invoke-ai/ui'; +import { Flex, IconButton } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; -import { - canvasImageToControlAdapter, - canvasMaskToControlAdapter, -} from 'features/canvas/store/actions'; +import { canvasImageToControlAdapter, canvasMaskToControlAdapter } from 'features/canvas/store/actions'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiExcludeBold, PiImageSquareBold } from 'react-icons/pi'; @@ -12,9 +9,7 @@ type ControlNetCanvasImageImportsProps = { id: string; }; -const ControlNetCanvasImageImports = ( - props: ControlNetCanvasImageImportsProps -) => { +const ControlNetCanvasImageImports = (props: ControlNetCanvasImageImportsProps) => { const { id } = props; const dispatch = useAppDispatch(); const { t } = useTranslation(); diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterBeginEnd.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterBeginEnd.tsx index 891cd1776a..a62f7e7d8a 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterBeginEnd.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterBeginEnd.tsx @@ -1,4 +1,4 @@ -import { CompositeRangeSlider, FormControl, FormLabel } from '@invoke-ai/ui'; +import { CompositeRangeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { useControlAdapterBeginEndStepPct } from 'features/controlAdapters/hooks/useControlAdapterBeginEndStepPct'; import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled'; @@ -54,10 +54,7 @@ export const ParamControlAdapterBeginEnd = memo(({ id }: Props) => { ); }, [dispatch, id]); - const value = useMemo<[number, number]>( - () => [stepPcts?.beginStepPct ?? 0, stepPcts?.endStepPct ?? 1], - [stepPcts] - ); + const value = useMemo<[number, number]>(() => [stepPcts?.beginStepPct ?? 0, stepPcts?.endStepPct ?? 1], [stepPcts]); if (!stepPcts) { return null; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterControlMode.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterControlMode.tsx index 1cee707bb6..ea16d6bc1f 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterControlMode.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterControlMode.tsx @@ -1,5 +1,5 @@ -import type { ComboboxOnChange } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; import { useControlAdapterControlMode } from 'features/controlAdapters/hooks/useControlAdapterControlMode'; @@ -58,11 +58,7 @@ const ParamControlAdapterControlMode = ({ id }: Props) => { {t('controlnet.controlMode')} - + ); }; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterModel.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterModel.tsx index 8323675caf..13851b143c 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterModel.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterModel.tsx @@ -1,4 +1,4 @@ -import { Combobox, FormControl, Tooltip } from '@invoke-ai/ui'; +import { Combobox, FormControl, Tooltip } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useGroupedModelCombobox } from 'common/hooks/useGroupedModelCombobox'; @@ -22,32 +22,21 @@ type ParamControlAdapterModelProps = { id: string; }; -const selectMainModel = createMemoizedSelector( - selectGenerationSlice, - (generation) => generation.model -); +const selectMainModel = createMemoizedSelector(selectGenerationSlice, (generation) => generation.model); const ParamControlAdapterModel = ({ id }: ParamControlAdapterModelProps) => { const isEnabled = useControlAdapterIsEnabled(id); const controlAdapterType = useControlAdapterType(id); const model = useControlAdapterModel(id); const dispatch = useAppDispatch(); - const currentBaseModel = useAppSelector( - (s) => s.generation.model?.base_model - ); + const currentBaseModel = useAppSelector((s) => s.generation.model?.base_model); const mainModel = useAppSelector(selectMainModel); const { t } = useTranslation(); const models = useControlAdapterModelEntities(controlAdapterType); const _onChange = useCallback( - ( - model: - | ControlNetModelConfigEntity - | IPAdapterModelConfigEntity - | T2IAdapterModelConfigEntity - | null - ) => { + (model: ControlNetModelConfigEntity | IPAdapterModelConfigEntity | T2IAdapterModelConfigEntity | null) => { if (!model) { return; } @@ -62,10 +51,7 @@ const ParamControlAdapterModel = ({ id }: ParamControlAdapterModelProps) => { ); const selectedModel = useMemo( - () => - model && controlAdapterType - ? { ...model, model_type: controlAdapterType } - : null, + () => (model && controlAdapterType ? { ...model, model_type: controlAdapterType } : null), [controlAdapterType, model] ); @@ -78,20 +64,16 @@ const ParamControlAdapterModel = ({ id }: ParamControlAdapterModelProps) => { [currentBaseModel] ); - const { options, value, onChange, noOptionsMessage } = - useGroupedModelCombobox({ - modelEntities: models, - onChange: _onChange, - selectedModel, - getIsDisabled, - }); + const { options, value, onChange, noOptionsMessage } = useGroupedModelCombobox({ + modelEntities: models, + onChange: _onChange, + selectedModel, + getIsDisabled, + }); return ( - + { })) .sort((a, b) => // sort 'none' to the top - a.value === 'none' - ? -1 - : b.value === 'none' - ? 1 - : a.label.localeCompare(b.label) + a.value === 'none' ? -1 : b.value === 'none' ? 1 : a.label.localeCompare(b.label) ) - .filter( - (d) => - !config.sd.disabledControlNetProcessors.includes( - d.value as ControlAdapterProcessorType - ) - ); + .filter((d) => !config.sd.disabledControlNetProcessors.includes(d.value as ControlAdapterProcessorType)); return options; }); @@ -60,10 +51,7 @@ const ParamControlAdapterProcessorSelect = ({ id }: Props) => { }, [id, dispatch] ); - const value = useMemo( - () => options.find((o) => o.value === processorNode?.type), - [options, processorNode] - ); + const value = useMemo(() => options.find((o) => o.value === processorNode?.type), [options, processorNode]); if (!processorNode) { return null; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterResizeMode.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterResizeMode.tsx index 1ee1fdc2ca..58b8905f5a 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterResizeMode.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterResizeMode.tsx @@ -1,5 +1,5 @@ -import type { ComboboxOnChange } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled'; @@ -45,10 +45,7 @@ const ParamControlAdapterResizeMode = ({ id }: Props) => { [id, dispatch] ); - const value = useMemo( - () => options.find((o) => o.value === resizeMode), - [options, resizeMode] - ); + const value = useMemo(() => options.find((o) => o.value === resizeMode), [options, resizeMode]); if (!resizeMode) { return null; @@ -59,12 +56,7 @@ const ParamControlAdapterResizeMode = ({ id }: Props) => { {t('controlnet.resizeMode')} - + ); }; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx index 27a4115ae7..7f45901f53 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled'; @@ -27,12 +22,8 @@ const ParamControlAdapterWeight = ({ id }: ParamControlAdapterWeightProps) => { const initial = useAppSelector((s) => s.config.sd.ca.weight.initial); const sliderMin = useAppSelector((s) => s.config.sd.ca.weight.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.ca.weight.sliderMax); - const numberInputMin = useAppSelector( - (s) => s.config.sd.ca.weight.numberInputMin - ); - const numberInputMax = useAppSelector( - (s) => s.config.sd.ca.weight.numberInputMax - ); + const numberInputMin = useAppSelector((s) => s.config.sd.ca.weight.numberInputMin); + const numberInputMax = useAppSelector((s) => s.config.sd.ca.weight.numberInputMax); const coarseStep = useAppSelector((s) => s.config.sd.ca.weight.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.ca.weight.fineStep); diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/CannyProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/CannyProcessor.tsx index 4803188202..1cc458be8e 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/CannyProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/CannyProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredCannyImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -12,8 +7,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.canny_image_processor - .default as RequiredCannyImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.canny_image_processor.default as RequiredCannyImageProcessorInvocation; type CannyProcessorProps = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/ColorMapProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/ColorMapProcessor.tsx index efbd4e5ba5..b0ddde6f93 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/ColorMapProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/ColorMapProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredColorMapImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -12,8 +7,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.color_map_image_processor - .default as RequiredColorMapImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.color_map_image_processor.default as RequiredColorMapImageProcessorInvocation; type ColorMapProcessorProps = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/ContentShuffleProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/ContentShuffleProcessor.tsx index cca0aba74c..413f301f5a 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/ContentShuffleProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/ContentShuffleProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredContentShuffleImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -102,57 +97,18 @@ const ContentShuffleProcessor = (props: Props) => { {t('controlnet.w')} - - + + {t('controlnet.h')} - - + + {t('controlnet.f')} - - + + ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/DepthAnyThingProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/DepthAnyThingProcessor.tsx index 025c53743e..272a2cab49 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/DepthAnyThingProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/DepthAnyThingProcessor.tsx @@ -1,11 +1,5 @@ -import type { ComboboxOnChange } from '@invoke-ai/ui'; -import { - Combobox, - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import type { ComboboxOnChange } from '@invoke-ai/ui-library'; +import { Combobox, CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { @@ -55,10 +49,7 @@ const DepthAnythingProcessor = (props: Props) => { [t] ); - const value = useMemo( - () => options.filter((o) => o.value === model_size)[0], - [options, model_size] - ); + const value = useMemo(() => options.filter((o) => o.value === model_size)[0], [options, model_size]); const handleResolutionChange = useCallback( (v: number) => { diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/HedProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/HedProcessor.tsx index 83c406829b..2452021d5e 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/HedProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/HedProcessor.tsx @@ -1,10 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, - Switch, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredHedImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -14,8 +8,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.hed_image_processor - .default as RequiredHedImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.hed_image_processor.default as RequiredHedImageProcessorInvocation; type HedProcessorProps = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartAnimeProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartAnimeProcessor.tsx index a1651cd428..3d08e4724a 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartAnimeProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartAnimeProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredLineartAnimeImageProcessorInvocation } from 'features/controlAdapters/store/types'; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartProcessor.tsx index 3535d15d3c..22a96f51f9 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/LineartProcessor.tsx @@ -1,10 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, - Switch, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredLineartImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -14,8 +8,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.lineart_image_processor - .default as RequiredLineartImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.lineart_image_processor.default as RequiredLineartImageProcessorInvocation; type LineartProcessorProps = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/MediapipeFaceProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/MediapipeFaceProcessor.tsx index e914491000..a0d5308210 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/MediapipeFaceProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/MediapipeFaceProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredMediapipeFaceProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -12,8 +7,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.mediapipe_face_processor - .default as RequiredMediapipeFaceProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.mediapipe_face_processor.default as RequiredMediapipeFaceProcessorInvocation; type Props = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/MidasDepthProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/MidasDepthProcessor.tsx index e95c4c8a7f..ba245bc2eb 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/MidasDepthProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/MidasDepthProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredMidasDepthImageProcessorInvocation } from 'features/controlAdapters/store/types'; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/MlsdImageProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/MlsdImageProcessor.tsx index 34a993b070..5138b2168b 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/MlsdImageProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/MlsdImageProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredMlsdImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -12,8 +7,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.mlsd_image_processor - .default as RequiredMlsdImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.mlsd_image_processor.default as RequiredMlsdImageProcessorInvocation; type Props = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/NormalBaeProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/NormalBaeProcessor.tsx index 24b83ef950..d05f600eaf 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/NormalBaeProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/NormalBaeProcessor.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredNormalbaeImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -12,8 +7,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.normalbae_image_processor - .default as RequiredNormalbaeImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.normalbae_image_processor.default as RequiredNormalbaeImageProcessorInvocation; type Props = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/OpenposeProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/OpenposeProcessor.tsx index 8385183cbc..bdc2e633ae 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/OpenposeProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/OpenposeProcessor.tsx @@ -1,10 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, - Switch, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredOpenposeImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -14,8 +8,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.openpose_image_processor - .default as RequiredOpenposeImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.openpose_image_processor.default as RequiredOpenposeImageProcessorInvocation; type Props = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/PidiProcessor.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/PidiProcessor.tsx index e8dac66e19..8948e8250d 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/PidiProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/PidiProcessor.tsx @@ -1,10 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, - Switch, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useProcessorNodeChanged } from 'features/controlAdapters/components/hooks/useProcessorNodeChanged'; import { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants'; import type { RequiredPidiImageProcessorInvocation } from 'features/controlAdapters/store/types'; @@ -14,8 +8,7 @@ import { useTranslation } from 'react-i18next'; import ProcessorWrapper from './common/ProcessorWrapper'; -const DEFAULTS = CONTROLNET_PROCESSORS.pidi_image_processor - .default as RequiredPidiImageProcessorInvocation; +const DEFAULTS = CONTROLNET_PROCESSORS.pidi_image_processor.default as RequiredPidiImageProcessorInvocation; type Props = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/processors/common/ProcessorWrapper.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/processors/common/ProcessorWrapper.tsx index 1eb1b45de1..0b99887b53 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/processors/common/ProcessorWrapper.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/processors/common/ProcessorWrapper.tsx @@ -1,4 +1,4 @@ -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import type { PropsWithChildren } from 'react'; import { memo } from 'react'; diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useAddControlAdapter.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useAddControlAdapter.ts index c08adc7f6f..51b36968d2 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useAddControlAdapter.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useAddControlAdapter.ts @@ -13,9 +13,7 @@ export const useAddControlAdapter = (type: ControlAdapterType) => { const firstModel = useMemo(() => { // prefer to use a model that matches the base model - const firstCompatibleModel = models.filter((m) => - baseModel ? m.base_model === baseModel : true - )[0]; + const firstCompatibleModel = models.filter((m) => (baseModel ? m.base_model === baseModel : true))[0]; if (firstCompatibleModel) { return firstCompatibleModel; diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterControlImage.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterControlImage.ts index 2ac85b960a..c8efdf9125 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterControlImage.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterControlImage.ts @@ -11,8 +11,7 @@ export const useControlAdapterControlImage = (id: string) => { () => createSelector( selectControlAdaptersSlice, - (controlAdapters) => - selectControlAdapterById(controlAdapters, id)?.controlImage + (controlAdapters) => selectControlAdapterById(controlAdapters, id)?.controlImage ), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterIsEnabled.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterIsEnabled.ts index ba4e263f59..58bb956ce3 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterIsEnabled.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterIsEnabled.ts @@ -11,8 +11,7 @@ export const useControlAdapterIsEnabled = (id: string) => { () => createSelector( selectControlAdaptersSlice, - (controlAdapters) => - selectControlAdapterById(controlAdapters, id)?.isEnabled ?? false + (controlAdapters) => selectControlAdapterById(controlAdapters, id)?.isEnabled ?? false ), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModel.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModel.ts index dd23c8ff44..1416c8c9f1 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModel.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModel.ts @@ -11,8 +11,7 @@ export const useControlAdapterModel = (id: string) => { () => createMemoizedSelector( selectControlAdaptersSlice, - (controlAdapters) => - selectControlAdapterById(controlAdapters, id)?.model + (controlAdapters) => selectControlAdapterById(controlAdapters, id)?.model ), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModels.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModels.ts index 57da6ec6e8..dd23211b9b 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModels.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterModels.ts @@ -12,27 +12,18 @@ import { export const useControlAdapterModels = (type?: ControlAdapterType) => { const { data: controlNetModelsData } = useGetControlNetModelsQuery(); const controlNetModels = useMemo( - () => - controlNetModelsData - ? controlNetModelsAdapterSelectors.selectAll(controlNetModelsData) - : [], + () => (controlNetModelsData ? controlNetModelsAdapterSelectors.selectAll(controlNetModelsData) : []), [controlNetModelsData] ); const { data: t2iAdapterModelsData } = useGetT2IAdapterModelsQuery(); const t2iAdapterModels = useMemo( - () => - t2iAdapterModelsData - ? t2iAdapterModelsAdapterSelectors.selectAll(t2iAdapterModelsData) - : [], + () => (t2iAdapterModelsData ? t2iAdapterModelsAdapterSelectors.selectAll(t2iAdapterModelsData) : []), [t2iAdapterModelsData] ); const { data: ipAdapterModelsData } = useGetIPAdapterModelsQuery(); const ipAdapterModels = useMemo( - () => - ipAdapterModelsData - ? ipAdapterModelsAdapterSelectors.selectAll(ipAdapterModelsData) - : [], + () => (ipAdapterModelsData ? ipAdapterModelsAdapterSelectors.selectAll(ipAdapterModelsData) : []), [ipAdapterModelsData] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessedControlImage.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessedControlImage.ts index d316ecb0a0..a02e1f9ed9 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessedControlImage.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessedControlImage.ts @@ -13,9 +13,7 @@ export const useControlAdapterProcessedControlImage = (id: string) => { createSelector(selectControlAdaptersSlice, (controlAdapters) => { const ca = selectControlAdapterById(controlAdapters, id); - return ca && isControlNetOrT2IAdapter(ca) - ? ca.processedControlImage - : undefined; + return ca && isControlNetOrT2IAdapter(ca) ? ca.processedControlImage : undefined; }), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorNode.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorNode.ts index 6626374dd2..272af132a6 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorNode.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorNode.ts @@ -13,9 +13,7 @@ export const useControlAdapterProcessorNode = (id: string) => { createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => { const ca = selectControlAdapterById(controlAdapters, id); - return ca && isControlNetOrT2IAdapter(ca) - ? ca.processorNode - : undefined; + return ca && isControlNetOrT2IAdapter(ca) ? ca.processorNode : undefined; }), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorType.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorType.ts index b7b58aed8b..777bfc05b4 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorType.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterProcessorType.ts @@ -13,9 +13,7 @@ export const useControlAdapterProcessorType = (id: string) => { createSelector(selectControlAdaptersSlice, (controlAdapters) => { const ca = selectControlAdapterById(controlAdapters, id); - return ca && isControlNetOrT2IAdapter(ca) - ? ca.processorType - : undefined; + return ca && isControlNetOrT2IAdapter(ca) ? ca.processorType : undefined; }), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterWeight.ts b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterWeight.ts index 53f1074bd0..9e65993fde 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterWeight.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/hooks/useControlAdapterWeight.ts @@ -11,8 +11,7 @@ export const useControlAdapterWeight = (id: string) => { () => createSelector( selectControlAdaptersSlice, - (controlAdapters) => - selectControlAdapterById(controlAdapters, id)?.weight + (controlAdapters) => selectControlAdapterById(controlAdapters, id)?.weight ), [id] ); diff --git a/invokeai/frontend/web/src/features/controlAdapters/store/constants.ts b/invokeai/frontend/web/src/features/controlAdapters/store/constants.ts index ddebffcfde..61af98afc4 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/store/constants.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/store/constants.ts @@ -1,9 +1,6 @@ import i18n from 'i18next'; -import type { - ControlAdapterProcessorType, - RequiredControlAdapterProcessorNode, -} from './types'; +import type { ControlAdapterProcessorType, RequiredControlAdapterProcessorNode } from './types'; type ControlNetProcessorsDict = Record< ControlAdapterProcessorType, diff --git a/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersPersistDenylist.ts b/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersPersistDenylist.ts index 0dfd46889f..ff8fcd1594 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersPersistDenylist.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersPersistDenylist.ts @@ -3,6 +3,4 @@ import type { ControlAdaptersState } from './types'; /** * ControlNet slice persist denylist */ -export const controlAdaptersPersistDenylist: (keyof ControlAdaptersState)[] = [ - 'pendingControlImages', -]; +export const controlAdaptersPersistDenylist: (keyof ControlAdaptersState)[] = ['pendingControlImages']; diff --git a/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersSlice.ts b/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersSlice.ts index 5e856a01eb..fd9a70ef57 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersSlice.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/store/controlAdaptersSlice.ts @@ -28,20 +28,12 @@ import type { ResizeMode, T2IAdapterConfig, } from './types'; -import { - isControlNet, - isControlNetOrT2IAdapter, - isIPAdapter, - isT2IAdapter, -} from './types'; +import { isControlNet, isControlNetOrT2IAdapter, isIPAdapter, isT2IAdapter } from './types'; export const caAdapter = createEntityAdapter({ selectId: (ca) => ca.id, }); -export const caAdapterSelectors = caAdapter.getSelectors( - undefined, - getSelectorsOptions -); +export const caAdapterSelectors = caAdapter.getSelectors(undefined, getSelectorsOptions); export const { selectById: selectControlAdapterById, @@ -51,14 +43,13 @@ export const { selectTotal: selectControlAdapterTotal, } = caAdapterSelectors; -export const initialControlAdaptersState: ControlAdaptersState = - caAdapter.getInitialState<{ - _version: 1; - pendingControlImages: string[]; - }>({ - _version: 1, - pendingControlImages: [], - }); +export const initialControlAdaptersState: ControlAdaptersState = caAdapter.getInitialState<{ + _version: 1; + pendingControlImages: string[]; +}>({ + _version: 1, + pendingControlImages: [], +}); export const selectAllControlNets = (controlAdapters: ControlAdaptersState) => selectControlAdapterAll(controlAdapters).filter(isControlNet); @@ -70,8 +61,7 @@ export const selectValidControlNets = (controlAdapters: ControlAdaptersState) => (ca) => ca.isEnabled && ca.model && - (Boolean(ca.processedControlImage) || - (ca.processorType === 'none' && Boolean(ca.controlImage))) + (Boolean(ca.processedControlImage) || (ca.processorType === 'none' && Boolean(ca.controlImage))) ); export const selectAllIPAdapters = (controlAdapters: ControlAdaptersState) => @@ -92,8 +82,7 @@ export const selectValidT2IAdapters = (controlAdapters: ControlAdaptersState) => (ca) => ca.isEnabled && ca.model && - (Boolean(ca.processedControlImage) || - (ca.processorType === 'none' && Boolean(ca.controlImage))) + (Boolean(ca.processedControlImage) || (ca.processorType === 'none' && Boolean(ca.controlImage))) ); export const controlAdaptersSlice = createSlice({ @@ -112,20 +101,11 @@ export const controlAdaptersSlice = createSlice({ const { id, type, overrides } = action.payload; caAdapter.addOne(state, buildControlAdapter(id, type, overrides)); }, - prepare: ({ - type, - overrides, - }: { - type: ControlAdapterType; - overrides?: Partial; - }) => { + prepare: ({ type, overrides }: { type: ControlAdapterType; overrides?: Partial }) => { return { payload: { id: uuidv4(), type, overrides } }; }, }, - controlAdapterRecalled: ( - state, - action: PayloadAction - ) => { + controlAdapterRecalled: (state, action: PayloadAction) => { caAdapter.addOne(state, action.payload); }, controlAdapterDuplicated: { @@ -161,25 +141,16 @@ export const controlAdaptersSlice = createSlice({ }> ) => { const { id, type, controlImage } = action.payload; - caAdapter.addOne( - state, - buildControlAdapter(id, type, { controlImage }) - ); + caAdapter.addOne(state, buildControlAdapter(id, type, { controlImage })); }, - prepare: (payload: { - type: ControlAdapterType; - controlImage: string; - }) => { + prepare: (payload: { type: ControlAdapterType; controlImage: string }) => { return { payload: { ...payload, id: uuidv4() } }; }, }, controlAdapterRemoved: (state, action: PayloadAction<{ id: string }>) => { caAdapter.removeOne(state, action.payload.id); }, - controlAdapterIsEnabledChanged: ( - state, - action: PayloadAction<{ id: string; isEnabled: boolean }> - ) => { + controlAdapterIsEnabledChanged: (state, action: PayloadAction<{ id: string; isEnabled: boolean }>) => { const { id, isEnabled } = action.payload; caAdapter.updateOne(state, { id, changes: { isEnabled } }); }, @@ -201,11 +172,7 @@ export const controlAdaptersSlice = createSlice({ changes: { controlImage, processedControlImage: null }, }); - if ( - controlImage !== null && - isControlNetOrT2IAdapter(ca) && - ca.processorType !== 'none' - ) { + if (controlImage !== null && isControlNetOrT2IAdapter(ca) && ca.processorType !== 'none') { state.pendingControlImages.push(id); } }, @@ -233,14 +200,9 @@ export const controlAdaptersSlice = createSlice({ }, }); - state.pendingControlImages = state.pendingControlImages.filter( - (pendingId) => pendingId !== id - ); + state.pendingControlImages = state.pendingControlImages.filter((pendingId) => pendingId !== id); }, - controlAdapterModelCleared: ( - state, - action: PayloadAction<{ id: string }> - ) => { + controlAdapterModelCleared: (state, action: PayloadAction<{ id: string }>) => { caAdapter.updateOne(state, { id: action.payload.id, changes: { model: null }, @@ -250,10 +212,7 @@ export const controlAdaptersSlice = createSlice({ state, action: PayloadAction<{ id: string; - model: - | ParameterControlNetModel - | ParameterT2IAdapterModel - | ParameterIPAdapterModel; + model: ParameterControlNetModel | ParameterT2IAdapterModel | ParameterIPAdapterModel; }> ) => { const { id, model } = action.payload; @@ -278,8 +237,7 @@ export const controlAdaptersSlice = createSlice({ for (const modelSubstring in CONTROLADAPTER_MODEL_DEFAULT_PROCESSORS) { if (model.model_name.includes(modelSubstring)) { - processorType = - CONTROLADAPTER_MODEL_DEFAULT_PROCESSORS[modelSubstring]; + processorType = CONTROLADAPTER_MODEL_DEFAULT_PROCESSORS[modelSubstring]; break; } } @@ -290,37 +248,24 @@ export const controlAdaptersSlice = createSlice({ .default as RequiredControlAdapterProcessorNode; } else { update.changes.processorType = 'none'; - update.changes.processorNode = CONTROLNET_PROCESSORS.none - .default as RequiredControlAdapterProcessorNode; + update.changes.processorNode = CONTROLNET_PROCESSORS.none.default as RequiredControlAdapterProcessorNode; } caAdapter.updateOne(state, update); }, - controlAdapterWeightChanged: ( - state, - action: PayloadAction<{ id: string; weight: number }> - ) => { + controlAdapterWeightChanged: (state, action: PayloadAction<{ id: string; weight: number }>) => { const { id, weight } = action.payload; caAdapter.updateOne(state, { id, changes: { weight } }); }, - controlAdapterBeginStepPctChanged: ( - state, - action: PayloadAction<{ id: string; beginStepPct: number }> - ) => { + controlAdapterBeginStepPctChanged: (state, action: PayloadAction<{ id: string; beginStepPct: number }>) => { const { id, beginStepPct } = action.payload; caAdapter.updateOne(state, { id, changes: { beginStepPct } }); }, - controlAdapterEndStepPctChanged: ( - state, - action: PayloadAction<{ id: string; endStepPct: number }> - ) => { + controlAdapterEndStepPctChanged: (state, action: PayloadAction<{ id: string; endStepPct: number }>) => { const { id, endStepPct } = action.payload; caAdapter.updateOne(state, { id, changes: { endStepPct } }); }, - controlAdapterControlModeChanged: ( - state, - action: PayloadAction<{ id: string; controlMode: ControlMode }> - ) => { + controlAdapterControlModeChanged: (state, action: PayloadAction<{ id: string; controlMode: ControlMode }>) => { const { id, controlMode } = action.payload; const cn = selectControlAdapterById(state, id); if (!cn || !isControlNet(cn)) { @@ -415,8 +360,7 @@ export const controlAdaptersSlice = createSlice({ for (const modelSubstring in CONTROLADAPTER_MODEL_DEFAULT_PROCESSORS) { if (cn.model?.model_name.includes(modelSubstring)) { - processorType = - CONTROLADAPTER_MODEL_DEFAULT_PROCESSORS[modelSubstring]; + processorType = CONTROLADAPTER_MODEL_DEFAULT_PROCESSORS[modelSubstring]; break; } } @@ -427,8 +371,7 @@ export const controlAdaptersSlice = createSlice({ .default as RequiredControlAdapterProcessorNode; } else { update.changes.processorType = 'none'; - update.changes.processorNode = CONTROLNET_PROCESSORS.none - .default as RequiredControlAdapterProcessorNode; + update.changes.processorNode = CONTROLNET_PROCESSORS.none.default as RequiredControlAdapterProcessorNode; } } @@ -448,9 +391,7 @@ export const controlAdaptersSlice = createSlice({ return; } if (cn.controlImage !== null) { - state.pendingControlImages = uniq( - state.pendingControlImages.concat(action.payload.id) - ); + state.pendingControlImages = uniq(state.pendingControlImages.concat(action.payload.id)); } }); @@ -491,8 +432,7 @@ export const isAnyControlAdapterAdded = isAnyOf( controlAdapterRecalled ); -export const selectControlAdaptersSlice = (state: RootState) => - state.controlAdapters; +export const selectControlAdaptersSlice = (state: RootState) => state.controlAdapters; /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ export const migrateControlAdaptersState = (state: any): any => { diff --git a/invokeai/frontend/web/src/features/controlAdapters/store/types.ts b/invokeai/frontend/web/src/features/controlAdapters/store/types.ts index 87366a443d..86aff63155 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/store/types.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/store/types.ts @@ -47,9 +47,7 @@ export type ControlAdapterProcessorNode = /** * Any ControlNet processor type */ -export type ControlAdapterProcessorType = NonNullable< - ControlAdapterProcessorNode['type'] | 'none' ->; +export type ControlAdapterProcessorType = NonNullable; /** * The Canny processor node, with parameters flagged as required @@ -85,9 +83,8 @@ export type RequiredDepthAnythingImageProcessorInvocation = O.Required< export const zDepthAnythingModelSize = z.enum(['large', 'base', 'small']); export type DepthAnythingModelSize = z.infer; -export const isDepthAnythingModelSize = ( - v: unknown -): v is DepthAnythingModelSize => zDepthAnythingModelSize.safeParse(v).success; +export const isDepthAnythingModelSize = (v: unknown): v is DepthAnythingModelSize => + zDepthAnythingModelSize.safeParse(v).success; /** * The HED processor node, with parameters flagged as required @@ -164,10 +161,7 @@ export type RequiredPidiImageProcessorInvocation = O.Required< /** * The ZoeDepth processor node, with parameters flagged as required */ -export type RequiredZoeDepthImageProcessorInvocation = O.Required< - ZoeDepthImageProcessorInvocation, - 'type' ->; +export type RequiredZoeDepthImageProcessorInvocation = O.Required; /** * Any ControlNet Processor node, with its parameters flagged as required @@ -195,9 +189,7 @@ export type RequiredControlAdapterProcessorNode = /** * Type guard for CannyImageProcessorInvocation */ -export const isCannyImageProcessorInvocation = ( - obj: unknown -): obj is CannyImageProcessorInvocation => { +export const isCannyImageProcessorInvocation = (obj: unknown): obj is CannyImageProcessorInvocation => { if (isObject(obj) && 'type' in obj && obj.type === 'canny_image_processor') { return true; } @@ -207,14 +199,8 @@ export const isCannyImageProcessorInvocation = ( /** * Type guard for ColorMapImageProcessorInvocation */ -export const isColorMapImageProcessorInvocation = ( - obj: unknown -): obj is ColorMapImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'color_map_image_processor' - ) { +export const isColorMapImageProcessorInvocation = (obj: unknown): obj is ColorMapImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'color_map_image_processor') { return true; } return false; @@ -226,11 +212,7 @@ export const isColorMapImageProcessorInvocation = ( export const isContentShuffleImageProcessorInvocation = ( obj: unknown ): obj is ContentShuffleImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'content_shuffle_image_processor' - ) { + if (isObject(obj) && 'type' in obj && obj.type === 'content_shuffle_image_processor') { return true; } return false; @@ -239,14 +221,8 @@ export const isContentShuffleImageProcessorInvocation = ( /** * Type guard for DepthAnythingImageProcessorInvocation */ -export const isDepthAnythingImageProcessorInvocation = ( - obj: unknown -): obj is DepthAnythingImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'depth_anything_image_processor' - ) { +export const isDepthAnythingImageProcessorInvocation = (obj: unknown): obj is DepthAnythingImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'depth_anything_image_processor') { return true; } return false; @@ -255,9 +231,7 @@ export const isDepthAnythingImageProcessorInvocation = ( /** * Type guard for HedImageprocessorInvocation */ -export const isHedImageprocessorInvocation = ( - obj: unknown -): obj is HedImageProcessorInvocation => { +export const isHedImageprocessorInvocation = (obj: unknown): obj is HedImageProcessorInvocation => { if (isObject(obj) && 'type' in obj && obj.type === 'hed_image_processor') { return true; } @@ -267,14 +241,8 @@ export const isHedImageprocessorInvocation = ( /** * Type guard for LineartAnimeImageProcessorInvocation */ -export const isLineartAnimeImageProcessorInvocation = ( - obj: unknown -): obj is LineartAnimeImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'lineart_anime_image_processor' - ) { +export const isLineartAnimeImageProcessorInvocation = (obj: unknown): obj is LineartAnimeImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'lineart_anime_image_processor') { return true; } return false; @@ -283,14 +251,8 @@ export const isLineartAnimeImageProcessorInvocation = ( /** * Type guard for LineartImageProcessorInvocation */ -export const isLineartImageProcessorInvocation = ( - obj: unknown -): obj is LineartImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'lineart_image_processor' - ) { +export const isLineartImageProcessorInvocation = (obj: unknown): obj is LineartImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'lineart_image_processor') { return true; } return false; @@ -299,14 +261,8 @@ export const isLineartImageProcessorInvocation = ( /** * Type guard for MediapipeFaceProcessorInvocation */ -export const isMediapipeFaceProcessorInvocation = ( - obj: unknown -): obj is MediapipeFaceProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'mediapipe_face_processor' - ) { +export const isMediapipeFaceProcessorInvocation = (obj: unknown): obj is MediapipeFaceProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'mediapipe_face_processor') { return true; } return false; @@ -315,14 +271,8 @@ export const isMediapipeFaceProcessorInvocation = ( /** * Type guard for MidasDepthImageProcessorInvocation */ -export const isMidasDepthImageProcessorInvocation = ( - obj: unknown -): obj is MidasDepthImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'midas_depth_image_processor' - ) { +export const isMidasDepthImageProcessorInvocation = (obj: unknown): obj is MidasDepthImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'midas_depth_image_processor') { return true; } return false; @@ -331,9 +281,7 @@ export const isMidasDepthImageProcessorInvocation = ( /** * Type guard for MlsdImageProcessorInvocation */ -export const isMlsdImageProcessorInvocation = ( - obj: unknown -): obj is MlsdImageProcessorInvocation => { +export const isMlsdImageProcessorInvocation = (obj: unknown): obj is MlsdImageProcessorInvocation => { if (isObject(obj) && 'type' in obj && obj.type === 'mlsd_image_processor') { return true; } @@ -343,14 +291,8 @@ export const isMlsdImageProcessorInvocation = ( /** * Type guard for NormalbaeImageProcessorInvocation */ -export const isNormalbaeImageProcessorInvocation = ( - obj: unknown -): obj is NormalbaeImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'normalbae_image_processor' - ) { +export const isNormalbaeImageProcessorInvocation = (obj: unknown): obj is NormalbaeImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'normalbae_image_processor') { return true; } return false; @@ -359,14 +301,8 @@ export const isNormalbaeImageProcessorInvocation = ( /** * Type guard for OpenposeImageProcessorInvocation */ -export const isOpenposeImageProcessorInvocation = ( - obj: unknown -): obj is OpenposeImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'openpose_image_processor' - ) { +export const isOpenposeImageProcessorInvocation = (obj: unknown): obj is OpenposeImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'openpose_image_processor') { return true; } return false; @@ -375,9 +311,7 @@ export const isOpenposeImageProcessorInvocation = ( /** * Type guard for PidiImageProcessorInvocation */ -export const isPidiImageProcessorInvocation = ( - obj: unknown -): obj is PidiImageProcessorInvocation => { +export const isPidiImageProcessorInvocation = (obj: unknown): obj is PidiImageProcessorInvocation => { if (isObject(obj) && 'type' in obj && obj.type === 'pidi_image_processor') { return true; } @@ -387,32 +321,18 @@ export const isPidiImageProcessorInvocation = ( /** * Type guard for ZoeDepthImageProcessorInvocation */ -export const isZoeDepthImageProcessorInvocation = ( - obj: unknown -): obj is ZoeDepthImageProcessorInvocation => { - if ( - isObject(obj) && - 'type' in obj && - obj.type === 'zoe_depth_image_processor' - ) { +export const isZoeDepthImageProcessorInvocation = (obj: unknown): obj is ZoeDepthImageProcessorInvocation => { + if (isObject(obj) && 'type' in obj && obj.type === 'zoe_depth_image_processor') { return true; } return false; }; -export type ControlMode = NonNullable< - components['schemas']['ControlNetInvocation']['control_mode'] ->; +export type ControlMode = NonNullable; -export const zResizeMode = z.enum([ - 'just_resize', - 'crop_resize', - 'fill_resize', - 'just_resize_simple', -]); +export const zResizeMode = z.enum(['just_resize', 'crop_resize', 'fill_resize', 'just_resize_simple']); export type ResizeMode = z.infer; -export const isResizeMode = (v: unknown): v is ResizeMode => - zResizeMode.safeParse(v).success; +export const isResizeMode = (v: unknown): v is ResizeMode => zResizeMode.safeParse(v).success; export type ControlNetConfig = { type: 'controlnet'; @@ -458,10 +378,7 @@ export type IPAdapterConfig = { endStepPct: number; }; -export type ControlAdapterConfig = - | ControlNetConfig - | IPAdapterConfig - | T2IAdapterConfig; +export type ControlAdapterConfig = ControlNetConfig | IPAdapterConfig | T2IAdapterConfig; export type ControlAdapterType = ControlAdapterConfig['type']; @@ -469,21 +386,15 @@ export type ControlAdaptersState = EntityState & { pendingControlImages: string[]; }; -export const isControlNet = ( - controlAdapter: ControlAdapterConfig -): controlAdapter is ControlNetConfig => { +export const isControlNet = (controlAdapter: ControlAdapterConfig): controlAdapter is ControlNetConfig => { return controlAdapter.type === 'controlnet'; }; -export const isIPAdapter = ( - controlAdapter: ControlAdapterConfig -): controlAdapter is IPAdapterConfig => { +export const isIPAdapter = (controlAdapter: ControlAdapterConfig): controlAdapter is IPAdapterConfig => { return controlAdapter.type === 'ip_adapter'; }; -export const isT2IAdapter = ( - controlAdapter: ControlAdapterConfig -): controlAdapter is T2IAdapterConfig => { +export const isT2IAdapter = (controlAdapter: ControlAdapterConfig): controlAdapter is T2IAdapterConfig => { return controlAdapter.type === 't2i_adapter'; }; diff --git a/invokeai/frontend/web/src/features/controlAdapters/util/buildControlAdapter.ts b/invokeai/frontend/web/src/features/controlAdapters/util/buildControlAdapter.ts index fb8a019570..34803b3de3 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/util/buildControlAdapter.ts +++ b/invokeai/frontend/web/src/features/controlAdapters/util/buildControlAdapter.ts @@ -21,8 +21,7 @@ export const initialControlNet: Omit = { controlImage: null, processedControlImage: null, processorType: 'canny_image_processor', - processorNode: CONTROLNET_PROCESSORS.canny_image_processor - .default as RequiredCannyImageProcessorInvocation, + processorNode: CONTROLNET_PROCESSORS.canny_image_processor.default as RequiredCannyImageProcessorInvocation, shouldAutoConfig: true, }; @@ -37,8 +36,7 @@ export const initialT2IAdapter: Omit = { controlImage: null, processedControlImage: null, processorType: 'canny_image_processor', - processorNode: CONTROLNET_PROCESSORS.canny_image_processor - .default as RequiredCannyImageProcessorInvocation, + processorNode: CONTROLNET_PROCESSORS.canny_image_processor.default as RequiredCannyImageProcessorInvocation, shouldAutoConfig: true, }; diff --git a/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageButton.tsx b/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageButton.tsx index e312553daf..9d46a185f8 100644 --- a/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageButton.tsx +++ b/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageButton.tsx @@ -1,5 +1,5 @@ -import type { IconButtonProps } from '@invoke-ai/ui'; -import { IconButton } from '@invoke-ai/ui'; +import type { IconButtonProps } from '@invoke-ai/ui-library'; +import { IconButton } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageModal.tsx b/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageModal.tsx index b59d810bd1..5783fe4ffc 100644 --- a/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageModal.tsx +++ b/invokeai/frontend/web/src/features/deleteImageModal/components/DeleteImageModal.tsx @@ -1,21 +1,10 @@ -import { - ConfirmationAlertDialog, - Divider, - Flex, - FormControl, - FormLabel, - Switch, - Text, -} from '@invoke-ai/ui'; +import { ConfirmationAlertDialog, Divider, Flex, FormControl, FormLabel, Switch, Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { selectCanvasSlice } from 'features/canvas/store/canvasSlice'; import { selectControlAdaptersSlice } from 'features/controlAdapters/store/controlAdaptersSlice'; import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions'; -import { - getImageUsage, - selectImageUsage, -} from 'features/deleteImageModal/store/selectors'; +import { getImageUsage, selectImageUsage } from 'features/deleteImageModal/store/selectors'; import { imageDeletionCanceled, isModalOpenChanged, @@ -41,14 +30,7 @@ const selectImageUsages = createMemoizedSelector( selectControlAdaptersSlice, selectImageUsage, ], - ( - deleteImageModal, - generation, - canvas, - nodes, - controlAdapters, - imagesUsage - ) => { + (deleteImageModal, generation, canvas, nodes, controlAdapters, imagesUsage) => { const { imagesToDelete } = deleteImageModal; const allImageUsage = (imagesToDelete ?? []).map(({ image_name }) => @@ -73,19 +55,13 @@ const selectImageUsages = createMemoizedSelector( const DeleteImageModal = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); - const shouldConfirmOnDelete = useAppSelector( - (s) => s.system.shouldConfirmOnDelete - ); - const canRestoreDeletedImagesFromBin = useAppSelector( - (s) => s.config.canRestoreDeletedImagesFromBin - ); + const shouldConfirmOnDelete = useAppSelector((s) => s.system.shouldConfirmOnDelete); + const canRestoreDeletedImagesFromBin = useAppSelector((s) => s.config.canRestoreDeletedImagesFromBin); const isModalOpen = useAppSelector((s) => s.deleteImageModal.isModalOpen); - const { imagesToDelete, imagesUsage, imageUsageSummary } = - useAppSelector(selectImageUsages); + const { imagesToDelete, imagesUsage, imageUsageSummary } = useAppSelector(selectImageUsages); const handleChangeShouldConfirmOnDelete = useCallback( - (e: ChangeEvent) => - dispatch(setShouldConfirmOnDelete(!e.target.checked)), + (e: ChangeEvent) => dispatch(setShouldConfirmOnDelete(!e.target.checked)), [dispatch] ); @@ -99,9 +75,7 @@ const DeleteImageModal = () => { return; } dispatch(imageDeletionCanceled()); - dispatch( - imageDeletionConfirmed({ imageDTOs: imagesToDelete, imagesUsage }) - ); + dispatch(imageDeletionConfirmed({ imageDTOs: imagesToDelete, imagesUsage })); }, [dispatch, imagesToDelete, imagesUsage]); return ( @@ -116,18 +90,11 @@ const DeleteImageModal = () => { - - {canRestoreDeletedImagesFromBin - ? t('gallery.deleteImageBin') - : t('gallery.deleteImagePermanent')} - + {canRestoreDeletedImagesFromBin ? t('gallery.deleteImageBin') : t('gallery.deleteImagePermanent')} {t('common.areYouSure')} {t('common.dontAskMeAgain')} - + diff --git a/invokeai/frontend/web/src/features/deleteImageModal/components/ImageUsageMessage.tsx b/invokeai/frontend/web/src/features/deleteImageModal/components/ImageUsageMessage.tsx index 2e5c4efe24..5a6856f346 100644 --- a/invokeai/frontend/web/src/features/deleteImageModal/components/ImageUsageMessage.tsx +++ b/invokeai/frontend/web/src/features/deleteImageModal/components/ImageUsageMessage.tsx @@ -1,4 +1,4 @@ -import { ListItem, Text, UnorderedList } from '@invoke-ai/ui'; +import { ListItem, Text, UnorderedList } from '@invoke-ai/ui-library'; import type { ImageUsage } from 'features/deleteImageModal/store/types'; import { some } from 'lodash-es'; import { memo } from 'react'; @@ -29,18 +29,10 @@ const ImageUsageMessage = (props: Props) => { <> {topMessage} - {imageUsage.isInitialImage && ( - {t('common.img2img')} - )} - {imageUsage.isCanvasImage && ( - {t('common.unifiedCanvas')} - )} - {imageUsage.isControlImage && ( - {t('common.controlNet')} - )} - {imageUsage.isNodesImage && ( - {t('common.nodeEditor')} - )} + {imageUsage.isInitialImage && {t('common.img2img')}} + {imageUsage.isCanvasImage && {t('common.unifiedCanvas')}} + {imageUsage.isControlImage && {t('common.controlNet')}} + {imageUsage.isNodesImage && {t('common.nodeEditor')}} {bottomMessage} diff --git a/invokeai/frontend/web/src/features/deleteImageModal/store/selectors.ts b/invokeai/frontend/web/src/features/deleteImageModal/store/selectors.ts index 24192647fc..f54f9a0dbb 100644 --- a/invokeai/frontend/web/src/features/deleteImageModal/store/selectors.ts +++ b/invokeai/frontend/web/src/features/deleteImageModal/store/selectors.ts @@ -27,23 +27,17 @@ export const getImageUsage = ( ) => { const isInitialImage = generation.initialImage?.imageName === image_name; - const isCanvasImage = canvas.layerState.objects.some( - (obj) => obj.kind === 'image' && obj.imageName === image_name - ); + const isCanvasImage = canvas.layerState.objects.some((obj) => obj.kind === 'image' && obj.imageName === image_name); const isNodesImage = nodes.nodes.filter(isInvocationNode).some((node) => { return some( node.data.inputs, - (input) => - isImageFieldInputInstance(input) && - input.value?.image_name === image_name + (input) => isImageFieldInputInstance(input) && input.value?.image_name === image_name ); }); const isControlImage = selectControlAdapterAll(controlAdapters).some( - (ca) => - ca.controlImage === image_name || - (isControlNetOrT2IAdapter(ca) && ca.processedControlImage === image_name) + (ca) => ca.controlImage === image_name || (isControlNetOrT2IAdapter(ca) && ca.processedControlImage === image_name) ); const imageUsage: ImageUsage = { diff --git a/invokeai/frontend/web/src/features/deleteImageModal/store/slice.ts b/invokeai/frontend/web/src/features/deleteImageModal/store/slice.ts index 03d1901d99..268602c350 100644 --- a/invokeai/frontend/web/src/features/deleteImageModal/store/slice.ts +++ b/invokeai/frontend/web/src/features/deleteImageModal/store/slice.ts @@ -22,13 +22,8 @@ const deleteImageModal = createSlice({ }, }); -export const { - isModalOpenChanged, - imagesToDeleteSelected, - imageDeletionCanceled, -} = deleteImageModal.actions; +export const { isModalOpenChanged, imagesToDeleteSelected, imageDeletionCanceled } = deleteImageModal.actions; export default deleteImageModal.reducer; -export const selectDeleteImageModalSlice = (state: RootState) => - state.deleteImageModal; +export const selectDeleteImageModalSlice = (state: RootState) => state.deleteImageModal; diff --git a/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx b/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx index 0fe069f68a..f800e5c869 100644 --- a/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx +++ b/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx @@ -4,11 +4,7 @@ import { dndDropped } from 'app/store/middleware/listenerMiddleware/listeners/im import { useAppDispatch } from 'app/store/storeHooks'; import { parseify } from 'common/util/serialize'; import DndOverlay from 'features/dnd/components/DndOverlay'; -import type { - DragEndEvent, - DragStartEvent, - TypesafeDraggableData, -} from 'features/dnd/types'; +import type { DragEndEvent, DragStartEvent, TypesafeDraggableData } from 'features/dnd/types'; import { customPointerWithin } from 'features/dnd/util/customPointerWithin'; import type { PropsWithChildren } from 'react'; import { memo, useCallback, useState } from 'react'; @@ -16,18 +12,14 @@ import { memo, useCallback, useState } from 'react'; import { DndContextTypesafe } from './DndContextTypesafe'; const AppDndContext = (props: PropsWithChildren) => { - const [activeDragData, setActiveDragData] = - useState(null); + const [activeDragData, setActiveDragData] = useState(null); const log = logger('images'); const dispatch = useAppDispatch(); const handleDragStart = useCallback( (event: DragStartEvent) => { - log.trace( - { dragData: parseify(event.active.data.current) }, - 'Drag started' - ); + log.trace({ dragData: parseify(event.active.data.current) }, 'Drag started'); const activeData = event.active.data.current; if (!activeData) { return; @@ -39,10 +31,7 @@ const AppDndContext = (props: PropsWithChildren) => { const handleDragEnd = useCallback( (event: DragEndEvent) => { - log.trace( - { dragData: parseify(event.active.data.current) }, - 'Drag ended' - ); + log.trace({ dragData: parseify(event.active.data.current) }, 'Drag ended'); const overData = event.over?.data.current; if (!activeDragData || !overData) { return; diff --git a/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx b/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx index 263ebf928c..34067c9b46 100644 --- a/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx +++ b/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx @@ -17,19 +17,10 @@ const DndOverlay = (props: DndOverlayProps) => { const modifiers = useMemo(() => [scaledModifier], [scaledModifier]); return ( - + {props.activeDragData && ( - + )} diff --git a/invokeai/frontend/web/src/features/dnd/components/DragPreview.tsx b/invokeai/frontend/web/src/features/dnd/components/DragPreview.tsx index f52f7945e0..9c4b715953 100644 --- a/invokeai/frontend/web/src/features/dnd/components/DragPreview.tsx +++ b/invokeai/frontend/web/src/features/dnd/components/DragPreview.tsx @@ -1,5 +1,5 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { Box, Flex, Heading, Image, Text } from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Box, Flex, Heading, Image, Text } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import type { TypesafeDraggableData } from 'features/dnd/types'; import { memo } from 'react'; @@ -61,21 +61,8 @@ const DragPreview = (props: OverlayDragImageProps) => { if (props.dragData.payloadType === 'IMAGE_DTO') { const { thumbnail_url, width, height } = props.dragData.payload.imageDTO; return ( - - + + ); } diff --git a/invokeai/frontend/web/src/features/dnd/hooks/useScaledCenteredModifer.ts b/invokeai/frontend/web/src/features/dnd/hooks/useScaledCenteredModifer.ts index e2ef6ab75c..2816fc4830 100644 --- a/invokeai/frontend/web/src/features/dnd/hooks/useScaledCenteredModifer.ts +++ b/invokeai/frontend/web/src/features/dnd/hooks/useScaledCenteredModifer.ts @@ -6,10 +6,8 @@ import { selectNodesSlice } from 'features/nodes/store/nodesSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { useCallback } from 'react'; -const selectZoom = createSelector( - [selectNodesSlice, activeTabNameSelector], - (nodes, activeTabName) => - activeTabName === 'nodes' ? nodes.viewport.zoom : 1 +const selectZoom = createSelector([selectNodesSlice, activeTabNameSelector], (nodes, activeTabName) => + activeTabName === 'nodes' ? nodes.viewport.zoom : 1 ); /** diff --git a/invokeai/frontend/web/src/features/dnd/types/index.ts b/invokeai/frontend/web/src/features/dnd/types/index.ts index ac62eb65cd..6e680b4ba9 100644 --- a/invokeai/frontend/web/src/features/dnd/types/index.ts +++ b/invokeai/frontend/web/src/features/dnd/types/index.ts @@ -11,10 +11,7 @@ import type { UseDroppableArguments, } from '@dnd-kit/core'; import type { BoardId } from 'features/gallery/store/types'; -import type { - FieldInputInstance, - FieldInputTemplate, -} from 'features/nodes/types/field'; +import type { FieldInputInstance, FieldInputTemplate } from 'features/nodes/types/field'; import type { ImageDTO } from 'services/api/types'; type BaseDropData = { @@ -93,33 +90,22 @@ export type GallerySelectionDraggableData = BaseDragData & { payload: { boardId: BoardId }; }; -export type TypesafeDraggableData = - | NodeFieldDraggableData - | ImageDraggableData - | GallerySelectionDraggableData; +export type TypesafeDraggableData = NodeFieldDraggableData | ImageDraggableData | GallerySelectionDraggableData; -export interface UseDroppableTypesafeArguments - extends Omit { +export interface UseDroppableTypesafeArguments extends Omit { data?: TypesafeDroppableData; } -export type UseDroppableTypesafeReturnValue = Omit< - ReturnType, - 'active' | 'over' -> & { +export type UseDroppableTypesafeReturnValue = Omit, 'active' | 'over'> & { active: TypesafeActive | null; over: TypesafeOver | null; }; -export interface UseDraggableTypesafeArguments - extends Omit { +export interface UseDraggableTypesafeArguments extends Omit { data?: TypesafeDraggableData; } -export type UseDraggableTypesafeReturnValue = Omit< - ReturnType, - 'active' | 'over' -> & { +export type UseDraggableTypesafeReturnValue = Omit, 'active' | 'over'> & { active: TypesafeActive | null; over: TypesafeOver | null; }; @@ -147,10 +133,7 @@ export interface DragEndEvent extends DragEvent {} export interface DragCancelEvent extends DragEndEvent {} export interface DndContextTypesafeProps - extends Omit< - DndContextProps, - 'onDragStart' | 'onDragMove' | 'onDragOver' | 'onDragEnd' | 'onDragCancel' - > { + extends Omit { onDragStart?(event: DragStartEvent): void; onDragMove?(event: DragMoveEvent): void; onDragOver?(event: DragOverEvent): void; diff --git a/invokeai/frontend/web/src/features/dnd/util/customPointerWithin.ts b/invokeai/frontend/web/src/features/dnd/util/customPointerWithin.ts index f3d08a75ca..5de1248324 100644 --- a/invokeai/frontend/web/src/features/dnd/util/customPointerWithin.ts +++ b/invokeai/frontend/web/src/features/dnd/util/customPointerWithin.ts @@ -16,20 +16,15 @@ export const customPointerWithin: CollisionDetection = (arg) => { // Get all elements at the pointer coordinates. This excludes elements which are overflowed, // so it won't include the droppable elements that are scrolled out of view. - const targetElements = document.elementsFromPoint( - arg.pointerCoordinates.x, - arg.pointerCoordinates.y - ); + const targetElements = document.elementsFromPoint(arg.pointerCoordinates.x, arg.pointerCoordinates.y); - const filteredDroppableContainers = arg.droppableContainers.filter( - (container) => { - if (!container.node.current) { - return false; - } - // Only include droppable elements that are in the list of elements at the pointer coordinates. - return targetElements.includes(container.node.current); + const filteredDroppableContainers = arg.droppableContainers.filter((container) => { + if (!container.node.current) { + return false; } - ); + // Only include droppable elements that are in the list of elements at the pointer coordinates. + return targetElements.includes(container.node.current); + }); // Run the provided collision detection with the filtered droppable elements. return pointerWithin({ diff --git a/invokeai/frontend/web/src/features/dnd/util/isValidDrop.ts b/invokeai/frontend/web/src/features/dnd/util/isValidDrop.ts index c691a1deba..c2c9de3f0c 100644 --- a/invokeai/frontend/web/src/features/dnd/util/isValidDrop.ts +++ b/invokeai/frontend/web/src/features/dnd/util/isValidDrop.ts @@ -1,9 +1,6 @@ import type { TypesafeActive, TypesafeDroppableData } from 'features/dnd/types'; -export const isValidDrop = ( - overData: TypesafeDroppableData | undefined, - active: TypesafeActive | null -) => { +export const isValidDrop = (overData: TypesafeDroppableData | undefined, active: TypesafeActive | null) => { if (!overData || !active?.data.current) { return false; } @@ -30,9 +27,7 @@ export const isValidDrop = ( // If the board is the same, don't allow the drop // Check the payload types - const isPayloadValid = ['IMAGE_DTO', 'GALLERY_SELECTION'].includes( - payloadType - ); + const isPayloadValid = ['IMAGE_DTO', 'GALLERY_SELECTION'].includes(payloadType); if (!isPayloadValid) { return false; } @@ -59,9 +54,7 @@ export const isValidDrop = ( // If the board is the same, don't allow the drop // Check the payload types - const isPayloadValid = ['IMAGE_DTO', 'GALLERY_SELECTION'].includes( - payloadType - ); + const isPayloadValid = ['IMAGE_DTO', 'GALLERY_SELECTION'].includes(payloadType); if (!isPayloadValid) { return false; } diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/DynamicPromptsPreviewModal.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/DynamicPromptsPreviewModal.tsx index 1783ccf9d1..620bda597f 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/DynamicPromptsPreviewModal.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/DynamicPromptsPreviewModal.tsx @@ -6,7 +6,7 @@ import { ModalContent, ModalHeader, ModalOverlay, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsCombinatorial.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsCombinatorial.tsx index 1a772d8245..64901ddb86 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsCombinatorial.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsCombinatorial.tsx @@ -1,4 +1,4 @@ -import { FormControl, FormLabel, Switch } from '@invoke-ai/ui'; +import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { combinatorialToggled } from 'features/dynamicPrompts/store/dynamicPromptsSlice'; import { memo, useCallback } from 'react'; diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx index cd0daaf22a..eb533db74f 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; import { maxPromptsChanged } from 'features/dynamicPrompts/store/dynamicPromptsSlice'; @@ -12,21 +7,11 @@ import { useTranslation } from 'react-i18next'; const ParamDynamicPromptsMaxPrompts = () => { const maxPrompts = useAppSelector((s) => s.dynamicPrompts.maxPrompts); - const sliderMin = useAppSelector( - (s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMin - ); - const sliderMax = useAppSelector( - (s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMax - ); - const numberInputMin = useAppSelector( - (s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMin - ); - const numberInputMax = useAppSelector( - (s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMax - ); - const initial = useAppSelector( - (s) => s.config.sd.dynamicPrompts.maxPrompts.initial - ); + const sliderMin = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMax); + const numberInputMin = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMin); + const numberInputMax = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMax); + const initial = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.initial); const isDisabled = useAppSelector((s) => !s.dynamicPrompts.combinatorial); const dispatch = useAppDispatch(); const { t } = useTranslation(); diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsPreview.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsPreview.tsx index 48cfd9a8d4..e714533a30 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsPreview.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsPreview.tsx @@ -1,13 +1,5 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { - Flex, - FormControl, - FormLabel, - ListItem, - OrderedList, - Spinner, - Text, -} from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Flex, FormControl, FormLabel, ListItem, OrderedList, Spinner, Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import { IAINoContentFallback } from 'common/components/IAIImageFallback'; @@ -18,10 +10,7 @@ import { memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { PiWarningCircleBold } from 'react-icons/pi'; -const selectPrompts = createMemoizedSelector( - selectDynamicPromptsSlice, - (dynamicPrompts) => dynamicPrompts.prompts -); +const selectPrompts = createMemoizedSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.prompts); const listItemStyles: ChakraProps['sx'] = { '&::marker': { color: 'base.500' }, @@ -44,48 +33,22 @@ const ParamDynamicPromptsPreview = () => { if (isError) { return ( - - + + ); } return ( - + {label} - + {prompts.map((prompt, i) => ( - + {prompt} ))} diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsSeedBehaviour.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsSeedBehaviour.tsx index 87a860ac89..d04faf0d10 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsSeedBehaviour.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsSeedBehaviour.tsx @@ -1,11 +1,8 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; -import { - isSeedBehaviour, - seedBehaviourChanged, -} from 'features/dynamicPrompts/store/dynamicPromptsSlice'; +import { isSeedBehaviour, seedBehaviourChanged } from 'features/dynamicPrompts/store/dynamicPromptsSlice'; import { memo, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -39,17 +36,11 @@ const ParamDynamicPromptsSeedBehaviour = () => { [dispatch] ); - const value = useMemo( - () => options.find((o) => o.value === seedBehaviour), - [options, seedBehaviour] - ); + const value = useMemo(() => options.find((o) => o.value === seedBehaviour), [options, seedBehaviour]); return ( - + {t('dynamicPrompts.seedBehaviour.label')} diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton.tsx index b590767868..3be6bfa747 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton.tsx @@ -1,5 +1,5 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { IconButton, spinAnimation, Tooltip } from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { IconButton, spinAnimation, Tooltip } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal'; import { memo } from 'react'; @@ -13,19 +13,11 @@ const loadingStyles: SystemStyleObject = { export const ShowDynamicPromptsPreviewButton = memo(() => { const { t } = useTranslation(); const isLoading = useAppSelector((s) => s.dynamicPrompts.isLoading); - const isError = useAppSelector((s) => - Boolean(s.dynamicPrompts.isError || s.dynamicPrompts.parsingError) - ); + const isError = useAppSelector((s) => Boolean(s.dynamicPrompts.isError || s.dynamicPrompts.parsingError)); const { isOpen, onOpen } = useDynamicPromptsModal(); return ( - + ; -export const isSeedBehaviour = (v: unknown): v is SeedBehaviour => - zSeedBehaviour.safeParse(v).success; +export const isSeedBehaviour = (v: unknown): v is SeedBehaviour => zSeedBehaviour.safeParse(v).success; export interface DynamicPromptsState { _version: 1; @@ -49,10 +48,7 @@ export const dynamicPromptsSlice = createSlice({ state.prompts = action.payload; state.isLoading = false; }, - parsingErrorChanged: ( - state, - action: PayloadAction - ) => { + parsingErrorChanged: (state, action: PayloadAction) => { state.parsingError = action.payload; }, isErrorChanged: (state, action: PayloadAction) => { @@ -80,8 +76,7 @@ export const { export default dynamicPromptsSlice.reducer; -export const selectDynamicPromptsSlice = (state: RootState) => - state.dynamicPrompts; +export const selectDynamicPromptsSlice = (state: RootState) => state.dynamicPrompts; /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ export const migrateDynamicPromptsState = (state: any): any => { diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/util/getShouldProcessPrompt.ts b/invokeai/frontend/web/src/features/dynamicPrompts/util/getShouldProcessPrompt.ts index 1d2a5e715e..416363fec1 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/util/getShouldProcessPrompt.ts +++ b/invokeai/frontend/web/src/features/dynamicPrompts/util/getShouldProcessPrompt.ts @@ -1,3 +1,2 @@ const hasOpenCloseCurlyBracesRegex = /.*\{[\s\S]*\}.*/; -export const getShouldProcessPrompt = (prompt: string): boolean => - hasOpenCloseCurlyBracesRegex.test(prompt); +export const getShouldProcessPrompt = (prompt: string): boolean => hasOpenCloseCurlyBracesRegex.test(prompt); diff --git a/invokeai/frontend/web/src/features/embedding/AddEmbeddingButton.tsx b/invokeai/frontend/web/src/features/embedding/AddEmbeddingButton.tsx index c1207a13b0..d32d6006ae 100644 --- a/invokeai/frontend/web/src/features/embedding/AddEmbeddingButton.tsx +++ b/invokeai/frontend/web/src/features/embedding/AddEmbeddingButton.tsx @@ -1,4 +1,4 @@ -import { IconButton, Tooltip } from '@invoke-ai/ui'; +import { IconButton, Tooltip } from '@invoke-ai/ui-library'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { PiCodeBold } from 'react-icons/pi'; diff --git a/invokeai/frontend/web/src/features/embedding/EmbeddingPopover.tsx b/invokeai/frontend/web/src/features/embedding/EmbeddingPopover.tsx index bd39c1012a..1ff18dc107 100644 --- a/invokeai/frontend/web/src/features/embedding/EmbeddingPopover.tsx +++ b/invokeai/frontend/web/src/features/embedding/EmbeddingPopover.tsx @@ -1,9 +1,4 @@ -import { - Popover, - PopoverAnchor, - PopoverBody, - PopoverContent, -} from '@invoke-ai/ui'; +import { Popover, PopoverAnchor, PopoverBody, PopoverContent } from '@invoke-ai/ui-library'; import { EmbeddingSelect } from 'features/embedding/EmbeddingSelect'; import type { EmbeddingPopoverProps } from 'features/embedding/types'; import { memo } from 'react'; diff --git a/invokeai/frontend/web/src/features/embedding/EmbeddingSelect.tsx b/invokeai/frontend/web/src/features/embedding/EmbeddingSelect.tsx index 2a263894ff..ffe9d63360 100644 --- a/invokeai/frontend/web/src/features/embedding/EmbeddingSelect.tsx +++ b/invokeai/frontend/web/src/features/embedding/EmbeddingSelect.tsx @@ -1,5 +1,5 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { Combobox, FormControl } from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Combobox, FormControl } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { useGroupedModelCombobox } from 'common/hooks/useGroupedModelCombobox'; import type { EmbeddingSelectProps } from 'features/embedding/types'; @@ -11,60 +11,54 @@ import { useGetTextualInversionModelsQuery } from 'services/api/endpoints/models const noOptionsMessage = () => t('embedding.noMatchingEmbedding'); -export const EmbeddingSelect = memo( - ({ onSelect, onClose }: EmbeddingSelectProps) => { - const { t } = useTranslation(); +export const EmbeddingSelect = memo(({ onSelect, onClose }: EmbeddingSelectProps) => { + const { t } = useTranslation(); - const currentBaseModel = useAppSelector( - (s) => s.generation.model?.base_model - ); + const currentBaseModel = useAppSelector((s) => s.generation.model?.base_model); - const getIsDisabled = useCallback( - (embedding: TextualInversionModelConfigEntity): boolean => { - const isCompatible = currentBaseModel === embedding.base_model; - const hasMainModel = Boolean(currentBaseModel); - return !hasMainModel || !isCompatible; - }, - [currentBaseModel] - ); - const { data, isLoading } = useGetTextualInversionModelsQuery(); + const getIsDisabled = useCallback( + (embedding: TextualInversionModelConfigEntity): boolean => { + const isCompatible = currentBaseModel === embedding.base_model; + const hasMainModel = Boolean(currentBaseModel); + return !hasMainModel || !isCompatible; + }, + [currentBaseModel] + ); + const { data, isLoading } = useGetTextualInversionModelsQuery(); - const _onChange = useCallback( - (embedding: TextualInversionModelConfigEntity | null) => { - if (!embedding) { - return; - } - onSelect(embedding.model_name); - }, - [onSelect] - ); + const _onChange = useCallback( + (embedding: TextualInversionModelConfigEntity | null) => { + if (!embedding) { + return; + } + onSelect(embedding.model_name); + }, + [onSelect] + ); - const { options, onChange } = useGroupedModelCombobox({ - modelEntities: data, - getIsDisabled, - onChange: _onChange, - }); + const { options, onChange } = useGroupedModelCombobox({ + modelEntities: data, + getIsDisabled, + onChange: _onChange, + }); - return ( - - - - ); - } -); + return ( + + + + ); +}); EmbeddingSelect.displayName = 'EmbeddingSelect'; diff --git a/invokeai/frontend/web/src/features/embedding/usePrompt.ts b/invokeai/frontend/web/src/features/embedding/usePrompt.ts index 4c5878df6f..c3a708e6ce 100644 --- a/invokeai/frontend/web/src/features/embedding/usePrompt.ts +++ b/invokeai/frontend/web/src/features/embedding/usePrompt.ts @@ -1,10 +1,6 @@ -import { useDisclosure } from '@invoke-ai/ui'; +import { useDisclosure } from '@invoke-ai/ui-library'; import { isNil } from 'lodash-es'; -import type { - ChangeEventHandler, - KeyboardEventHandler, - RefObject, -} from 'react'; +import type { ChangeEventHandler, KeyboardEventHandler, RefObject } from 'react'; import { useCallback } from 'react'; import { flushSync } from 'react-dom'; @@ -14,11 +10,7 @@ export type UseInsertEmbeddingArg = { onChange: (v: string) => void; }; -export const usePrompt = ({ - prompt, - textareaRef, - onChange: _onChange, -}: UseInsertEmbeddingArg) => { +export const usePrompt = ({ prompt, textareaRef, onChange: _onChange }: UseInsertEmbeddingArg) => { const { isOpen, onClose, onOpen } = useDisclosure(); const onChange: ChangeEventHandler = useCallback( diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx index edb15344c4..6541b66151 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/AutoAddIcon.tsx @@ -1,4 +1,4 @@ -import { Badge, Flex } from '@invoke-ai/ui'; +import { Badge, Flex } from '@invoke-ai/ui-library'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx index 0286dd350d..da05209d9d 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx @@ -1,5 +1,5 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice'; import { memo, useCallback, useMemo } from 'react'; @@ -10,9 +10,7 @@ const BoardAutoAddSelect = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId); - const autoAssignBoardOnClick = useAppSelector( - (s) => s.gallery.autoAssignBoardOnClick - ); + const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick); const { options, hasBoards } = useListAllBoardsQuery(undefined, { selectFromResult: ({ data }) => { const options: ComboboxOption[] = [ @@ -43,10 +41,7 @@ const BoardAutoAddSelect = () => { [dispatch] ); - const value = useMemo( - () => options.find((o) => o.value === autoAddBoardId), - [options, autoAddBoardId] - ); + const value = useMemo(() => options.find((o) => o.value === autoAddBoardId), [options, autoAddBoardId]); const noOptionsMessage = useCallback(() => t('boards.noMatching'), [t]); diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx index 09c4e94709..490e8eac9e 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx @@ -1,11 +1,8 @@ -import type { ContextMenuProps } from '@invoke-ai/ui'; -import { ContextMenu, MenuGroup, MenuItem, MenuList } from '@invoke-ai/ui'; +import type { ContextMenuProps } from '@invoke-ai/ui-library'; +import { ContextMenu, MenuGroup, MenuItem, MenuList } from '@invoke-ai/ui-library'; import { createSelector } from '@reduxjs/toolkit'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - autoAddBoardIdChanged, - selectGallerySlice, -} from 'features/gallery/store/gallerySlice'; +import { autoAddBoardIdChanged, selectGallerySlice } from 'features/gallery/store/gallerySlice'; import type { BoardId } from 'features/gallery/store/types'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { addToast } from 'features/system/store/systemSlice'; @@ -25,30 +22,18 @@ type Props = { setBoardToDelete?: (board?: BoardDTO) => void; }; -const BoardContextMenu = ({ - board, - board_id, - setBoardToDelete, - children, -}: Props) => { +const BoardContextMenu = ({ board, board_id, setBoardToDelete, children }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); - const autoAssignBoardOnClick = useAppSelector( - (s) => s.gallery.autoAssignBoardOnClick - ); + const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick); const selectIsSelectedForAutoAdd = useMemo( - () => - createSelector( - selectGallerySlice, - (gallery) => board && board.board_id === gallery.autoAddBoardId - ), + () => createSelector(selectGallerySlice, (gallery) => board && board.board_id === gallery.autoAddBoardId), [board] ); const isSelectedForAutoAdd = useAppSelector(selectIsSelectedForAutoAdd); const boardName = useBoardName(board_id); - const isBulkDownloadEnabled = - useFeatureStatus('bulkDownload').isFeatureEnabled; + const isBulkDownloadEnabled = useFeatureStatus('bulkDownload').isFeatureEnabled; const [bulkDownload] = useBulkDownloadImagesMutation(); @@ -98,19 +83,11 @@ const BoardContextMenu = ({ {t('boards.menuItemAutoAdd')} {isBulkDownloadEnabled && ( - } - onClickCapture={handleBulkDownload} - > + } onClickCapture={handleBulkDownload}> {t('boards.downloadBoard')} )} - {board && ( - - )} + {board && } ), diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/AddBoardButton.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/AddBoardButton.tsx index 5e7a4b0f99..5cd4d001f4 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/AddBoardButton.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/AddBoardButton.tsx @@ -1,4 +1,4 @@ -import { IconButton } from '@invoke-ai/ui'; +import { IconButton } from '@invoke-ai/ui-library'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiPlusBold } from 'react-icons/pi'; diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx index 4d62e5393c..7f95bcc973 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx @@ -1,4 +1,4 @@ -import { Collapse, Flex, Grid, GridItem } from '@invoke-ai/ui'; +import { Collapse, Flex, Grid, GridItem } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants'; import DeleteBoardModal from 'features/gallery/components/Boards/DeleteBoardModal'; @@ -28,32 +28,19 @@ const BoardsList = (props: Props) => { const boardSearchText = useAppSelector((s) => s.gallery.boardSearchText); const { data: boards } = useListAllBoardsQuery(); const filteredBoards = boardSearchText - ? boards?.filter((board) => - board.board_name.toLowerCase().includes(boardSearchText.toLowerCase()) - ) + ? boards?.filter((board) => board.board_name.toLowerCase().includes(boardSearchText.toLowerCase())) : boards; const [boardToDelete, setBoardToDelete] = useState(); return ( <> - + - + { {filteredBoards && filteredBoards.map((board, index) => ( - + { - + ); }; diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsSearch.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsSearch.tsx index 99d5367dd2..931c1e6cbb 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsSearch.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsSearch.tsx @@ -1,9 +1,4 @@ -import { - IconButton, - Input, - InputGroup, - InputRightElement, -} from '@invoke-ai/ui'; +import { IconButton, Input, InputGroup, InputRightElement } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { boardSearchTextChanged } from 'features/gallery/store/gallerySlice'; import type { ChangeEvent, KeyboardEvent } from 'react'; diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx index ca6eac89e4..8e3c7e4ab2 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx @@ -1,15 +1,5 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { - Box, - Editable, - EditableInput, - EditablePreview, - Flex, - Icon, - Image, - Text, - Tooltip, -} from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Box, Editable, EditableInput, EditablePreview, Flex, Icon, Image, Text, Tooltip } from '@invoke-ai/ui-library'; import { createSelector } from '@reduxjs/toolkit'; import { skipToken } from '@reduxjs/toolkit/query'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; @@ -18,11 +8,7 @@ import SelectionOverlay from 'common/components/SelectionOverlay'; import type { AddToBoardDropData } from 'features/dnd/types'; import AutoAddIcon from 'features/gallery/components/Boards/AutoAddIcon'; import BoardContextMenu from 'features/gallery/components/Boards/BoardContextMenu'; -import { - autoAddBoardIdChanged, - boardIdSelected, - selectGallerySlice, -} from 'features/gallery/store/gallerySlice'; +import { autoAddBoardIdChanged, boardIdSelected, selectGallerySlice } from 'features/gallery/store/gallerySlice'; import { memo, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { PiImagesSquare } from 'react-icons/pi'; @@ -48,21 +34,11 @@ interface GalleryBoardProps { setBoardToDelete: (board?: BoardDTO) => void; } -const GalleryBoard = ({ - board, - isSelected, - setBoardToDelete, -}: GalleryBoardProps) => { +const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps) => { const dispatch = useAppDispatch(); - const autoAssignBoardOnClick = useAppSelector( - (s) => s.gallery.autoAssignBoardOnClick - ); + const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick); const selectIsSelectedForAutoAdd = useMemo( - () => - createSelector( - selectGallerySlice, - (gallery) => board.board_id === gallery.autoAddBoardId - ), + () => createSelector(selectGallerySlice, (gallery) => board.board_id === gallery.autoAddBoardId), [board.board_id] ); @@ -86,9 +62,7 @@ const GalleryBoard = ({ } asset${assetsTotal.total === 1 ? '' : 's'}`; }, [assetsTotal, imagesTotal]); - const { currentData: coverImage } = useGetImageDTOQuery( - board.cover_image_name ?? skipToken - ); + const { currentData: coverImage } = useGetImageDTOQuery(board.cover_image_name ?? skipToken); const { board_name, board_id } = board; const [localBoardName, setLocalBoardName] = useState(board_name); @@ -100,8 +74,7 @@ const GalleryBoard = ({ } }, [board_id, autoAssignBoardOnClick, dispatch]); - const [updateBoard, { isLoading: isUpdateBoardLoading }] = - useUpdateBoardMutation(); + const [updateBoard, { isLoading: isUpdateBoardLoading }] = useUpdateBoardMutation(); const droppableData: AddToBoardDropData = useMemo( () => ({ @@ -157,11 +130,7 @@ const GalleryBoard = ({ w="full" h="full" > - + {(ref) => ( ) : ( - - + + )} {isSelectedForAutoAdd && } - + - {t('unifiedCanvas.move')} - } - /> + {t('unifiedCanvas.move')}} /> )} diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx index c8e8e3bb53..2b022dc90a 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx @@ -1,21 +1,15 @@ -import { Box, Flex, Image, Text, Tooltip } from '@invoke-ai/ui'; +import { Box, Flex, Image, Text, Tooltip } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAIDroppable from 'common/components/IAIDroppable'; import SelectionOverlay from 'common/components/SelectionOverlay'; import type { RemoveFromBoardDropData } from 'features/dnd/types'; import AutoAddIcon from 'features/gallery/components/Boards/AutoAddIcon'; import BoardContextMenu from 'features/gallery/components/Boards/BoardContextMenu'; -import { - autoAddBoardIdChanged, - boardIdSelected, -} from 'features/gallery/store/gallerySlice'; +import { autoAddBoardIdChanged, boardIdSelected } from 'features/gallery/store/gallerySlice'; import InvokeLogoSVG from 'public/assets/images/invoke-symbol-wht-lrg.svg'; import { memo, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { - useGetBoardAssetsTotalQuery, - useGetBoardImagesTotalQuery, -} from 'services/api/endpoints/boards'; +import { useGetBoardAssetsTotalQuery, useGetBoardImagesTotalQuery } from 'services/api/endpoints/boards'; import { useBoardName } from 'services/api/hooks/useBoardName'; interface Props { @@ -25,9 +19,7 @@ interface Props { const NoBoardBoard = memo(({ isSelected }: Props) => { const dispatch = useAppDispatch(); const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId); - const autoAssignBoardOnClick = useAppSelector( - (s) => s.gallery.autoAssignBoardOnClick - ); + const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick); const boardName = useBoardName('none'); const handleSelectBoard = useCallback(() => { dispatch(boardIdSelected({ boardId: 'none' })); @@ -92,12 +84,7 @@ const NoBoardBoard = memo(({ isSelected }: Props) => { cursor="pointer" bg="base.800" > - + invoke-ai-logo { > {boardName} - - {t('unifiedCanvas.move')} - } - /> + + {t('unifiedCanvas.move')}} /> )} diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/DeleteBoardModal.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/DeleteBoardModal.tsx index 0f78177371..6581033aaa 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/DeleteBoardModal.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/DeleteBoardModal.tsx @@ -9,7 +9,7 @@ import { Flex, Skeleton, Text, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { skipToken } from '@reduxjs/toolkit/query'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; @@ -24,10 +24,7 @@ import { some } from 'lodash-es'; import { memo, useCallback, useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { useListAllImageNamesForBoardQuery } from 'services/api/endpoints/boards'; -import { - useDeleteBoardAndImagesMutation, - useDeleteBoardMutation, -} from 'services/api/endpoints/images'; +import { useDeleteBoardAndImagesMutation, useDeleteBoardMutation } from 'services/api/endpoints/images'; import type { BoardDTO } from 'services/api/types'; type Props = { @@ -38,21 +35,15 @@ type Props = { const DeleteBoardModal = (props: Props) => { const { boardToDelete, setBoardToDelete } = props; const { t } = useTranslation(); - const canRestoreDeletedImagesFromBin = useAppSelector( - (s) => s.config.canRestoreDeletedImagesFromBin + const canRestoreDeletedImagesFromBin = useAppSelector((s) => s.config.canRestoreDeletedImagesFromBin); + const { currentData: boardImageNames, isFetching: isFetchingBoardNames } = useListAllImageNamesForBoardQuery( + boardToDelete?.board_id ?? skipToken ); - const { currentData: boardImageNames, isFetching: isFetchingBoardNames } = - useListAllImageNamesForBoardQuery(boardToDelete?.board_id ?? skipToken); const selectImageUsageSummary = useMemo( () => createMemoizedSelector( - [ - selectGenerationSlice, - selectCanvasSlice, - selectNodesSlice, - selectControlAdaptersSlice, - ], + [selectGenerationSlice, selectCanvasSlice, selectNodesSlice, selectControlAdaptersSlice], (generation, canvas, nodes, controlAdapters) => { const allImageUsage = (boardImageNames ?? []).map((imageName) => getImageUsage(generation, canvas, nodes, controlAdapters, imageName) @@ -71,11 +62,9 @@ const DeleteBoardModal = (props: Props) => { [boardImageNames] ); - const [deleteBoardOnly, { isLoading: isDeleteBoardOnlyLoading }] = - useDeleteBoardMutation(); + const [deleteBoardOnly, { isLoading: isDeleteBoardOnlyLoading }] = useDeleteBoardMutation(); - const [deleteBoardAndImages, { isLoading: isDeleteBoardAndImagesLoading }] = - useDeleteBoardAndImagesMutation(); + const [deleteBoardAndImages, { isLoading: isDeleteBoardAndImagesLoading }] = useDeleteBoardAndImagesMutation(); const imageUsageSummary = useAppSelector(selectImageUsageSummary); @@ -102,15 +91,8 @@ const DeleteBoardModal = (props: Props) => { const cancelRef = useRef(null); const isLoading = useMemo( - () => - isDeleteBoardAndImagesLoading || - isDeleteBoardOnlyLoading || - isFetchingBoardNames, - [ - isDeleteBoardAndImagesLoading, - isDeleteBoardOnlyLoading, - isFetchingBoardNames, - ] + () => isDeleteBoardAndImagesLoading || isDeleteBoardOnlyLoading || isFetchingBoardNames, + [isDeleteBoardAndImagesLoading, isDeleteBoardOnlyLoading, isFetchingBoardNames] ); if (!boardToDelete) { @@ -118,12 +100,7 @@ const DeleteBoardModal = (props: Props) => { } return ( - + @@ -145,9 +122,7 @@ const DeleteBoardModal = (props: Props) => { )} {t('boards.deletedBoardsCannotbeRestored')} - {canRestoreDeletedImagesFromBin - ? t('gallery.deleteImageBin') - : t('gallery.deleteImagePermanent')} + {canRestoreDeletedImagesFromBin ? t('gallery.deleteImageBin') : t('gallery.deleteImagePermanent')} @@ -156,18 +131,10 @@ const DeleteBoardModal = (props: Props) => { - - diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx index 70e22a920c..d1280bf109 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx @@ -1,4 +1,4 @@ -import { MenuItem } from '@invoke-ai/ui'; +import { MenuItem } from '@invoke-ai/ui-library'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiTrashSimpleBold } from 'react-icons/pi'; @@ -20,11 +20,7 @@ const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { return ( <> - } - onClick={handleDelete} - > + } onClick={handleDelete}> {t('boards.deleteBoard')} diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx index d141371d3c..e25324b9ea 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx @@ -1,11 +1,4 @@ -import { - ButtonGroup, - Flex, - IconButton, - Menu, - MenuButton, - MenuList, -} from '@invoke-ai/ui'; +import { ButtonGroup, Flex, IconButton, Menu, MenuButton, MenuList } from '@invoke-ai/ui-library'; import { createSelector } from '@reduxjs/toolkit'; import { skipToken } from '@reduxjs/toolkit/query'; import { useAppToaster } from 'app/components/Toaster'; @@ -23,10 +16,7 @@ import { initialImageSelected } from 'features/parameters/store/actions'; import { useIsQueueMutationInProgress } from 'features/queue/hooks/useIsQueueMutationInProgress'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { selectSystemSlice } from 'features/system/store/systemSlice'; -import { - setShouldShowImageDetails, - setShouldShowProgressInViewer, -} from 'features/ui/store/uiSlice'; +import { setShouldShowImageDetails, setShouldShowProgressInViewer } from 'features/ui/store/uiSlice'; import { useGetAndLoadEmbeddedWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadEmbeddedWorkflow'; import { memo, useCallback } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; @@ -58,39 +48,23 @@ const selectShouldDisableToolbarButtons = createSelector( const CurrentImageButtons = () => { const dispatch = useAppDispatch(); const isConnected = useAppSelector((s) => s.system.isConnected); - const shouldShowImageDetails = useAppSelector( - (s) => s.ui.shouldShowImageDetails - ); - const shouldShowProgressInViewer = useAppSelector( - (s) => s.ui.shouldShowProgressInViewer - ); + const shouldShowImageDetails = useAppSelector((s) => s.ui.shouldShowImageDetails); + const shouldShowProgressInViewer = useAppSelector((s) => s.ui.shouldShowProgressInViewer); const lastSelectedImage = useAppSelector(selectLastSelectedImage); - const shouldDisableToolbarButtons = useAppSelector( - selectShouldDisableToolbarButtons - ); + const shouldDisableToolbarButtons = useAppSelector(selectShouldDisableToolbarButtons); const isUpscalingEnabled = useFeatureStatus('upscaling').isFeatureEnabled; const isQueueMutationInProgress = useIsQueueMutationInProgress(); const toaster = useAppToaster(); const { t } = useTranslation(); - const { - recallBothPrompts, - recallSeed, - recallWidthAndHeight, - recallAllParameters, - } = useRecallParameters(); + const { recallBothPrompts, recallSeed, recallWidthAndHeight, recallAllParameters } = useRecallParameters(); - const { currentData: imageDTO } = useGetImageDTOQuery( - lastSelectedImage?.image_name ?? skipToken - ); + const { currentData: imageDTO } = useGetImageDTOQuery(lastSelectedImage?.image_name ?? skipToken); - const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata( - lastSelectedImage?.image_name - ); + const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata(lastSelectedImage?.image_name); - const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = - useGetAndLoadEmbeddedWorkflow({}); + const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = useGetAndLoadEmbeddedWorkflow({}); const handleLoadWorkflow = useCallback(() => { if (!lastSelectedImage || !lastSelectedImage.has_workflow) { @@ -173,10 +147,7 @@ const CurrentImageButtons = () => { handleClickUpscale(); }, { - enabled: () => - Boolean( - isUpscalingEnabled && !shouldDisableToolbarButtons && isConnected - ), + enabled: () => Boolean(isUpscalingEnabled && !shouldDisableToolbarButtons && isConnected), }, [isUpscalingEnabled, imageDTO, shouldDisableToolbarButtons, isConnected] ); @@ -227,9 +198,7 @@ const CurrentImageButtons = () => { isDisabled={!imageDTO} icon={} /> - - {imageDTO && } - + {imageDTO && } diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageDisplay.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageDisplay.tsx index 5d7a3755c3..f4b707b859 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageDisplay.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageDisplay.tsx @@ -1,4 +1,4 @@ -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import { memo } from 'react'; import CurrentImageButtons from './CurrentImageButtons'; diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx index 1496562d5e..02863daa2f 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx @@ -1,13 +1,10 @@ -import { Box, Flex } from '@invoke-ai/ui'; +import { Box, Flex } from '@invoke-ai/ui-library'; import { createSelector } from '@reduxjs/toolkit'; import { skipToken } from '@reduxjs/toolkit/query'; import { useAppSelector } from 'app/store/storeHooks'; import IAIDndImage from 'common/components/IAIDndImage'; import { IAINoContentFallback } from 'common/components/IAIImageFallback'; -import type { - TypesafeDraggableData, - TypesafeDroppableData, -} from 'features/dnd/types'; +import type { TypesafeDraggableData, TypesafeDroppableData } from 'features/dnd/types'; import ProgressImage from 'features/gallery/components/CurrentImage/ProgressImage'; import ImageMetadataViewer from 'features/gallery/components/ImageMetadataViewer/ImageMetadataViewer'; import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons'; @@ -26,16 +23,10 @@ const selectLastSelectedImageName = createSelector( ); const CurrentImagePreview = () => { - const shouldShowImageDetails = useAppSelector( - (s) => s.ui.shouldShowImageDetails - ); + const shouldShowImageDetails = useAppSelector((s) => s.ui.shouldShowImageDetails); const imageName = useAppSelector(selectLastSelectedImageName); - const hasDenoiseProgress = useAppSelector((s) => - Boolean(s.system.denoiseProgress) - ); - const shouldShowProgressInViewer = useAppSelector( - (s) => s.ui.shouldShowProgressInViewer - ); + const hasDenoiseProgress = useAppSelector((s) => Boolean(s.system.denoiseProgress)); + const shouldShowProgressInViewer = useAppSelector((s) => s.ui.shouldShowProgressInViewer); const { currentData: imageDTO } = useGetImageDTOQuery(imageName ?? skipToken); @@ -58,8 +49,7 @@ const CurrentImagePreview = () => { ); // Show and hide the next/prev buttons on mouse move - const [shouldShowNextPrevButtons, setShouldShowNextPrevButtons] = - useState(false); + const [shouldShowNextPrevButtons, setShouldShowNextPrevButtons] = useState(false); const timeoutId = useRef(0); @@ -97,35 +87,18 @@ const CurrentImagePreview = () => { fitContainer useThumbailFallback dropLabel={t('gallery.setCurrentImage')} - noContentFallback={ - - } + noContentFallback={} dataTestId="image-preview" /> )} {shouldShowImageDetails && imageDTO && ( - + )} {!shouldShowImageDetails && imageDTO && shouldShowNextPrevButtons && ( - + )} diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/ProgressImage.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/ProgressImage.tsx index 6cb5ee05be..0ee75fbcd4 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/ProgressImage.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/ProgressImage.tsx @@ -1,15 +1,11 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { Image } from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Image } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { memo, useMemo } from 'react'; const CurrentImagePreview = () => { - const progress_image = useAppSelector( - (s) => s.system.denoiseProgress?.progress_image - ); - const shouldAntialiasProgressImage = useAppSelector( - (s) => s.system.shouldAntialiasProgressImage - ); + const progress_image = useAppSelector((s) => s.system.denoiseProgress?.progress_image); + const shouldAntialiasProgressImage = useAppSelector((s) => s.system.shouldAntialiasProgressImage); const sx = useMemo( () => ({ diff --git a/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx b/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx index 04a4ae8078..55aec17ab2 100644 --- a/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx @@ -1,4 +1,4 @@ -import { Button, Flex, Icon, Spacer } from '@invoke-ai/ui'; +import { Button, Flex, Icon, Spacer } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { memo, useMemo } from 'react'; import { PiCaretUpBold } from 'react-icons/pi'; diff --git a/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx b/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx index bc5720e9fc..a877ce0128 100644 --- a/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx @@ -1,4 +1,4 @@ -import type { FormLabelProps } from '@invoke-ai/ui'; +import type { FormLabelProps } from '@invoke-ai/ui-library'; import { Checkbox, CompositeSlider, @@ -12,7 +12,7 @@ import { PopoverContent, PopoverTrigger, Switch, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { autoAssignBoardOnClickChanged, @@ -33,13 +33,9 @@ const formLabelProps: FormLabelProps = { const GallerySettingsPopover = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); - const galleryImageMinimumWidth = useAppSelector( - (s) => s.gallery.galleryImageMinimumWidth - ); + const galleryImageMinimumWidth = useAppSelector((s) => s.gallery.galleryImageMinimumWidth); const shouldAutoSwitch = useAppSelector((s) => s.gallery.shouldAutoSwitch); - const autoAssignBoardOnClick = useAppSelector( - (s) => s.gallery.autoAssignBoardOnClick - ); + const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick); const handleChangeGalleryImageMinimumWidth = useCallback( (v: number) => { @@ -56,8 +52,7 @@ const GallerySettingsPopover = () => { ); const handleChangeAutoAssignBoardOnClick = useCallback( - (e: ChangeEvent) => - dispatch(autoAssignBoardOnClickChanged(e.target.checked)), + (e: ChangeEvent) => dispatch(autoAssignBoardOnClickChanged(e.target.checked)), [dispatch] ); @@ -87,17 +82,11 @@ const GallerySettingsPopover = () => { {t('gallery.autoSwitchNewImages')} - + {t('gallery.autoAssignBoardOnClick')} - + diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx index ada0d7bf61..632763e313 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx @@ -1,5 +1,5 @@ -import type { ContextMenuProps } from '@invoke-ai/ui'; -import { ContextMenu, MenuList } from '@invoke-ai/ui'; +import type { ContextMenuProps } from '@invoke-ai/ui-library'; +import { ContextMenu, MenuList } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { memo, useCallback } from 'react'; import type { ImageDTO } from 'services/api/types'; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/MultipleSelectionMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/MultipleSelectionMenuItems.tsx index bf30bd2565..e8f71c02f3 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/MultipleSelectionMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/MultipleSelectionMenuItems.tsx @@ -1,23 +1,14 @@ -import { MenuDivider, MenuItem } from '@invoke-ai/ui'; +import { MenuDivider, MenuItem } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { $customStarUI } from 'app/store/nanostores/customStarUI'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - imagesToChangeSelected, - isModalOpenChanged, -} from 'features/changeBoardModal/store/slice'; +import { imagesToChangeSelected, isModalOpenChanged } from 'features/changeBoardModal/store/slice'; import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { addToast } from 'features/system/store/systemSlice'; import { memo, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { - PiDownloadSimpleBold, - PiFoldersBold, - PiStarBold, - PiStarFill, - PiTrashSimpleBold, -} from 'react-icons/pi'; +import { PiDownloadSimpleBold, PiFoldersBold, PiStarBold, PiStarFill, PiTrashSimpleBold } from 'react-icons/pi'; import { useBulkDownloadImagesMutation, useStarImagesMutation, @@ -30,8 +21,7 @@ const MultipleSelectionMenuItems = () => { const selection = useAppSelector((s) => s.gallery.selection); const customStarUi = useStore($customStarUI); - const isBulkDownloadEnabled = - useFeatureStatus('bulkDownload').isFeatureEnabled; + const isBulkDownloadEnabled = useFeatureStatus('bulkDownload').isFeatureEnabled; const [starImages] = useStarImagesMutation(); const [unstarImages] = useUnstarImagesMutation(); @@ -94,26 +84,17 @@ const MultipleSelectionMenuItems = () => { return ( <> {areAllStarred && ( - } - onClickCapture={handleUnstarSelection} - > + } onClickCapture={handleUnstarSelection}> {customStarUi ? customStarUi.off.text : `Unstar All`} )} {(areAllUnstarred || (!areAllStarred && !areAllUnstarred)) && ( - } - onClickCapture={handleStarSelection} - > + } onClickCapture={handleStarSelection}> {customStarUi ? customStarUi.on.text : `Star All`} )} {isBulkDownloadEnabled && ( - } - onClickCapture={handleBulkDownload} - > + } onClickCapture={handleBulkDownload}> {t('gallery.downloadSelection')} )} @@ -121,11 +102,7 @@ const MultipleSelectionMenuItems = () => { {t('boards.changeBoard')} - } - onClickCapture={handleDeleteSelection} - > + } onClickCapture={handleDeleteSelection}> {t('gallery.deleteSelection')} diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx index 049c58e70b..4a9b9c6e8b 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx @@ -1,19 +1,13 @@ -import { Flex, MenuDivider, MenuItem, Spinner } from '@invoke-ai/ui'; +import { Flex, MenuDivider, MenuItem, Spinner } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { useAppToaster } from 'app/components/Toaster'; import { $customStarUI } from 'app/store/nanostores/customStarUI'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useCopyImageToClipboard } from 'common/hooks/useCopyImageToClipboard'; import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice'; -import { - imagesToChangeSelected, - isModalOpenChanged, -} from 'features/changeBoardModal/store/slice'; +import { imagesToChangeSelected, isModalOpenChanged } from 'features/changeBoardModal/store/slice'; import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice'; -import { - sentImageToCanvas, - sentImageToImg2Img, -} from 'features/gallery/store/actions'; +import { sentImageToCanvas, sentImageToImg2Img } from 'features/gallery/store/actions'; import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters'; import { initialImageSelected } from 'features/parameters/store/actions'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; @@ -37,10 +31,7 @@ import { PiStarFill, PiTrashSimpleBold, } from 'react-icons/pi'; -import { - useStarImagesMutation, - useUnstarImagesMutation, -} from 'services/api/endpoints/images'; +import { useStarImagesMutation, useUnstarImagesMutation } from 'services/api/endpoints/images'; import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata'; import type { ImageDTO } from 'services/api/types'; @@ -57,12 +48,9 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { const isCanvasEnabled = useFeatureStatus('unifiedCanvas').isFeatureEnabled; const customStarUi = useStore($customStarUI); - const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata( - imageDTO?.image_name - ); + const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata(imageDTO?.image_name); - const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = - useGetAndLoadEmbeddedWorkflow({}); + const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = useGetAndLoadEmbeddedWorkflow({}); const handleLoadWorkflow = useCallback(() => { getAndLoadEmbeddedWorkflow(imageDTO.image_name); @@ -71,8 +59,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { const [starImages] = useStarImagesMutation(); const [unstarImages] = useUnstarImagesMutation(); - const { isClipboardAPIAvailable, copyImageToClipboard } = - useCopyImageToClipboard(); + const { isClipboardAPIAvailable, copyImageToClipboard } = useCopyImageToClipboard(); const handleDelete = useCallback(() => { if (!imageDTO) { @@ -81,8 +68,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { dispatch(imagesToDeleteSelected([imageDTO])); }, [dispatch, imageDTO]); - const { recallBothPrompts, recallSeed, recallAllParameters } = - useRecallParameters(); + const { recallBothPrompts, recallSeed, recallAllParameters } = useRecallParameters(); // Recall parameters handlers const handleRecallPrompt = useCallback(() => { @@ -159,12 +145,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { return ( <> - } - > + }> {t('common.openInNewTab')} {isClipboardAPIAvailable && ( @@ -184,27 +165,17 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { - ) : ( - - ) - } + icon={getAndLoadEmbeddedWorkflowResult.isLoading ? : } onClickCapture={handleLoadWorkflow} isDisabled={!imageDTO.has_workflow} > {t('nodes.loadWorkflow')} : - } + icon={isLoadingMetadata ? : } onClickCapture={handleRemixImage} isDisabled={ - isLoadingMetadata || - (metadata?.positive_prompt === undefined && - metadata?.negative_prompt === undefined) + isLoadingMetadata || (metadata?.positive_prompt === undefined && metadata?.negative_prompt === undefined) } > {t('parameters.remixImage')} @@ -213,9 +184,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { icon={isLoadingMetadata ? : } onClickCapture={handleRecallPrompt} isDisabled={ - isLoadingMetadata || - (metadata?.positive_prompt === undefined && - metadata?.negative_prompt === undefined) + isLoadingMetadata || (metadata?.positive_prompt === undefined && metadata?.negative_prompt === undefined) } > {t('parameters.usePrompt')} @@ -235,19 +204,11 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { {t('parameters.useAll')} - } - onClickCapture={handleSendToImageToImage} - id="send-to-img2img" - > + } onClickCapture={handleSendToImageToImage} id="send-to-img2img"> {t('parameters.sendToImg2Img')} {isCanvasEnabled && ( - } - onClickCapture={handleSendToCanvas} - id="send-to-canvas" - > + } onClickCapture={handleSendToCanvas} id="send-to-canvas"> {t('parameters.sendToUnifiedCanvas')} )} @@ -256,26 +217,16 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { {t('boards.changeBoard')} {imageDTO.starred ? ( - } - onClickCapture={handleUnstarImage} - > + } onClickCapture={handleUnstarImage}> {customStarUi ? customStarUi.off.text : t('gallery.unstarImage')} ) : ( - } - onClickCapture={handleStarImage} - > + } onClickCapture={handleStarImage}> {customStarUi ? customStarUi.on.text : t('gallery.starImage')} )} - } - onClickCapture={handleDelete} - > + } onClickCapture={handleDelete}> {t('gallery.deleteImage')} diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx index aad3bfeecc..bd9afcd417 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx @@ -1,14 +1,4 @@ -import { - Box, - Button, - ButtonGroup, - Flex, - Tab, - TabList, - Tabs, - useDisclosure, - VStack, -} from '@invoke-ai/ui'; +import { Box, Button, ButtonGroup, Flex, Tab, TabList, Tabs, useDisclosure, VStack } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { $galleryHeader } from 'app/store/nanostores/galleryHeader'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; @@ -30,8 +20,7 @@ const ImageGalleryContent = () => { const galleryView = useAppSelector((s) => s.gallery.galleryView); const dispatch = useAppDispatch(); const galleryHeader = useStore($galleryHeader); - const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } = - useDisclosure({ defaultIsOpen: true }); + const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } = useDisclosure({ defaultIsOpen: true }); const handleClickImages = useCallback(() => { dispatch(galleryViewChanged('images')); @@ -42,26 +31,11 @@ const ImageGalleryContent = () => { }, [dispatch]); return ( - + {galleryHeader} - - + + @@ -70,12 +44,7 @@ const ImageGalleryContent = () => { - + { const shift = useShiftModifier(); const { t } = useTranslation(); const selectedBoardId = useAppSelector((s) => s.gallery.selectedBoardId); - const { handleClick, isSelected, areMultiplesSelected } = - useMultiselect(imageDTO); + const { handleClick, isSelected, areMultiplesSelected } = useMultiselect(imageDTO); const customStarUi = useStore($customStarUI); - const imageContainerRef = useScrollIntoView( - isSelected, - props.index, - areMultiplesSelected - ); + const imageContainerRef = useScrollIntoView(isSelected, props.index, areMultiplesSelected); const handleDelete = useCallback( (e: MouseEvent) => { @@ -127,22 +114,14 @@ const GalleryImage = (props: HoverableImageProps) => { return ''; }, [imageDTO?.starred, customStarUi]); - const dataTestId = useMemo( - () => getGalleryImageDataTestId(imageDTO?.image_name), - [imageDTO?.image_name] - ); + const dataTestId = useMemo(() => getGalleryImageDataTestId(imageDTO?.image_name), [imageDTO?.image_name]); if (!imageDTO) { return ; } return ( - + { onMouseOut={handleMouseOut} > <> - + {isHovered && shift && ( { const { t } = useTranslation(); const rootRef = useRef(null); const [scroller, setScroller] = useState(null); - const [initialize, osInstance] = useOverlayScrollbars( - overlayScrollbarsParams - ); + const [initialize, osInstance] = useOverlayScrollbars(overlayScrollbarsParams); const selectedBoardId = useAppSelector((s) => s.gallery.selectedBoardId); const { currentViewTotal } = useBoardTotal(selectedBoardId); const virtuosoRangeRef = useRef(null); @@ -49,13 +42,7 @@ const GalleryImageGrid = () => { } = useGalleryImages(); useGalleryHotkeys(); const itemContentFunc: ItemContent = useCallback( - (index, imageName) => ( - - ), + (index, imageName) => , [] ); @@ -95,10 +82,7 @@ const GalleryImageGrid = () => { if (isSuccess && currentData?.ids.length === 0) { return ( - + ); } @@ -135,10 +119,7 @@ const GalleryImageGrid = () => { if (isError) { return ( - + ); } diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridItemContainer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridItemContainer.tsx index 26247cc864..16e851c0eb 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridItemContainer.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridItemContainer.tsx @@ -1,5 +1,5 @@ -import type { FlexProps } from '@invoke-ai/ui'; -import { Box, forwardRef } from '@invoke-ai/ui'; +import type { FlexProps } from '@invoke-ai/ui-library'; +import { Box, forwardRef } from '@invoke-ai/ui-library'; import type { PropsWithChildren } from 'react'; import { memo } from 'react'; @@ -7,12 +7,7 @@ export const imageItemContainerTestId = 'image-item-container'; type ItemContainerProps = PropsWithChildren & FlexProps; const ItemContainer = forwardRef((props: ItemContainerProps, ref) => ( - + {props.children} )); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridListContainer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridListContainer.tsx index 58d074712f..1dbf7d95a6 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridListContainer.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/ImageGridListContainer.tsx @@ -1,5 +1,5 @@ -import type { FlexProps } from '@invoke-ai/ui'; -import { forwardRef, Grid } from '@invoke-ai/ui'; +import type { FlexProps } from '@invoke-ai/ui-library'; +import { forwardRef, Grid } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import type { PropsWithChildren } from 'react'; import { memo } from 'react'; @@ -8,9 +8,7 @@ export const imageListContainerTestId = 'image-list-container'; type ListContainerProps = PropsWithChildren & FlexProps; const ListContainer = forwardRef((props: ListContainerProps, ref) => { - const galleryImageMinimumWidth = useAppSelector( - (s) => s.gallery.galleryImageMinimumWidth - ); + const galleryImageMinimumWidth = useAppSelector((s) => s.gallery.galleryImageMinimumWidth); return ( - `gallery-image-${imageName}`; +export const getGalleryImageDataTestId = (imageName?: string) => `gallery-image-${imageName}`; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/DataViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/DataViewer.tsx index 394b6cbda9..8f6cef2c20 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/DataViewer.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/DataViewer.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, IconButton, Tooltip } from '@invoke-ai/ui'; +import { Box, Flex, IconButton, Tooltip } from '@invoke-ai/ui-library'; import { getOverlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants'; import { isString } from 'lodash-es'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; @@ -15,17 +15,11 @@ type Props = { withCopy?: boolean; }; -const overlayscrollbarsOptions = getOverlayScrollbarsParams( - 'scroll', - 'scroll' -).options; +const overlayscrollbarsOptions = getOverlayScrollbarsParams('scroll', 'scroll').options; const DataViewer = (props: Props) => { const { label, data, fileName, withDownload = true, withCopy = true } = props; - const dataString = useMemo( - () => (isString(data) ? data : JSON.stringify(data, null, 2)), - [data] - ); + const dataString = useMemo(() => (isString(data) ? data : JSON.stringify(data, null, 2)), [data]); const handleCopy = useCallback(() => { navigator.clipboard.writeText(dataString); @@ -44,29 +38,9 @@ const DataViewer = (props: Props) => { const { t } = useTranslation(); return ( - - - + + +
{dataString}
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx index 3cf0d5db10..e9a1461186 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx @@ -147,25 +147,19 @@ const ImageMetadataActions = (props: Props) => { const validControlNets: ControlNetMetadataItem[] = useMemo(() => { return metadata?.controlnets - ? metadata.controlnets.filter((controlnet) => - isParameterControlNetModel(controlnet.control_model) - ) + ? metadata.controlnets.filter((controlnet) => isParameterControlNetModel(controlnet.control_model)) : []; }, [metadata?.controlnets]); const validIPAdapters: IPAdapterMetadataItem[] = useMemo(() => { return metadata?.ipAdapters - ? metadata.ipAdapters.filter((ipAdapter) => - isParameterControlNetModel(ipAdapter.ip_adapter_model) - ) + ? metadata.ipAdapters.filter((ipAdapter) => isParameterControlNetModel(ipAdapter.ip_adapter_model)) : []; }, [metadata?.ipAdapters]); const validT2IAdapters: T2IAdapterMetadataItem[] = useMemo(() => { return metadata?.t2iAdapters - ? metadata.t2iAdapters.filter((t2iAdapter) => - isParameterT2IAdapterModel(t2iAdapter.t2i_adapter_model) - ) + ? metadata.t2iAdapters.filter((t2iAdapter) => isParameterT2IAdapterModel(t2iAdapter.t2i_adapter_model)) : []; }, [metadata?.t2iAdapters]); @@ -175,17 +169,9 @@ const ImageMetadataActions = (props: Props) => { return ( <> - {metadata.created_by && ( - - )} + {metadata.created_by && } {metadata.generation_mode && ( - + )} {metadata.positive_prompt && ( { /> )} {metadata.seed !== undefined && metadata.seed !== null && ( - + + )} + {metadata.model !== undefined && metadata.model !== null && metadata.model.model_name && ( + )} - {metadata.model !== undefined && - metadata.model !== null && - metadata.model.model_name && ( - - )} {metadata.width && ( - + )} {metadata.height && ( - + )} {metadata.scheduler && ( - + )} { onClick={handleRecallVaeModel} /> {metadata.steps && ( - + )} {metadata.cfg_scale !== undefined && metadata.cfg_scale !== null && ( + + )} + {metadata.cfg_rescale_multiplier !== undefined && metadata.cfg_rescale_multiplier !== null && ( )} - {metadata.cfg_rescale_multiplier !== undefined && - metadata.cfg_rescale_multiplier !== null && ( - - )} {metadata.strength && ( - + )} {metadata.hrf_enabled && ( { +const ImageMetadataItem = ({ label, value, onClick, isLink, labelPosition, withCopy = false }: MetadataItemProps) => { const { t } = useTranslation(); - const handleCopy = useCallback( - () => navigator.clipboard.writeText(value.toString()), - [value] - ); + const handleCopy = useCallback(() => navigator.clipboard.writeText(value.toString()), [value]); if (!value) { return null; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataViewer.tsx index 58c04e483b..6cb4f6ddd3 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataViewer.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataViewer.tsx @@ -1,12 +1,4 @@ -import { - ExternalLink, - Flex, - Tab, - TabList, - TabPanel, - TabPanels, - Tabs, -} from '@invoke-ai/ui'; +import { ExternalLink, Flex, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library'; import { IAINoContentFallback } from 'common/components/IAIImageFallback'; import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent'; import { memo } from 'react'; @@ -46,14 +38,7 @@ const ImageMetadataViewer = ({ image }: ImageMetadataViewerProps) => { > - + {t('metadata.recallParameters')} {t('metadata.metadata')} diff --git a/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx index 350ac9be1c..9949fb5bd5 100644 --- a/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx @@ -1,14 +1,10 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { Box, Flex, IconButton, Spinner } from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Box, Flex, IconButton, Spinner } from '@invoke-ai/ui-library'; import { useGalleryImages } from 'features/gallery/hooks/useGalleryImages'; import { useGalleryNavigation } from 'features/gallery/hooks/useGalleryNavigation'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; -import { - PiCaretDoubleRightBold, - PiCaretLeftBold, - PiCaretRightBold, -} from 'react-icons/pi'; +import { PiCaretDoubleRightBold, PiCaretLeftBold, PiCaretRightBold } from 'react-icons/pi'; const nextPrevButtonStyles: ChakraProps['sx'] = { color: 'base.100', @@ -18,8 +14,7 @@ const nextPrevButtonStyles: ChakraProps['sx'] = { const NextPrevImageButtons = () => { const { t } = useTranslation(); - const { handleLeftImage, handleRightImage, isOnFirstImage, isOnLastImage } = - useGalleryNavigation(); + const { handleLeftImage, handleRightImage, isOnFirstImage, isOnLastImage } = useGalleryNavigation(); const { areMoreImagesAvailable, @@ -29,12 +24,7 @@ const NextPrevImageButtons = () => { return ( - + {!isOnFirstImage && ( { /> )} - + {!isOnLastImage && ( { queryResult: { isFetching }, } = useGalleryImages(); - const { - handleLeftImage, - handleRightImage, - handleUpImage, - handleDownImage, - isOnLastImage, - areImagesBelowCurrent, - } = useGalleryNavigation(); + const { handleLeftImage, handleRightImage, handleUpImage, handleDownImage, isOnLastImage, areImagesBelowCurrent } = + useGalleryNavigation(); useHotkeys( 'left', @@ -40,13 +34,7 @@ export const useGalleryHotkeys = () => { handleRightImage(); } }, - [ - isOnLastImage, - areMoreImagesAvailable, - handleLoadMoreImages, - isFetching, - handleRightImage, - ] + [isOnLastImage, areMoreImagesAvailable, handleLoadMoreImages, isFetching, handleRightImage] ); useHotkeys( @@ -68,12 +56,6 @@ export const useGalleryHotkeys = () => { handleDownImage(); }, { preventDefault: true }, - [ - areImagesBelowCurrent, - areMoreImagesAvailable, - handleLoadMoreImages, - isFetching, - handleDownImage, - ] + [areImagesBelowCurrent, areMoreImagesAvailable, handleLoadMoreImages, isFetching, handleDownImage] ); }; diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useGalleryImages.ts b/invokeai/frontend/web/src/features/gallery/hooks/useGalleryImages.ts index 773fba9013..b3310d5e34 100644 --- a/invokeai/frontend/web/src/features/gallery/hooks/useGalleryImages.ts +++ b/invokeai/frontend/web/src/features/gallery/hooks/useGalleryImages.ts @@ -2,10 +2,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors'; import { moreImagesLoaded } from 'features/gallery/store/gallerySlice'; import { useCallback, useMemo } from 'react'; -import { - useGetBoardAssetsTotalQuery, - useGetBoardImagesTotalQuery, -} from 'services/api/endpoints/boards'; +import { useGetBoardAssetsTotalQuery, useGetBoardImagesTotalQuery } from 'services/api/endpoints/boards'; import { useListImagesQuery } from 'services/api/endpoints/images'; /** diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts b/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts index a0d6d208a4..b6fdb183e6 100644 --- a/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts +++ b/invokeai/frontend/web/src/features/gallery/hooks/useGalleryNavigation.ts @@ -29,14 +29,10 @@ import { imagesSelectors } from 'services/api/util'; */ const getImagesPerRow = (): number => { const widthOfGalleryImage = - document - .querySelector(`[data-testid="${imageItemContainerTestId}"]`) - ?.getBoundingClientRect().width ?? 1; + document.querySelector(`[data-testid="${imageItemContainerTestId}"]`)?.getBoundingClientRect().width ?? 1; const widthOfGalleryGrid = - document - .querySelector(`[data-testid="${imageListContainerTestId}"]`) - ?.getBoundingClientRect().width ?? 0; + document.querySelector(`[data-testid="${imageListContainerTestId}"]`)?.getBoundingClientRect().width ?? 0; const imagesPerRow = Math.round(widthOfGalleryGrid / widthOfGalleryImage); @@ -59,9 +55,7 @@ const scrollToImage = (imageName: string, index: number) => { return; } - const imageElement = document.querySelector( - `[data-testid="${getGalleryImageDataTestId(imageName)}"]` - ); + const imageElement = document.querySelector(`[data-testid="${getGalleryImageDataTestId(imageName)}"]`); const itemRect = imageElement?.getBoundingClientRect(); const rootRect = root.getBoundingClientRect(); if (!itemRect || !getIsVisible(itemRect, rootRect)) { @@ -90,9 +84,7 @@ const getUpImage = (images: ImageDTO[], currentIndex: number) => { const imagesPerRow = getImagesPerRow(); // If we are on the first row, we want to stay on the first row, not go to first image const isOnFirstRow = currentIndex < imagesPerRow; - const index = isOnFirstRow - ? currentIndex - : clamp(currentIndex - imagesPerRow, 0, images.length - 1); + const index = isOnFirstRow ? currentIndex : clamp(currentIndex - imagesPerRow, 0, images.length - 1); const image = images[index]; return { index, image }; }; @@ -101,9 +93,7 @@ const getDownImage = (images: ImageDTO[], currentIndex: number) => { const imagesPerRow = getImagesPerRow(); // If there are no images below the current image, we want to stay where we are const areImagesBelow = currentIndex < images.length - imagesPerRow; - const index = areImagesBelow - ? clamp(currentIndex + imagesPerRow, 0, images.length - 1) - : currentIndex; + const index = areImagesBelow ? clamp(currentIndex + imagesPerRow, 0, images.length - 1) : currentIndex; const image = images[index]; return { index, image }; }; @@ -137,17 +127,12 @@ export const useGalleryNavigation = (): UseGalleryNavigationReturn => { const { queryResult: { data }, } = useGalleryImages(); - const loadedImagesCount = useMemo( - () => data?.ids.length ?? 0, - [data?.ids.length] - ); + const loadedImagesCount = useMemo(() => data?.ids.length ?? 0, [data?.ids.length]); const lastSelectedImageIndex = useMemo(() => { if (!data || !lastSelectedImage) { return 0; } - return imagesSelectors - .selectAll(data) - .findIndex((i) => i.image_name === lastSelectedImage.image_name); + return imagesSelectors.selectAll(data).findIndex((i) => i.image_name === lastSelectedImage.image_name); }, [lastSelectedImage, data]); const handleNavigation = useCallback( @@ -155,10 +140,7 @@ export const useGalleryNavigation = (): UseGalleryNavigationReturn => { if (!data) { return; } - const { index, image } = getImageFuncs[direction]( - imagesSelectors.selectAll(data), - lastSelectedImageIndex - ); + const { index, image } = getImageFuncs[direction](imagesSelectors.selectAll(data), lastSelectedImageIndex); if (!image || index === lastSelectedImageIndex) { return; } @@ -168,10 +150,7 @@ export const useGalleryNavigation = (): UseGalleryNavigationReturn => { [dispatch, lastSelectedImageIndex, data] ); - const isOnFirstImage = useMemo( - () => lastSelectedImageIndex === 0, - [lastSelectedImageIndex] - ); + const isOnFirstImage = useMemo(() => lastSelectedImageIndex === 0, [lastSelectedImageIndex]); const isOnLastImage = useMemo( () => lastSelectedImageIndex === loadedImagesCount - 1, diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useMultiselect.ts b/invokeai/frontend/web/src/features/gallery/hooks/useMultiselect.ts index b32fec6e02..05e7d075e5 100644 --- a/invokeai/frontend/web/src/features/gallery/hooks/useMultiselect.ts +++ b/invokeai/frontend/web/src/features/gallery/hooks/useMultiselect.ts @@ -1,10 +1,7 @@ import { createSelector } from '@reduxjs/toolkit'; import { galleryImageClicked } from 'app/store/middleware/listenerMiddleware/listeners/galleryImageClicked'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - selectGallerySlice, - selectionChanged, -} from 'features/gallery/store/gallerySlice'; +import { selectGallerySlice, selectionChanged } from 'features/gallery/store/gallerySlice'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import type { MouseEvent } from 'react'; import { useCallback, useMemo } from 'react'; @@ -12,9 +9,7 @@ import type { ImageDTO } from 'services/api/types'; export const useMultiselect = (imageDTO?: ImageDTO) => { const dispatch = useAppDispatch(); - const areMultiplesSelected = useAppSelector( - (s) => s.gallery.selection.length > 1 - ); + const areMultiplesSelected = useAppSelector((s) => s.gallery.selection.length > 1); const selectIsSelected = useMemo( () => createSelector(selectGallerySlice, (gallery) => diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useScrollIntoView.ts b/invokeai/frontend/web/src/features/gallery/hooks/useScrollIntoView.ts index 01579cfe79..9947a4d78c 100644 --- a/invokeai/frontend/web/src/features/gallery/hooks/useScrollIntoView.ts +++ b/invokeai/frontend/web/src/features/gallery/hooks/useScrollIntoView.ts @@ -16,11 +16,7 @@ import { useEffect, useRef } from 'react'; * @param selectionCount The number of images selected. * @returns */ -export const useScrollIntoView = ( - isSelected: boolean, - index: number, - areMultiplesSelected: boolean -) => { +export const useScrollIntoView = (isSelected: boolean, index: number, areMultiplesSelected: boolean) => { const imageContainerRef = useRef(null); useEffect(() => { diff --git a/invokeai/frontend/web/src/features/gallery/store/actions.ts b/invokeai/frontend/web/src/features/gallery/store/actions.ts index 5b2891e147..4ebf4e021d 100644 --- a/invokeai/frontend/web/src/features/gallery/store/actions.ts +++ b/invokeai/frontend/web/src/features/gallery/store/actions.ts @@ -7,10 +7,9 @@ export type RequestedBoardImagesDeletionArg = { imagesUsage: ImageUsage; }; -export const requestedBoardImagesDeletion = - createAction( - 'gallery/requestedBoardImagesDeletion' - ); +export const requestedBoardImagesDeletion = createAction( + 'gallery/requestedBoardImagesDeletion' +); export const sentImageToCanvas = createAction('gallery/sentImageToCanvas'); diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySelectors.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySelectors.ts index ceea56b2da..1c64fc7809 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySelectors.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySelectors.ts @@ -1,9 +1,6 @@ import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { selectGallerySlice } from 'features/gallery/store/gallerySlice'; -import { - ASSETS_CATEGORIES, - IMAGE_CATEGORIES, -} from 'features/gallery/store/types'; +import { ASSETS_CATEGORIES, IMAGE_CATEGORIES } from 'features/gallery/store/types'; import type { ListImagesArgs } from 'services/api/types'; export const selectLastSelectedImage = createMemoizedSelector( @@ -15,8 +12,7 @@ export const selectListImagesQueryArgs = createMemoizedSelector( selectGallerySlice, (gallery): ListImagesArgs => ({ board_id: gallery.selectedBoardId, - categories: - gallery.galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES, + categories: gallery.galleryView === 'images' ? IMAGE_CATEGORIES : ASSETS_CATEGORIES, offset: gallery.offset, limit: gallery.limit, is_intermediate: false, diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index d1158173ed..6adad0be70 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -41,10 +41,7 @@ export const gallerySlice = createSlice({ autoAssignBoardOnClickChanged: (state, action: PayloadAction) => { state.autoAssignBoardOnClick = action.payload; }, - boardIdSelected: ( - state, - action: PayloadAction<{ boardId: BoardId; selectedImageName?: string }> - ) => { + boardIdSelected: (state, action: PayloadAction<{ boardId: BoardId; selectedImageName?: string }>) => { state.selectedBoardId = action.payload.boardId; state.galleryView = 'images'; state.offset = 0; @@ -86,19 +83,16 @@ export const gallerySlice = createSlice({ state.autoAddBoardId = 'none'; } }); - builder.addMatcher( - boardsApi.endpoints.listAllBoards.matchFulfilled, - (state, action) => { - const boards = action.payload; - if (!state.autoAddBoardId) { - return; - } - - if (!boards.map((b) => b.board_id).includes(state.autoAddBoardId)) { - state.autoAddBoardId = 'none'; - } + builder.addMatcher(boardsApi.endpoints.listAllBoards.matchFulfilled, (state, action) => { + const boards = action.payload; + if (!state.autoAddBoardId) { + return; } - ); + + if (!boards.map((b) => b.board_id).includes(state.autoAddBoardId)) { + state.autoAddBoardId = 'none'; + } + }); }, }); diff --git a/invokeai/frontend/web/src/features/gallery/store/types.ts b/invokeai/frontend/web/src/features/gallery/store/types.ts index 9f7ceedc6a..6ac9269b36 100644 --- a/invokeai/frontend/web/src/features/gallery/store/types.ts +++ b/invokeai/frontend/web/src/features/gallery/store/types.ts @@ -1,12 +1,7 @@ import type { ImageCategory, ImageDTO } from 'services/api/types'; export const IMAGE_CATEGORIES: ImageCategory[] = ['general']; -export const ASSETS_CATEGORIES: ImageCategory[] = [ - 'control', - 'mask', - 'user', - 'other', -]; +export const ASSETS_CATEGORIES: ImageCategory[] = ['control', 'mask', 'user', 'other']; export const INITIAL_IMAGE_LIMIT = 100; export const IMAGE_LIMIT = 20; diff --git a/invokeai/frontend/web/src/features/gallery/util/getScrollToIndexAlign.ts b/invokeai/frontend/web/src/features/gallery/util/getScrollToIndexAlign.ts index 46be56db88..686f89cd45 100644 --- a/invokeai/frontend/web/src/features/gallery/util/getScrollToIndexAlign.ts +++ b/invokeai/frontend/web/src/features/gallery/util/getScrollToIndexAlign.ts @@ -6,10 +6,7 @@ import type { ListRange } from 'react-virtuoso'; * @param range The range of items currently visible. * @returns */ -export const getScrollToIndexAlign = ( - index: number, - range: ListRange -): 'start' | 'end' => { +export const getScrollToIndexAlign = (index: number, range: ListRange): 'start' | 'end' => { if (index > (range.endIndex - range.startIndex) / 2 + range.startIndex) { return 'end'; } diff --git a/invokeai/frontend/web/src/features/hrf/components/HrfSettings.tsx b/invokeai/frontend/web/src/features/hrf/components/HrfSettings.tsx index cca4c49259..2cb96a935f 100644 --- a/invokeai/frontend/web/src/features/hrf/components/HrfSettings.tsx +++ b/invokeai/frontend/web/src/features/hrf/components/HrfSettings.tsx @@ -1,4 +1,4 @@ -import { FormControlGroup } from '@invoke-ai/ui'; +import { FormControlGroup } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { memo } from 'react'; diff --git a/invokeai/frontend/web/src/features/hrf/components/ParamHrfMethod.tsx b/invokeai/frontend/web/src/features/hrf/components/ParamHrfMethod.tsx index f13c041f79..8a94544233 100644 --- a/invokeai/frontend/web/src/features/hrf/components/ParamHrfMethod.tsx +++ b/invokeai/frontend/web/src/features/hrf/components/ParamHrfMethod.tsx @@ -1,5 +1,5 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { setHrfMethod } from 'features/hrf/store/hrfSlice'; import { isParameterHRFMethod } from 'features/parameters/types/parameterSchemas'; @@ -26,10 +26,7 @@ const ParamHrfMethodSelect = () => { [dispatch] ); - const value = useMemo( - () => options.find((o) => o.value === hrfMethod), - [hrfMethod] - ); + const value = useMemo(() => options.find((o) => o.value === hrfMethod), [hrfMethod]); return ( diff --git a/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx b/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx index 3033b6f578..c663989b08 100644 --- a/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx +++ b/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx @@ -1,9 +1,4 @@ -import { - CompositeNumberInput, - CompositeSlider, - FormControl, - FormLabel, -} from '@invoke-ai/ui'; +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { setHrfStrength } from 'features/hrf/store/hrfSlice'; import { memo, useCallback } from 'react'; @@ -14,12 +9,8 @@ const ParamHrfStrength = () => { const initial = useAppSelector((s) => s.config.sd.hrfStrength.initial); const sliderMin = useAppSelector((s) => s.config.sd.hrfStrength.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.hrfStrength.sliderMax); - const numberInputMin = useAppSelector( - (s) => s.config.sd.hrfStrength.numberInputMin - ); - const numberInputMax = useAppSelector( - (s) => s.config.sd.hrfStrength.numberInputMax - ); + const numberInputMin = useAppSelector((s) => s.config.sd.hrfStrength.numberInputMin); + const numberInputMax = useAppSelector((s) => s.config.sd.hrfStrength.numberInputMax); const coarseStep = useAppSelector((s) => s.config.sd.hrfStrength.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.hrfStrength.fineStep); const dispatch = useAppDispatch(); diff --git a/invokeai/frontend/web/src/features/hrf/components/ParamHrfToggle.tsx b/invokeai/frontend/web/src/features/hrf/components/ParamHrfToggle.tsx index 47ce6190fc..fdd2c97e9f 100644 --- a/invokeai/frontend/web/src/features/hrf/components/ParamHrfToggle.tsx +++ b/invokeai/frontend/web/src/features/hrf/components/ParamHrfToggle.tsx @@ -1,4 +1,4 @@ -import { FormControl, FormLabel, Switch } from '@invoke-ai/ui'; +import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { setHrfEnabled } from 'features/hrf/store/hrfSlice'; import type { ChangeEvent } from 'react'; @@ -12,8 +12,7 @@ const ParamHrfToggle = () => { const hrfEnabled = useAppSelector((s) => s.hrf.hrfEnabled); const handleHrfEnabled = useCallback( - (e: ChangeEvent) => - dispatch(setHrfEnabled(e.target.checked)), + (e: ChangeEvent) => dispatch(setHrfEnabled(e.target.checked)), [dispatch] ); diff --git a/invokeai/frontend/web/src/features/hrf/store/hrfSlice.ts b/invokeai/frontend/web/src/features/hrf/store/hrfSlice.ts index 5190272b97..ac846ec58e 100644 --- a/invokeai/frontend/web/src/features/hrf/store/hrfSlice.ts +++ b/invokeai/frontend/web/src/features/hrf/store/hrfSlice.ts @@ -1,10 +1,7 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import type { RootState } from 'app/store/store'; -import type { - ParameterHRFMethod, - ParameterStrength, -} from 'features/parameters/types/parameterSchemas'; +import type { ParameterHRFMethod, ParameterStrength } from 'features/parameters/types/parameterSchemas'; export interface HRFState { _version: 1; diff --git a/invokeai/frontend/web/src/features/lora/components/LoRACard.tsx b/invokeai/frontend/web/src/features/lora/components/LoRACard.tsx index 9fdaa64bcc..f0c8e3fcd3 100644 --- a/invokeai/frontend/web/src/features/lora/components/LoRACard.tsx +++ b/invokeai/frontend/web/src/features/lora/components/LoRACard.tsx @@ -6,7 +6,7 @@ import { CompositeSlider, IconButton, Text, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import type { LoRA } from 'features/lora/store/loraSlice'; import { loraRemoved, loraWeightChanged } from 'features/lora/store/loraSlice'; diff --git a/invokeai/frontend/web/src/features/lora/components/LoRAList.tsx b/invokeai/frontend/web/src/features/lora/components/LoRAList.tsx index 4804cf76c6..9f37454d16 100644 --- a/invokeai/frontend/web/src/features/lora/components/LoRAList.tsx +++ b/invokeai/frontend/web/src/features/lora/components/LoRAList.tsx @@ -1,4 +1,4 @@ -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import { LoRACard } from 'features/lora/components/LoRACard'; @@ -6,9 +6,7 @@ import { selectLoraSlice } from 'features/lora/store/loraSlice'; import { map } from 'lodash-es'; import { memo } from 'react'; -const selectLoRAsArray = createMemoizedSelector(selectLoraSlice, (lora) => - map(lora.loras) -); +const selectLoRAsArray = createMemoizedSelector(selectLoraSlice, (lora) => map(lora.loras)); export const LoRAList = memo(() => { const lorasArray = useAppSelector(selectLoRAsArray); diff --git a/invokeai/frontend/web/src/features/lora/components/LoRASelect.tsx b/invokeai/frontend/web/src/features/lora/components/LoRASelect.tsx index 8b51e6876e..30ef99d2f7 100644 --- a/invokeai/frontend/web/src/features/lora/components/LoRASelect.tsx +++ b/invokeai/frontend/web/src/features/lora/components/LoRASelect.tsx @@ -1,5 +1,5 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useGroupedModelCombobox } from 'common/hooks/useGroupedModelCombobox'; @@ -9,19 +9,14 @@ import { useTranslation } from 'react-i18next'; import type { LoRAModelConfigEntity } from 'services/api/endpoints/models'; import { useGetLoRAModelsQuery } from 'services/api/endpoints/models'; -const selectAddedLoRAs = createMemoizedSelector( - selectLoraSlice, - (lora) => lora.loras -); +const selectAddedLoRAs = createMemoizedSelector(selectLoraSlice, (lora) => lora.loras); const LoRASelect = () => { const dispatch = useAppDispatch(); const { data, isLoading } = useGetLoRAModelsQuery(); const { t } = useTranslation(); const addedLoRAs = useAppSelector(selectAddedLoRAs); - const currentBaseModel = useAppSelector( - (s) => s.generation.model?.base_model - ); + const currentBaseModel = useAppSelector((s) => s.generation.model?.base_model); const getIsDisabled = (lora: LoRAModelConfigEntity): boolean => { const isCompatible = currentBaseModel === lora.base_model; diff --git a/invokeai/frontend/web/src/features/lora/store/loraSlice.ts b/invokeai/frontend/web/src/features/lora/store/loraSlice.ts index c61a42af02..8562090fbc 100644 --- a/invokeai/frontend/web/src/features/lora/store/loraSlice.ts +++ b/invokeai/frontend/web/src/features/lora/store/loraSlice.ts @@ -31,10 +31,7 @@ export const loraSlice = createSlice({ const { model_name, id, base_model } = action.payload; state.loras[id] = { id, model_name, base_model, ...defaultLoRAConfig }; }, - loraRecalled: ( - state, - action: PayloadAction - ) => { + loraRecalled: (state, action: PayloadAction) => { const { model_name, id, base_model, weight } = action.payload; state.loras[id] = { id, model_name, base_model, weight }; }, @@ -45,10 +42,7 @@ export const loraSlice = createSlice({ lorasCleared: (state) => { state.loras = {}; }, - loraWeightChanged: ( - state, - action: PayloadAction<{ id: string; weight: number }> - ) => { + loraWeightChanged: (state, action: PayloadAction<{ id: string; weight: number }>) => { const { id, weight } = action.payload; const lora = state.loras[id]; if (!lora) { @@ -67,14 +61,8 @@ export const loraSlice = createSlice({ }, }); -export const { - loraAdded, - loraRemoved, - loraWeightChanged, - loraWeightReset, - lorasCleared, - loraRecalled, -} = loraSlice.actions; +export const { loraAdded, loraRemoved, loraWeightChanged, loraWeightReset, lorasCleared, loraRecalled } = + loraSlice.actions; export default loraSlice.reducer; diff --git a/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsButton.tsx b/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsButton.tsx index 0fd2bdb3a6..8a49bc2585 100644 --- a/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsButton.tsx +++ b/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsButton.tsx @@ -1,5 +1,5 @@ -import type { ButtonProps } from '@invoke-ai/ui'; -import { Button } from '@invoke-ai/ui'; +import type { ButtonProps } from '@invoke-ai/ui-library'; +import { Button } from '@invoke-ai/ui-library'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsIconButton.tsx b/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsIconButton.tsx index 0bff475673..986a99bd0b 100644 --- a/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsIconButton.tsx +++ b/invokeai/frontend/web/src/features/modelManager/components/SyncModels/SyncModelsIconButton.tsx @@ -1,5 +1,5 @@ -import type { IconButtonProps } from '@invoke-ai/ui'; -import { IconButton } from '@invoke-ai/ui'; +import type { IconButtonProps } from '@invoke-ai/ui-library'; +import { IconButton } from '@invoke-ai/ui-library'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -7,29 +7,27 @@ import { PiArrowsClockwiseBold } from 'react-icons/pi'; import { useSyncModels } from './useSyncModels'; -export const SyncModelsIconButton = memo( - (props: Omit) => { - const { t } = useTranslation(); - const { syncModels, isLoading } = useSyncModels(); - const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled; +export const SyncModelsIconButton = memo((props: Omit) => { + const { t } = useTranslation(); + const { syncModels, isLoading } = useSyncModels(); + const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled; - if (!isSyncModelEnabled) { - return null; - } - - return ( - } - tooltip={t('modelManager.syncModels')} - aria-label={t('modelManager.syncModels')} - isLoading={isLoading} - onClick={syncModels} - size="sm" - variant="ghost" - {...props} - /> - ); + if (!isSyncModelEnabled) { + return null; } -); + + return ( + } + tooltip={t('modelManager.syncModels')} + aria-label={t('modelManager.syncModels')} + isLoading={isLoading} + onClick={syncModels} + size="sm" + variant="ghost" + {...props} + /> + ); +}); SyncModelsIconButton.displayName = 'SyncModelsIconButton'; diff --git a/invokeai/frontend/web/src/features/modelManager/store/modelManagerSlice.ts b/invokeai/frontend/web/src/features/modelManager/store/modelManagerSlice.ts index 829e9d4d9b..5da08d7f54 100644 --- a/invokeai/frontend/web/src/features/modelManager/store/modelManagerSlice.ts +++ b/invokeai/frontend/web/src/features/modelManager/store/modelManagerSlice.ts @@ -27,8 +27,7 @@ export const modelManagerSlice = createSlice({ }, }); -export const { setSearchFolder, setAdvancedAddScanModel } = - modelManagerSlice.actions; +export const { setSearchFolder, setAdvancedAddScanModel } = modelManagerSlice.actions; export default modelManagerSlice.reducer; diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AddModels.tsx index c3e85a3a5b..cb50334c99 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AddModels.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AddModels.tsx @@ -1,4 +1,4 @@ -import { Button, ButtonGroup, Flex } from '@invoke-ai/ui'; +import { Button, ButtonGroup, Flex } from '@invoke-ai/ui-library'; import { memo, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -7,35 +7,16 @@ import SimpleAddModels from './SimpleAddModels'; const AddModels = () => { const { t } = useTranslation(); - const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>( - 'simple' - ); + const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>('simple'); const handleAddModelSimple = useCallback(() => setAddModelMode('simple'), []); - const handleAddModelAdvanced = useCallback( - () => setAddModelMode('advanced'), - [] - ); + const handleAddModelAdvanced = useCallback(() => setAddModelMode('advanced'), []); return ( - + - - diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx index 0960c51417..31f4312eb5 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx @@ -1,12 +1,4 @@ -import { - Button, - Checkbox, - Flex, - FormControl, - FormErrorMessage, - FormLabel, - Input, -} from '@invoke-ai/ui'; +import { Button, Checkbox, Flex, FormControl, FormErrorMessage, FormLabel, Input } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { setAdvancedAddScanModel } from 'features/modelManager/store/modelManagerSlice'; import BaseModelSelect from 'features/modelManager/subpanels/shared/BaseModelSelect'; @@ -113,10 +105,7 @@ const AdvancedAddCheckpoint = (props: AdvancedAddCheckpointProps) => { [getValues, setValue] ); - const handleChangeUseCustomConfig = useCallback( - () => setUseCustomConfig((prev) => !prev), - [] - ); + const handleChangeUseCustomConfig = useCallback(() => setUseCustomConfig((prev) => !prev), []); return (
@@ -125,30 +114,21 @@ const AdvancedAddCheckpoint = (props: AdvancedAddCheckpointProps) => { {t('modelManager.model')} - value.trim().length > 3 || 'Must be at least 3 characters', + validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters', })} /> - {errors.model_name?.message && ( - {errors.model_name?.message} - )} + {errors.model_name?.message && {errors.model_name?.message}} - - control={control} - name="base_model" - /> + control={control} name="base_model" /> {t('modelManager.modelLocation')} - value.trim().length > 0 || 'Must provide a path', + validate: (value) => value.trim().length > 0 || 'Must provide a path', onBlur, })} /> - {errors.path?.message && ( - {errors.path?.message} - )} + {errors.path?.message && {errors.path?.message}} {t('modelManager.description')} @@ -158,10 +138,7 @@ const AdvancedAddCheckpoint = (props: AdvancedAddCheckpointProps) => { {t('modelManager.vaeLocation')} - - control={control} - name="variant" - /> + control={control} name="variant" /> {!useCustomConfig ? ( @@ -173,10 +150,7 @@ const AdvancedAddCheckpoint = (props: AdvancedAddCheckpointProps) => { )} {t('modelManager.useCustomConfig')} - + - ) : ( - + {t('common.installed')} )} @@ -162,15 +125,7 @@ const FoundModelsList = () => { if (!foundModels || foundModels.length === 0) { return ( - + {t('modelManager.noModels')} ); @@ -204,10 +159,7 @@ const FoundModelsList = () => { return renderFoundModels(); }; -const foundModelsFilter = ( - data: SearchFolderResponse | undefined, - nameFilter: string -) => { +const foundModelsFilter = (data: SearchFolderResponse | undefined, nameFilter: string) => { const filteredModels: SearchFolderResponse = []; forEach(data, (model) => { if (!model) { diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx index 933a3c8498..445eb7ed5a 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx @@ -1,13 +1,5 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { - Box, - Combobox, - Flex, - FormControl, - FormLabel, - IconButton, - Text, -} from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Box, Combobox, Flex, FormControl, FormLabel, IconButton, Text } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { setAdvancedAddScanModel } from 'features/modelManager/store/modelManagerSlice'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; @@ -20,9 +12,7 @@ import type { ManualAddMode } from './AdvancedAddModels'; import { isManualAddMode } from './AdvancedAddModels'; const ScanAdvancedAddModels = () => { - const advancedAddScanModel = useAppSelector( - (s) => s.modelmanager.advancedAddScanModel - ); + const advancedAddScanModel = useAppSelector((s) => s.modelmanager.advancedAddScanModel); const { t } = useTranslation(); @@ -34,26 +24,19 @@ const ScanAdvancedAddModels = () => { [t] ); - const [advancedAddMode, setAdvancedAddMode] = - useState('diffusers'); + const [advancedAddMode, setAdvancedAddMode] = useState('diffusers'); const [isCheckpoint, setIsCheckpoint] = useState(true); useEffect(() => { - advancedAddScanModel && - ['.ckpt', '.safetensors', '.pth', '.pt'].some((ext) => - advancedAddScanModel.endsWith(ext) - ) + advancedAddScanModel && ['.ckpt', '.safetensors', '.pth', '.pt'].some((ext) => advancedAddScanModel.endsWith(ext)) ? setAdvancedAddMode('checkpoint') : setAdvancedAddMode('diffusers'); }, [advancedAddScanModel, setAdvancedAddMode, isCheckpoint]); const dispatch = useAppDispatch(); - const handleClickSetAdvanced = useCallback( - () => dispatch(setAdvancedAddScanModel(null)), - [dispatch] - ); + const handleClickSetAdvanced = useCallback(() => dispatch(setAdvancedAddScanModel(null)), [dispatch]); const handleChangeAddMode = useCallback((v) => { if (!isManualAddMode(v?.value)) { @@ -67,10 +50,7 @@ const ScanAdvancedAddModels = () => { } }, []); - const value = useMemo( - () => options.find((o) => o.value === advancedAddMode), - [options, advancedAddMode] - ); + const value = useMemo(() => options.find((o) => o.value === advancedAddMode), [options, advancedAddMode]); if (!advancedAddScanModel) { return null; @@ -90,9 +70,7 @@ const ScanAdvancedAddModels = () => { > - {isCheckpoint || advancedAddMode === 'checkpoint' - ? 'Add Checkpoint Model' - : 'Add Diffusers Model'} + {isCheckpoint || advancedAddMode === 'checkpoint' ? 'Add Checkpoint Model' : 'Add Diffusers Model'} } @@ -103,22 +81,12 @@ const ScanAdvancedAddModels = () => { {t('modelManager.modelType')} - + {isCheckpoint ? ( - + ) : ( - + )} ); diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanModels.tsx index 694bcbc644..f3287270a2 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanModels.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanModels.tsx @@ -1,4 +1,4 @@ -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import { memo } from 'react'; import FoundModelsList from './FoundModelsList'; diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx index 6e3368a4d2..dc1d39f7aa 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx @@ -1,18 +1,11 @@ -import { Flex, IconButton, Input, Text } from '@invoke-ai/ui'; +import { Flex, IconButton, Input, Text } from '@invoke-ai/ui-library'; import { useForm } from '@mantine/form'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { - setAdvancedAddScanModel, - setSearchFolder, -} from 'features/modelManager/store/modelManagerSlice'; +import { setAdvancedAddScanModel, setSearchFolder } from 'features/modelManager/store/modelManagerSlice'; import type { CSSProperties } from 'react'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { - PiArrowsCounterClockwiseBold, - PiMagnifyingGlassBold, - PiTrashSimpleBold, -} from 'react-icons/pi'; +import { PiArrowsCounterClockwiseBold, PiMagnifyingGlassBold, PiTrashSimpleBold } from 'react-icons/pi'; import { useGetModelsInFolderQuery } from 'services/api/endpoints/models'; type SearchFolderForm = { @@ -52,38 +45,16 @@ function SearchFolderForm() { }, [dispatch]); return ( - - searchFolderFormSubmitHandler(values) - )} - style={formStyles} - > + searchFolderFormSubmitHandler(values))} style={formStyles}> - + {t('common.folder')} {!searchFolder ? ( - + ) : ( - + {searchFolder} )} diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx index 8b7367153e..d7f705aedc 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx @@ -1,12 +1,5 @@ -import type { ComboboxOption } from '@invoke-ai/ui'; -import { - Button, - Combobox, - Flex, - FormControl, - FormLabel, - Input, -} from '@invoke-ai/ui'; +import type { ComboboxOption } from '@invoke-ai/ui-library'; +import { Button, Combobox, Flex, FormControl, FormLabel, Input } from '@invoke-ai/ui-library'; import { useForm } from '@mantine/form'; import { useAppDispatch } from 'app/store/storeHooks'; import { addToast } from 'features/system/store/systemSlice'; @@ -44,8 +37,7 @@ const SimpleAddModels = () => { const handleAddModelSubmit = (values: ExtendedImportModelConfig) => { const importModelResponseBody = { location: values.location, - prediction_type: - values.prediction_type === 'none' ? undefined : values.prediction_type, + prediction_type: values.prediction_type === 'none' ? undefined : values.prediction_type, }; importMainModel({ body: importModelResponseBody }) @@ -76,26 +68,15 @@ const SimpleAddModels = () => { }; return ( - handleAddModelSubmit(v))} - style={formStyles} - > + handleAddModelSubmit(v))} style={formStyles}> {t('modelManager.modelLocation')} - + {t('modelManager.predictionType')} - + - - {addModelTab == 'add' && } - {addModelTab == 'scan' && } + {addModelTab === 'add' && } + {addModelTab === 'scan' && } ); }; diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/MergeModelsPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/MergeModelsPanel.tsx index 8c113f5da5..fe90db5b8a 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/MergeModelsPanel.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/MergeModelsPanel.tsx @@ -1,4 +1,4 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; import { Button, Checkbox, @@ -14,7 +14,7 @@ import { RadioGroup, Text, Tooltip, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; @@ -23,10 +23,7 @@ import type { ChangeEvent } from 'react'; import { memo, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ALL_BASE_MODELS } from 'services/api/constants'; -import { - useGetMainModelsQuery, - useMergeMainModelsMutation, -} from 'services/api/endpoints/models'; +import { useGetMainModelsQuery, useMergeMainModelsMutation } from 'services/api/endpoints/models'; import type { BaseModelType, MergeModelConfig } from 'services/api/types'; const baseModelTypeSelectOptions: ComboboxOption[] = [ @@ -34,11 +31,7 @@ const baseModelTypeSelectOptions: ComboboxOption[] = [ { label: 'Stable Diffusion 2', value: 'sd-2' }, ]; -type MergeInterpolationMethods = - | 'weighted_sum' - | 'sigmoid' - | 'inv_sigmoid' - | 'add_difference'; +type MergeInterpolationMethods = 'weighted_sum' | 'sigmoid' | 'inv_sigmoid' | 'add_difference'; const MergeModelsPanel = () => { const { t } = useTranslation(); @@ -49,20 +42,15 @@ const MergeModelsPanel = () => { const [mergeModels, { isLoading }] = useMergeMainModelsMutation(); const [baseModel, setBaseModel] = useState('sd-1'); - const valueBaseModel = useMemo( - () => baseModelTypeSelectOptions.find((o) => o.value === baseModel), - [baseModel] - ); + const valueBaseModel = useMemo(() => baseModelTypeSelectOptions.find((o) => o.value === baseModel), [baseModel]); const sd1DiffusersModels = pickBy( data?.entities, - (value, _) => - value?.model_format === 'diffusers' && value?.base_model === 'sd-1' + (value, _) => value?.model_format === 'diffusers' && value?.base_model === 'sd-1' ); const sd2DiffusersModels = pickBy( data?.entities, - (value, _) => - value?.model_format === 'diffusers' && value?.base_model === 'sd-2' + (value, _) => value?.model_format === 'diffusers' && value?.base_model === 'sd-2' ); const modelsMap = useMemo(() => { @@ -83,15 +71,11 @@ const MergeModelsPanel = () => { const [mergedModelName, setMergedModelName] = useState(''); const [modelMergeAlpha, setModelMergeAlpha] = useState(0.5); - const [modelMergeInterp, setModelMergeInterp] = - useState('weighted_sum'); + const [modelMergeInterp, setModelMergeInterp] = useState('weighted_sum'); - const [modelMergeSaveLocType, setModelMergeSaveLocType] = useState< - 'root' | 'custom' - >('root'); + const [modelMergeSaveLocType, setModelMergeSaveLocType] = useState<'root' | 'custom'>('root'); - const [modelMergeCustomSaveLoc, setModelMergeCustomSaveLoc] = - useState(''); + const [modelMergeCustomSaveLoc, setModelMergeCustomSaveLoc] = useState(''); const [modelMergeForce, setModelMergeForce] = useState(false); @@ -153,14 +137,8 @@ const MergeModelsPanel = () => { } }, []); - const valueModelOne = useMemo( - () => optionsModelOne.find((o) => o.value === modelOne), - [modelOne, optionsModelOne] - ); - const valueModelTwo = useMemo( - () => optionsModelTwo.find((o) => o.value === modelTwo), - [modelTwo, optionsModelTwo] - ); + const valueModelOne = useMemo(() => optionsModelOne.find((o) => o.value === modelOne), [modelOne, optionsModelOne]); + const valueModelTwo = useMemo(() => optionsModelTwo.find((o) => o.value === modelTwo), [modelTwo, optionsModelTwo]); const valueModelThree = useMemo( () => optionsModelThree.find((o) => o.value === modelThree), [modelThree, optionsModelThree] @@ -170,25 +148,12 @@ const MergeModelsPanel = () => { (e: ChangeEvent) => setMergedModelName(e.target.value), [] ); - const handleChangeModelMergeAlpha = useCallback( - (v: number) => setModelMergeAlpha(v), - [] - ); - const handleResetModelMergeAlpha = useCallback( - () => setModelMergeAlpha(0.5), - [] - ); - const handleChangeMergeInterp = useCallback( - (v: MergeInterpolationMethods) => setModelMergeInterp(v), - [] - ); - const handleChangeMergeSaveLocType = useCallback( - (v: 'root' | 'custom') => setModelMergeSaveLocType(v), - [] - ); + const handleChangeModelMergeAlpha = useCallback((v: number) => setModelMergeAlpha(v), []); + const handleResetModelMergeAlpha = useCallback(() => setModelMergeAlpha(0.5), []); + const handleChangeMergeInterp = useCallback((v: MergeInterpolationMethods) => setModelMergeInterp(v), []); + const handleChangeMergeSaveLocType = useCallback((v: 'root' | 'custom') => setModelMergeSaveLocType(v), []); const handleChangeMergeCustomSaveLoc = useCallback( - (e: ChangeEvent) => - setModelMergeCustomSaveLoc(e.target.value), + (e: ChangeEvent) => setModelMergeCustomSaveLoc(e.target.value), [] ); const handleChangeModelMergeForce = useCallback( @@ -210,13 +175,11 @@ const MergeModelsPanel = () => { const mergeModelsInfo: MergeModelConfig['body'] = { model_names: models_names, - merged_model_name: - mergedModelName !== '' ? mergedModelName : models_names.join('-'), + merged_model_name: mergedModelName !== '' ? mergedModelName : models_names.join('-'), alpha: modelMergeAlpha, interp: modelMergeInterp, force: modelMergeForce, - merge_dest_directory: - modelMergeSaveLocType === 'root' ? undefined : modelMergeCustomSaveLoc, + merge_dest_directory: modelMergeSaveLocType === 'root' ? undefined : modelMergeCustomSaveLoc, }; mergeModels({ @@ -274,36 +237,19 @@ const MergeModelsPanel = () => { {t('modelManager.modelType')} - + {t('modelManager.modelOne')} - + {t('modelManager.modelTwo')} - + {t('modelManager.modelThree')} - + @@ -312,13 +258,7 @@ const MergeModelsPanel = () => { - + {t('modelManager.alpha')} { onChange={handleChangeModelMergeAlpha} onReset={handleResetModelMergeAlpha} /> - - {t('modelManager.modelMergeAlphaHelp')} - + {t('modelManager.modelMergeAlphaHelp')} @@ -364,9 +302,7 @@ const MergeModelsPanel = () => { ) : ( - + {t('modelManager.addDifference')} @@ -375,21 +311,12 @@ const MergeModelsPanel = () => { - + {t('modelManager.mergedModelSaveLocation')} - + {t('modelManager.invokeAIFolder')} @@ -404,30 +331,18 @@ const MergeModelsPanel = () => { {modelMergeSaveLocType === 'custom' && ( - - {t('modelManager.mergedModelCustomSaveLocation')} - - + {t('modelManager.mergedModelCustomSaveLocation')} + )} {t('modelManager.ignoreMismatch')} - + - diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel.tsx index 55272a98cc..6b9abdbfec 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel.tsx @@ -1,4 +1,4 @@ -import { Flex, Text } from '@invoke-ai/ui'; +import { Flex, Text } from '@invoke-ai/ui-library'; import { memo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ALL_BASE_MODELS } from 'services/api/constants'; @@ -7,10 +7,7 @@ import type { LoRAModelConfigEntity, MainModelConfigEntity, } from 'services/api/endpoints/models'; -import { - useGetLoRAModelsQuery, - useGetMainModelsQuery, -} from 'services/api/endpoints/models'; +import { useGetLoRAModelsQuery, useGetMainModelsQuery } from 'services/api/endpoints/models'; import CheckpointModelEdit from './ModelManagerPanel/CheckpointModelEdit'; import DiffusersModelEdit from './ModelManagerPanel/DiffusersModelEdit'; @@ -34,10 +31,7 @@ const ModelManagerPanel = () => { return ( - + ); @@ -56,12 +50,7 @@ const ModelEdit = (props: ModelEditProps) => { } if (model?.model_format === 'diffusers') { - return ( - - ); + return ; } if (model?.model_type === 'lora') { @@ -69,14 +58,7 @@ const ModelEdit = (props: ModelEditProps) => { } return ( - + {t('modelManager.noModelSelected')} ); diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx index 549c725b34..f4d271187d 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx @@ -9,7 +9,7 @@ import { FormLabel, Input, Text, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import BaseModelSelect from 'features/modelManager/subpanels/shared/BaseModelSelect'; import CheckpointConfigsSelect from 'features/modelManager/subpanels/shared/CheckpointConfigsSelect'; @@ -22,10 +22,7 @@ import type { SubmitHandler } from 'react-hook-form'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import type { CheckpointModelConfigEntity } from 'services/api/endpoints/models'; -import { - useGetCheckpointConfigsQuery, - useUpdateMainModelsMutation, -} from 'services/api/endpoints/models'; +import { useGetCheckpointConfigsQuery, useUpdateMainModelsMutation } from 'services/api/endpoints/models'; import type { CheckpointModelConfig } from 'services/api/types'; import ModelConvert from './ModelConvert'; @@ -72,10 +69,7 @@ const CheckpointModelEdit = (props: CheckpointModelEditProps) => { mode: 'onChange', }); - const handleChangeUseCustomConfig = useCallback( - () => setUseCustomConfig((prev) => !prev), - [] - ); + const handleChangeUseCustomConfig = useCallback(() => setUseCustomConfig((prev) => !prev), []); const onSubmit = useCallback>( (values) => { @@ -133,50 +127,32 @@ const CheckpointModelEdit = (props: CheckpointModelEditProps) => { - + {t('modelManager.name')} - value.trim().length > 3 || 'Must be at least 3 characters', + validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters', })} /> - {errors.model_name?.message && ( - - {errors.model_name?.message} - - )} + {errors.model_name?.message && {errors.model_name?.message}} {t('modelManager.description')} - - control={control} - name="base_model" - /> - - control={control} - name="variant" - /> + control={control} name="base_model" /> + control={control} name="variant" /> {t('modelManager.modelLocation')} - value.trim().length > 0 || 'Must provide a path', + validate: (value) => value.trim().length > 0 || 'Must provide a path', })} /> - {errors.path?.message && ( - {errors.path?.message} - )} + {errors.path?.message && {errors.path?.message}} {t('modelManager.vaeLocation')} @@ -194,10 +170,7 @@ const CheckpointModelEdit = (props: CheckpointModelEditProps) => { )} {t('modelManager.useCustomConfig')} - + diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx index a873d06e61..4670f32157 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx @@ -1,13 +1,4 @@ -import { - Button, - Divider, - Flex, - FormControl, - FormErrorMessage, - FormLabel, - Input, - Text, -} from '@invoke-ai/ui'; +import { Button, Divider, Flex, FormControl, FormErrorMessage, FormLabel, Input, Text } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import BaseModelSelect from 'features/modelManager/subpanels/shared/BaseModelSelect'; import ModelVariantSelect from 'features/modelManager/subpanels/shared/ModelVariantSelect'; @@ -108,37 +99,25 @@ const DiffusersModelEdit = (props: DiffusersModelEditProps) => { {t('modelManager.name')} - value.trim().length > 3 || 'Must be at least 3 characters', + validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters', })} /> - {errors.model_name?.message && ( - {errors.model_name?.message} - )} + {errors.model_name?.message && {errors.model_name?.message}} {t('modelManager.description')} - - control={control} - name="base_model" - /> - - control={control} - name="variant" - /> + control={control} name="base_model" /> + control={control} name="variant" /> {t('modelManager.modelLocation')} - value.trim().length > 0 || 'Must provide a path', + validate: (value) => value.trim().length > 0 || 'Must provide a path', })} /> - {errors.path?.message && ( - {errors.path?.message} - )} + {errors.path?.message && {errors.path?.message}} {t('modelManager.vaeLocation')} diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx index 67a6f5c1e5..2baf735bee 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx @@ -1,19 +1,7 @@ -import { - Button, - Divider, - Flex, - FormControl, - FormErrorMessage, - FormLabel, - Input, - Text, -} from '@invoke-ai/ui'; +import { Button, Divider, Flex, FormControl, FormErrorMessage, FormLabel, Input, Text } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import BaseModelSelect from 'features/modelManager/subpanels/shared/BaseModelSelect'; -import { - LORA_MODEL_FORMAT_MAP, - MODEL_TYPE_MAP, -} from 'features/parameters/types/constants'; +import { LORA_MODEL_FORMAT_MAP, MODEL_TYPE_MAP } from 'features/parameters/types/constants'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; import { memo, useCallback } from 'react'; @@ -97,8 +85,8 @@ const LoRAModelEdit = (props: LoRAModelEditProps) => { {model.model_name} - {MODEL_TYPE_MAP[model.base_model]} {t('modelManager.model')} ⋅{' '} - {LORA_MODEL_FORMAT_MAP[model.model_format]} {t('common.format')} + {MODEL_TYPE_MAP[model.base_model]} {t('modelManager.model')} ⋅ {LORA_MODEL_FORMAT_MAP[model.model_format]}{' '} + {t('common.format')} @@ -109,34 +97,25 @@ const LoRAModelEdit = (props: LoRAModelEditProps) => { {t('modelManager.name')} - value.trim().length > 3 || 'Must be at least 3 characters', + validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters', })} /> - {errors.model_name?.message && ( - {errors.model_name?.message} - )} + {errors.model_name?.message && {errors.model_name?.message}} {t('modelManager.description')} - - control={control} - name="base_model" - /> + control={control} name="base_model" /> {t('modelManager.modelLocation')} - value.trim().length > 0 || 'Must provide a path', + validate: (value) => value.trim().length > 0 || 'Must provide a path', })} /> - {errors.path?.message && ( - {errors.path?.message} - )} + {errors.path?.message && {errors.path?.message}} - @@ -122,16 +83,9 @@ const ModelList = (props: ModelListProps) => { - + {/* Diffusers List */} - {isLoadingDiffusersModels && ( - - )} + {isLoadingDiffusersModels && } {['all', 'diffusers'].includes(modelFormatFilter) && !isLoadingDiffusersModels && filteredDiffusersModels.length > 0 && ( @@ -143,9 +97,7 @@ const ModelList = (props: ModelListProps) => { /> )} {/* Checkpoints List */} - {isLoadingCheckpointModels && ( - - )} + {isLoadingCheckpointModels && } {['all', 'checkpoint'].includes(modelFormatFilter) && !isLoadingCheckpointModels && filteredCheckpointModels.length > 0 && ( @@ -158,19 +110,15 @@ const ModelList = (props: ModelListProps) => { )} {/* LoRAs List */} - {isLoadingLoraModels && ( - + {isLoadingLoraModels && } + {['all', 'lora'].includes(modelFormatFilter) && !isLoadingLoraModels && filteredLoraModels.length > 0 && ( + )} - {['all', 'lora'].includes(modelFormatFilter) && - !isLoadingLoraModels && - filteredLoraModels.length > 0 && ( - - )} @@ -191,12 +139,9 @@ const modelsFilter = ( return; } - const matchesFilter = model.model_name - .toLowerCase() - .includes(nameFilter.toLowerCase()); + const matchesFilter = model.model_name.toLowerCase().includes(nameFilter.toLowerCase()); - const matchesFormat = - model_format === undefined || model.model_format === model_format; + const matchesFormat = model_format === undefined || model.model_format === model_format; const matchesType = model.model_type === model_type; if (matchesFilter && matchesFormat && matchesType) { @@ -245,25 +190,15 @@ const ModelListWrapper = memo((props: ModelListWrapperProps) => { ModelListWrapper.displayName = 'ModelListWrapper'; -const FetchingModelsLoader = memo( - ({ loadingMessage }: { loadingMessage?: string }) => { - return ( - - - - - {loadingMessage ? loadingMessage : 'Fetching...'} - - - - ); - } -); +const FetchingModelsLoader = memo(({ loadingMessage }: { loadingMessage?: string }) => { + return ( + + + + {loadingMessage ? loadingMessage : 'Fetching...'} + + + ); +}); FetchingModelsLoader.displayName = 'FetchingModelsLoader'; diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelListItem.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelListItem.tsx index 48774809d2..fdd13e09f5 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelListItem.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelListItem.tsx @@ -7,7 +7,7 @@ import { Text, Tooltip, useDisclosure, -} from '@invoke-ai/ui'; +} from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { MODEL_TYPE_SHORT_MAP } from 'features/parameters/types/constants'; import { addToast } from 'features/system/store/systemSlice'; @@ -15,14 +15,8 @@ import { makeToast } from 'features/system/util/makeToast'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiTrashSimpleBold } from 'react-icons/pi'; -import type { - LoRAModelConfigEntity, - MainModelConfigEntity, -} from 'services/api/endpoints/models'; -import { - useDeleteLoRAModelsMutation, - useDeleteMainModelsMutation, -} from 'services/api/endpoints/models'; +import type { LoRAModelConfigEntity, MainModelConfigEntity } from 'services/api/endpoints/models'; +import { useDeleteLoRAModelsMutation, useDeleteMainModelsMutation } from 'services/api/endpoints/models'; type ModelListItemProps = { model: MainModelConfigEntity | LoRAModelConfigEntity; @@ -66,9 +60,7 @@ const ModelListItem = (props: ModelListItemProps) => { dispatch( addToast( makeToast({ - title: `${t('modelManager.modelDeleteFailed')}: ${ - model.model_name - }`, + title: `${t('modelManager.modelDeleteFailed')}: ${model.model_name}`, status: 'error', }) ) @@ -76,14 +68,7 @@ const ModelListItem = (props: ModelListItemProps) => { } }); setSelectedModelId(undefined); - }, [ - deleteMainModel, - deleteLoRAModel, - model, - setSelectedModelId, - dispatch, - t, - ]); + }, [deleteMainModel, deleteLoRAModel, model, setSelectedModelId, dispatch, t]); return ( @@ -100,11 +85,7 @@ const ModelListItem = (props: ModelListItemProps) => { > - { - MODEL_TYPE_SHORT_MAP[ - model.base_model as keyof typeof MODEL_TYPE_SHORT_MAP - ] - } + {MODEL_TYPE_SHORT_MAP[model.base_model as keyof typeof MODEL_TYPE_SHORT_MAP]} {model.model_name} diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel.tsx index 91a6be5044..50118d9b97 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel.tsx @@ -1,4 +1,4 @@ -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import { memo } from 'react'; import SyncModels from './ModelManagerSettingsPanel/SyncModels'; diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx index d851b566ce..a4af3e1517 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx @@ -1,4 +1,4 @@ -import { Flex, Text } from '@invoke-ai/ui'; +import { Flex, Text } from '@invoke-ai/ui-library'; import { SyncModelsButton } from 'features/modelManager/components/SyncModels/SyncModelsButton'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -7,15 +7,7 @@ const SyncModels = () => { const { t } = useTranslation(); return ( - + {t('modelManager.syncModels')} diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/shared/BaseModelSelect.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/BaseModelSelect.tsx index fdae4da7dd..fce16f3f13 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/shared/BaseModelSelect.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/BaseModelSelect.tsx @@ -1,5 +1,5 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { typedMemo } from 'common/util/typedMemo'; import { MODEL_TYPE_MAP } from 'features/parameters/types/constants'; import { useCallback, useMemo } from 'react'; @@ -15,15 +15,10 @@ const options: ComboboxOption[] = [ { value: 'sdxl-refiner', label: MODEL_TYPE_MAP['sdxl-refiner'] }, ]; -const BaseModelSelect = ( - props: UseControllerProps -) => { +const BaseModelSelect = (props: UseControllerProps) => { const { t } = useTranslation(); const { field } = useController(props); - const value = useMemo( - () => options.find((o) => o.value === field.value), - [field.value] - ); + const value = useMemo(() => options.find((o) => o.value === field.value), [field.value]); const onChange = useCallback( (v) => { field.onChange(v?.value); diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/shared/CheckpointConfigsSelect.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/CheckpointConfigsSelect.tsx index 1e9ce209d3..569f1abbba 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/shared/CheckpointConfigsSelect.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/CheckpointConfigsSelect.tsx @@ -1,9 +1,5 @@ -import type { - ChakraProps, - ComboboxOnChange, - ComboboxOption, -} from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ChakraProps, ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { memo, useCallback, useMemo } from 'react'; import { useController, type UseControllerProps } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; @@ -12,20 +8,12 @@ import type { CheckpointModelConfig } from 'services/api/types'; const sx: ChakraProps['sx'] = { w: 'full' }; -const CheckpointConfigsSelect = ( - props: UseControllerProps -) => { +const CheckpointConfigsSelect = (props: UseControllerProps) => { const { data } = useGetCheckpointConfigsQuery(); const { t } = useTranslation(); - const options = useMemo( - () => (data ? data.map((i) => ({ label: i, value: i })) : []), - [data] - ); + const options = useMemo(() => (data ? data.map((i) => ({ label: i, value: i })) : []), [data]); const { field } = useController(props); - const value = useMemo( - () => options.find((o) => o.value === field.value), - [field.value, options] - ); + const value = useMemo(() => options.find((o) => o.value === field.value), [field.value, options]); const onChange = useCallback( (v) => { field.onChange(v?.value); @@ -36,13 +24,7 @@ const CheckpointConfigsSelect = ( return ( {t('modelManager.configFile')} - + ); }; diff --git a/invokeai/frontend/web/src/features/modelManager/subpanels/shared/ModelVariantSelect.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/ModelVariantSelect.tsx index 4514e18250..27ded93843 100644 --- a/invokeai/frontend/web/src/features/modelManager/subpanels/shared/ModelVariantSelect.tsx +++ b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/ModelVariantSelect.tsx @@ -1,14 +1,11 @@ -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { typedMemo } from 'common/util/typedMemo'; import { useCallback, useMemo } from 'react'; import type { UseControllerProps } from 'react-hook-form'; import { useController } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; -import type { - CheckpointModelConfig, - DiffusersModelConfig, -} from 'services/api/types'; +import type { CheckpointModelConfig, DiffusersModelConfig } from 'services/api/types'; const options: ComboboxOption[] = [ { value: 'normal', label: 'Normal' }, @@ -16,17 +13,10 @@ const options: ComboboxOption[] = [ { value: 'depth', label: 'Depth' }, ]; -const ModelVariantSelect = < - T extends CheckpointModelConfig | DiffusersModelConfig, ->( - props: UseControllerProps -) => { +const ModelVariantSelect = (props: UseControllerProps) => { const { t } = useTranslation(); const { field } = useController(props); - const value = useMemo( - () => options.find((o) => o.value === field.value), - [field.value] - ); + const value = useMemo(() => options.find((o) => o.value === field.value), [field.value]); const onChange = useCallback( (v) => { field.onChange(v?.value); diff --git a/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx b/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx index 65d142a830..501d263c38 100644 --- a/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx @@ -1,6 +1,6 @@ import 'reactflow/dist/style.css'; -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { IAINoContentFallback } from 'common/components/IAIImageFallback'; import TopPanel from 'features/nodes/components/flow/panels/TopPanel/TopPanel'; @@ -53,12 +53,7 @@ const NodeEditor = () => { > {isReady && ( - + @@ -69,12 +64,7 @@ const NodeEditor = () => { {!isReady && ( - + { justifyContent="center" pointerEvents="none" > - + )} diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/AddNodePopover/AddNodePopover.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/AddNodePopover/AddNodePopover.tsx index 368f3c4f7e..faa4c0b054 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/AddNodePopover/AddNodePopover.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/AddNodePopover/AddNodePopover.tsx @@ -1,24 +1,13 @@ import 'reactflow/dist/style.css'; -import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui'; -import { - Combobox, - Flex, - Popover, - PopoverAnchor, - PopoverBody, - PopoverContent, -} from '@invoke-ai/ui'; +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox, Flex, Popover, PopoverAnchor, PopoverBody, PopoverContent } from '@invoke-ai/ui-library'; import { useAppToaster } from 'app/components/Toaster'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import type { SelectInstance } from 'chakra-react-select'; import { useBuildNode } from 'features/nodes/hooks/useBuildNode'; -import { - addNodePopoverClosed, - addNodePopoverOpened, - nodeAdded, -} from 'features/nodes/store/nodesSlice'; +import { addNodePopoverClosed, addNodePopoverOpened, nodeAdded } from 'features/nodes/store/nodesSlice'; import { selectNodeTemplatesSlice } from 'features/nodes/store/nodeTemplatesSlice'; import { validateSourceAndTargetTypes } from 'features/nodes/store/util/validateSourceAndTargetTypes'; import { filter, map, memoize, some } from 'lodash-es'; @@ -42,19 +31,17 @@ const createRegex = memoize( ) ); -const filterOption = memoize( - (option: FilterOptionOption, inputValue: string) => { - if (!inputValue) { - return true; - } - const regex = createRegex(inputValue); - return ( - regex.test(option.label) || - regex.test(option.data.description ?? '') || - (option.data.tags ?? []).some((tag) => regex.test(tag)) - ); +const filterOption = memoize((option: FilterOptionOption, inputValue: string) => { + if (!inputValue) { + return true; } -); + const regex = createRegex(inputValue); + return ( + regex.test(option.label) || + regex.test(option.data.description ?? '') || + (option.data.tags ?? []).some((tag) => regex.test(tag)) + ); +}); const AddNodePopover = () => { const dispatch = useAppDispatch(); @@ -65,64 +52,53 @@ const AddNodePopover = () => { const inputRef = useRef(null); const fieldFilter = useAppSelector((s) => s.nodes.connectionStartFieldType); - const handleFilter = useAppSelector( - (s) => s.nodes.connectionStartParams?.handleType - ); + const handleFilter = useAppSelector((s) => s.nodes.connectionStartParams?.handleType); - const selector = createMemoizedSelector( - selectNodeTemplatesSlice, - (nodeTemplates) => { - // If we have a connection in progress, we need to filter the node choices - const filteredNodeTemplates = fieldFilter - ? filter(nodeTemplates.templates, (template) => { - const handles = - handleFilter == 'source' ? template.inputs : template.outputs; + const selector = createMemoizedSelector(selectNodeTemplatesSlice, (nodeTemplates) => { + // If we have a connection in progress, we need to filter the node choices + const filteredNodeTemplates = fieldFilter + ? filter(nodeTemplates.templates, (template) => { + const handles = handleFilter === 'source' ? template.inputs : template.outputs; - return some(handles, (handle) => { - const sourceType = - handleFilter == 'source' ? fieldFilter : handle.type; - const targetType = - handleFilter == 'target' ? fieldFilter : handle.type; + return some(handles, (handle) => { + const sourceType = handleFilter === 'source' ? fieldFilter : handle.type; + const targetType = handleFilter === 'target' ? fieldFilter : handle.type; - return validateSourceAndTargetTypes(sourceType, targetType); - }); - }) - : map(nodeTemplates.templates); + return validateSourceAndTargetTypes(sourceType, targetType); + }); + }) + : map(nodeTemplates.templates); - const options: ComboboxOption[] = map( - filteredNodeTemplates, - (template) => { - return { - label: template.title, - value: template.type, - description: template.description, - tags: template.tags, - }; - } - ); + const options: ComboboxOption[] = map(filteredNodeTemplates, (template) => { + return { + label: template.title, + value: template.type, + description: template.description, + tags: template.tags, + }; + }); - //We only want these nodes if we're not filtered - if (fieldFilter === null) { - options.push({ - label: t('nodes.currentImage'), - value: 'current_image', - description: t('nodes.currentImageDescription'), - tags: ['progress'], - }); + //We only want these nodes if we're not filtered + if (fieldFilter === null) { + options.push({ + label: t('nodes.currentImage'), + value: 'current_image', + description: t('nodes.currentImageDescription'), + tags: ['progress'], + }); - options.push({ - label: t('nodes.notes'), - value: 'notes', - description: t('nodes.notesDescription'), - tags: ['notes'], - }); - } - - options.sort((a, b) => a.label.localeCompare(b.label)); - - return { options }; + options.push({ + label: t('nodes.notes'), + value: 'notes', + description: t('nodes.notesDescription'), + tags: ['notes'], + }); } - ); + + options.sort((a, b) => a.label.localeCompare(b.label)); + + return { options }; + }); const { options } = useAppSelector(selector); const isOpen = useAppSelector((s) => s.nodes.isAddNodePopoverOpen); @@ -205,12 +181,7 @@ const AddNodePopover = () => { initialFocusRef={inputRef} > - + { // Easiest to just keep track of the last mouse event for this particular feature const edgeUpdateMouseEvent = useRef(); - const onEdgeUpdateStart: NonNullable = - useCallback( - (e, edge, _handleType) => { - // update mouse event - edgeUpdateMouseEvent.current = e; - // always delete the edge when starting an updated - dispatch(edgeDeleted(edge.id)); - dispatch(edgeChangeStarted()); - }, - [dispatch] - ); + const onEdgeUpdateStart: NonNullable = useCallback( + (e, edge, _handleType) => { + // update mouse event + edgeUpdateMouseEvent.current = e; + // always delete the edge when starting an updated + dispatch(edgeDeleted(edge.id)); + dispatch(edgeChangeStarted()); + }, + [dispatch] + ); const onEdgeUpdate: OnEdgeUpdateFunc = useCallback( (_oldEdge, newConnection) => { @@ -214,24 +213,23 @@ export const Flow = memo(() => { [dispatch] ); - const onEdgeUpdateEnd: NonNullable = - useCallback( - (e, edge, _handleType) => { - // Handle the case where user begins a drag but didn't move the cursor - - // bc we deleted the edge, we need to add it back - if ( - // ignore touch events - !('touches' in e) && - edgeUpdateMouseEvent.current?.clientX === e.clientX && - edgeUpdateMouseEvent.current?.clientY === e.clientY - ) { - dispatch(edgeAdded(edge)); - } - // reset mouse event - edgeUpdateMouseEvent.current = undefined; - }, - [dispatch] - ); + const onEdgeUpdateEnd: NonNullable = useCallback( + (e, edge, _handleType) => { + // Handle the case where user begins a drag but didn't move the cursor - + // bc we deleted the edge, we need to add it back + if ( + // ignore touch events + !('touches' in e) && + edgeUpdateMouseEvent.current?.clientX === e.clientX && + edgeUpdateMouseEvent.current?.clientY === e.clientY + ) { + dispatch(edgeAdded(edge)); + } + // reset mouse event + edgeUpdateMouseEvent.current = undefined; + }, + [dispatch] + ); // #endregion diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/connectionLines/CustomConnectionLine.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/connectionLines/CustomConnectionLine.tsx index 7be6f1544b..61efcea06a 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/connectionLines/CustomConnectionLine.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/connectionLines/CustomConnectionLine.tsx @@ -9,27 +9,16 @@ import type { ConnectionLineComponentProps } from 'reactflow'; import { getBezierPath } from 'reactflow'; const selectStroke = createSelector(selectNodesSlice, (nodes) => - nodes.shouldColorEdges - ? getFieldColor(nodes.connectionStartFieldType) - : colorTokenToCssVar('base.500') + nodes.shouldColorEdges ? getFieldColor(nodes.connectionStartFieldType) : colorTokenToCssVar('base.500') ); const selectClassName = createSelector(selectNodesSlice, (nodes) => - nodes.shouldAnimateEdges - ? 'react-flow__custom_connection-path animated' - : 'react-flow__custom_connection-path' + nodes.shouldAnimateEdges ? 'react-flow__custom_connection-path animated' : 'react-flow__custom_connection-path' ); const pathStyles: CSSProperties = { opacity: 0.8 }; -const CustomConnectionLine = ({ - fromX, - fromY, - fromPosition, - toX, - toY, - toPosition, -}: ConnectionLineComponentProps) => { +const CustomConnectionLine = ({ fromX, fromY, fromPosition, toX, toY, toPosition }: ConnectionLineComponentProps) => { const stroke = useAppSelector(selectStroke); const className = useAppSelector(selectClassName); @@ -46,14 +35,7 @@ const CustomConnectionLine = ({ return ( - + ); }; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationCollapsedEdge.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationCollapsedEdge.tsx index 4c313d8f15..eae7970804 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationCollapsedEdge.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationCollapsedEdge.tsx @@ -1,4 +1,4 @@ -import { Badge, Flex } from '@invoke-ai/ui'; +import { Badge, Flex } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { useChakraThemeTokens } from 'common/hooks/useChakraThemeTokens'; import { memo, useMemo } from 'react'; @@ -23,14 +23,7 @@ const InvocationCollapsedEdge = ({ targetHandleId, }: EdgeProps<{ count: number }>) => { const selector = useMemo( - () => - makeEdgeSelector( - source, - sourceHandleId, - target, - targetHandleId, - selected - ), + () => makeEdgeSelector(source, sourceHandleId, target, targetHandleId, selected), [selected, source, sourceHandleId, target, targetHandleId] ); @@ -68,12 +61,7 @@ const InvocationCollapsedEdge = ({ transform={`translate(-50%, -50%) translate(${labelX}px,${labelY}px)`} className="nodrag nopan" > - + {data.count} diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationDefaultEdge.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationDefaultEdge.tsx index 15e0f851ca..0a18c2a959 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationDefaultEdge.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/edges/InvocationDefaultEdge.tsx @@ -21,14 +21,7 @@ const InvocationDefaultEdge = ({ targetHandleId, }: EdgeProps) => { const selector = useMemo( - () => - makeEdgeSelector( - source, - sourceHandleId, - target, - targetHandleId, - selected - ), + () => makeEdgeSelector(source, sourceHandleId, target, targetHandleId, selected), [source, sourceHandleId, target, targetHandleId, selected] ); diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/edges/util/makeEdgeSelector.ts b/invokeai/frontend/web/src/features/nodes/components/flow/edges/util/makeEdgeSelector.ts index 89d9e514ff..4bfc588e67 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/edges/util/makeEdgeSelector.ts +++ b/invokeai/frontend/web/src/features/nodes/components/flow/edges/util/makeEdgeSelector.ts @@ -16,18 +16,12 @@ export const makeEdgeSelector = ( const sourceNode = nodes.nodes.find((node) => node.id === source); const targetNode = nodes.nodes.find((node) => node.id === target); - const isInvocationToInvocationEdge = - isInvocationNode(sourceNode) && isInvocationNode(targetNode); + const isInvocationToInvocationEdge = isInvocationNode(sourceNode) && isInvocationNode(targetNode); const isSelected = sourceNode?.selected || targetNode?.selected || selected; - const sourceType = isInvocationToInvocationEdge - ? sourceNode?.data?.outputs[sourceHandleId || '']?.type - : undefined; + const sourceType = isInvocationToInvocationEdge ? sourceNode?.data?.outputs[sourceHandleId || '']?.type : undefined; - const stroke = - sourceType && nodes.shouldColorEdges - ? getFieldColor(sourceType) - : colorTokenToCssVar('base.500'); + const stroke = sourceType && nodes.shouldColorEdges ? getFieldColor(sourceType) : colorTokenToCssVar('base.500'); return { isSelected, diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx index 038370db9c..968136a3c2 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx @@ -1,4 +1,4 @@ -import { Flex, Image, Text } from '@invoke-ai/ui'; +import { Flex, Image, Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import IAIDndImage from 'common/components/IAIDndImage'; @@ -15,18 +15,14 @@ import { memo, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { NodeProps } from 'reactflow'; -const selector = createMemoizedSelector( - selectSystemSlice, - selectGallerySlice, - (system, gallery) => { - const imageDTO = gallery.selection[gallery.selection.length - 1]; +const selector = createMemoizedSelector(selectSystemSlice, selectGallerySlice, (system, gallery) => { + const imageDTO = gallery.selection[gallery.selection.length - 1]; - return { - imageDTO, - progressImage: system.denoiseProgress?.progress_image, - }; - } -); + return { + imageDTO, + progressImage: system.denoiseProgress?.progress_image, + }; +}); const CurrentImageNode = (props: NodeProps) => { const { progressImage, imageDTO } = useAppSelector(selector); @@ -34,13 +30,7 @@ const CurrentImageNode = (props: NodeProps) => { if (progressImage) { return ( - + ); } @@ -74,11 +64,7 @@ const Wrapper = (props: PropsWithChildren<{ nodeProps: NodeProps }>) => { }, []); const { t } = useTranslation(); return ( - + ) => { position="relative" flexDirection="column" > - + {t('nodes.currentImage')} - + {props.children} {isHovering && ( - + )} diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx index f798454be1..0147bcaed2 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNode.tsx @@ -1,4 +1,4 @@ -import { Flex, Grid, GridItem } from '@invoke-ai/ui'; +import { Flex, Grid, GridItem } from '@invoke-ai/ui-library'; import NodeWrapper from 'features/nodes/components/flow/nodes/common/NodeWrapper'; import { useAnyOrDirectInputFieldNames } from 'features/nodes/hooks/useAnyOrDirectInputFieldNames'; import { useConnectionInputFieldNames } from 'features/nodes/hooks/useConnectionInputFieldNames'; @@ -27,13 +27,7 @@ const InvocationNode = ({ nodeId, isOpen, label, type, selected }: Props) => { return ( - + {isOpen && ( <> { {inputConnectionFieldNames.map((fieldName, i) => ( - + ))} {outputFieldNames.map((fieldName, i) => ( - + ))} {inputAnyOrDirectFieldNames.map((fieldName) => ( - + ))} diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx index 0f21fd8c92..ddeb883d23 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx @@ -1,4 +1,4 @@ -import { Icon, Tooltip } from '@invoke-ai/ui'; +import { Icon, Tooltip } from '@invoke-ai/ui-library'; import { useNodeClassification } from 'features/nodes/hooks/useNodeClassification'; import type { Classification } from 'features/nodes/types/common'; import { memo } from 'react'; @@ -22,33 +22,26 @@ const InvocationNodeClassificationIcon = ({ nodeId }: Props) => { placement="top" shouldWrapChildren > - + ); }; export default memo(InvocationNodeClassificationIcon); -const ClassificationTooltipContent = memo( - ({ classification }: { classification: Classification }) => { - const { t } = useTranslation(); +const ClassificationTooltipContent = memo(({ classification }: { classification: Classification }) => { + const { t } = useTranslation(); - if (classification === 'beta') { - return t('nodes.betaDesc'); - } - - if (classification === 'prototype') { - return t('nodes.prototypeDesc'); - } - - return null; + if (classification === 'beta') { + return t('nodes.betaDesc'); } -); + + if (classification === 'prototype') { + return t('nodes.prototypeDesc'); + } + + return null; +}); ClassificationTooltipContent.displayName = 'ClassificationTooltipContent'; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx index abe4ca0856..1b93c0fdd3 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeFooter.tsx @@ -1,5 +1,5 @@ -import type { ChakraProps } from '@invoke-ai/ui'; -import { Flex, FormControlGroup } from '@invoke-ai/ui'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Flex, FormControlGroup } from '@invoke-ai/ui-library'; import { useHasImageOutput } from 'features/nodes/hooks/useHasImageOutput'; import { DRAG_HANDLE_CLASSNAME } from 'features/nodes/types/constants'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx index 99caba2df8..21ba769bfd 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx @@ -1,4 +1,4 @@ -import { Flex } from '@invoke-ai/ui'; +import { Flex } from '@invoke-ai/ui-library'; import NodeCollapseButton from 'features/nodes/components/flow/nodes/common/NodeCollapseButton'; import NodeTitle from 'features/nodes/components/flow/nodes/common/NodeTitle'; import InvocationNodeClassificationIcon from 'features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon'; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeInfoIcon.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeInfoIcon.tsx index 42fd120cd1..58e881860e 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeInfoIcon.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeInfoIcon.tsx @@ -1,4 +1,4 @@ -import { Flex, Icon, Text, Tooltip } from '@invoke-ai/ui'; +import { Flex, Icon, Text, Tooltip } from '@invoke-ai/ui-library'; import { compare } from 'compare-versions'; import { useNodeData } from 'features/nodes/hooks/useNodeData'; import { useNodeNeedsUpdate } from 'features/nodes/hooks/useNodeNeedsUpdate'; @@ -16,18 +16,8 @@ const InvocationNodeInfoIcon = ({ nodeId }: Props) => { const needsUpdate = useNodeNeedsUpdate(nodeId); return ( - } - placement="top" - shouldWrapChildren - > - + } placement="top" shouldWrapChildren> + ); }; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeStatusIndicator.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeStatusIndicator.tsx index b96edf9b2a..3138cb32fe 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeStatusIndicator.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeStatusIndicator.tsx @@ -1,13 +1,5 @@ -import type { SystemStyleObject } from '@invoke-ai/ui'; -import { - Badge, - CircularProgress, - Flex, - Icon, - Image, - Text, - Tooltip, -} from '@invoke-ai/ui'; +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Badge, CircularProgress, Flex, Icon, Image, Text, Tooltip } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import { selectNodesSlice } from 'features/nodes/store/nodesSlice'; @@ -16,11 +8,7 @@ import type { NodeExecutionState } from 'features/nodes/types/invocation'; import { zNodeStatus } from 'features/nodes/types/invocation'; import { memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { - PiCheckBold, - PiDotsThreeOutlineFill, - PiWarningBold, -} from 'react-icons/pi'; +import { PiCheckBold, PiDotsThreeOutlineFill, PiWarningBold } from 'react-icons/pi'; type Props = { nodeId: string; @@ -37,11 +25,7 @@ const circleStyles: SystemStyleObject = { const InvocationNodeStatusIndicator = ({ nodeId }: Props) => { const selectNodeExecutionState = useMemo( - () => - createMemoizedSelector( - selectNodesSlice, - (nodes) => nodes.nodeExecutionStates[nodeId] - ), + () => createMemoizedSelector(selectNodesSlice, (nodes) => nodes.nodeExecutionStates[nodeId]), [nodeId] ); @@ -52,17 +36,8 @@ const InvocationNodeStatusIndicator = ({ nodeId }: Props) => { } return ( - } - placement="top" - > - + } placement="top"> + @@ -85,13 +60,7 @@ const TooltipLabel = memo(({ nodeExecutionState }: TooltipLabelProps) => { if (progressImage) { return ( - + {progress !== null && ( {Math.round(progress * 100)}% @@ -132,23 +101,11 @@ type StatusIconProps = { const StatusIcon = memo((props: StatusIconProps) => { const { progress, status } = props.nodeExecutionState; if (status === zNodeStatus.enum.PENDING) { - return ( - - ); + return ; } if (status === zNodeStatus.enum.IN_PROGRESS) { return progress === null ? ( - + ) : ( { +const InvocationNodeUnknownFallback = ({ nodeId, isOpen, label, type, selected }: Props) => { const { t } = useTranslation(); const nodePack = useNodePack(nodeId); return ( diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeWrapper.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeWrapper.tsx index b2ee81c292..d7a5dc3895 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeWrapper.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeWrapper.tsx @@ -13,10 +13,7 @@ const InvocationNodeWrapper = (props: NodeProps) => { const { id: nodeId, type, isOpen, label } = data; const hasTemplateSelector = useMemo( - () => - createSelector(selectNodeTemplatesSlice, (nodeTemplates) => - Boolean(nodeTemplates.templates[type]) - ), + () => createSelector(selectNodeTemplatesSlice, (nodeTemplates) => Boolean(nodeTemplates.templates[type])), [type] ); @@ -24,25 +21,11 @@ const InvocationNodeWrapper = (props: NodeProps) => { if (!hasTemplate) { return ( - + ); } - return ( - - ); + return ; }; export default memo(InvocationNodeWrapper); diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/NotesTextarea.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/NotesTextarea.tsx index 6e092b0448..ed5031d435 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/NotesTextarea.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/NotesTextarea.tsx @@ -1,4 +1,4 @@ -import { FormControl, FormLabel, Textarea } from '@invoke-ai/ui'; +import { FormControl, FormLabel, Textarea } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { useNodeData } from 'features/nodes/hooks/useNodeData'; import { nodeNotesChanged } from 'features/nodes/store/nodesSlice'; @@ -23,12 +23,7 @@ const NotesTextarea = ({ nodeId }: { nodeId: string }) => { return ( {t('nodes.notes')} -