mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-08-14 10:15:31 +02:00
Compare commits
653 Commits
Author | SHA1 | Date | |
---|---|---|---|
2c861c65d4 | |||
a59bac4b40 | |||
cf214bf367 | |||
75724797f7 | |||
d04aeb55ad | |||
47bd6dc6b8 | |||
5e0f525932 | |||
1f66daf2f3 | |||
ded9cb0358 | |||
04f201933b | |||
f5ec1cb3a4 | |||
6c23e3f534 | |||
e99d54d1f6 | |||
3c71200eb4 | |||
f124cf8318 | |||
9d2b944063 | |||
8e1ec5903b | |||
5cf763d51f | |||
3546859fe5 | |||
6530e45178 | |||
07f0036b2b | |||
5237f55a71 | |||
a108e5067d | |||
a4a24b1a1a | |||
ffe0eb1544 | |||
288e8a65f3 | |||
0ebfbca93e | |||
f22f57495e | |||
8786a9d21d | |||
f06a97d30b | |||
2329c47faf | |||
2967261acb | |||
64ff1ecbb6 | |||
8707f88c07 | |||
36846618ec | |||
0cb2f19e29 | |||
125a50ae87 | |||
9d37ea23f8 | |||
31617ae340 | |||
950614fb81 | |||
14bbd7b7ae | |||
257cd34101 | |||
ab6ec3a9b7 | |||
39814a89b6 | |||
24fbbf8aa8 | |||
338ceffa6d | |||
371e104b00 | |||
d5aba8eaf1 | |||
1d2b3a4ed8 | |||
f904945d40 | |||
027b2e1b88 | |||
d79eb5e1a6 | |||
f6651b03b5 | |||
5f880a179c | |||
ea03fd22db | |||
e252c9ac05 | |||
a212fb35c1 | |||
e561e4de0b | |||
1c3d5cd851 | |||
e59fbac761 | |||
745ea5fb05 | |||
fa16ca4eec | |||
d7757b8b03 | |||
98aefad249 | |||
a19ba40672 | |||
3983cb001f | |||
c17222dbe4 | |||
abd8c69395 | |||
a7fde73df4 | |||
78b464b404 | |||
aa21115e26 | |||
a39f845835 | |||
3fdd8d91e2 | |||
c13bccc7ae | |||
b4f7d6bf25 | |||
fa0c2f7138 | |||
453cc2a951 | |||
bd56795c62 | |||
2c54b7f289 | |||
cd5f847b55 | |||
a25544baea | |||
d1c9db874f | |||
f954542dda | |||
9fec7d236c | |||
67656accf8 | |||
64952a536c | |||
65e0d5f511 | |||
5a06946469 | |||
baef31b2c7 | |||
b9a12d1562 | |||
3f26d03166 | |||
1fed3ad532 | |||
929b245f5f | |||
0da6354825 | |||
716a28891d | |||
93a2e91694 | |||
4913dc1aad | |||
087df18fea | |||
058ce6fe82 | |||
087c10d52d | |||
18292e447c | |||
6c1dda47c0 | |||
ad1fc8f3d8 | |||
bca98269bb | |||
1bebaf933d | |||
166eb996a9 | |||
10fae34754 | |||
aa4d97e8df | |||
dbbb9d7877 | |||
82fda5cb03 | |||
3ff213b3e8 | |||
65587536ab | |||
ad31be8344 | |||
25815c81bf | |||
852a22f86d | |||
69c7f22053 | |||
75a964167a | |||
c5768c81e1 | |||
4eb2b818e7 | |||
f742aad810 | |||
e22b171b7b | |||
d061eb2c64 | |||
69aa115178 | |||
e175b87384 | |||
f216ee739a | |||
16d6644573 | |||
38afc6e6f8 | |||
8f1d214b12 | |||
51fb1a43de | |||
a86b6bfbd6 | |||
1176ddcc85 | |||
fa080e380c | |||
57c3acd9d8 | |||
302cf5b10b | |||
e2a9e81dbc | |||
b1cf7391ce | |||
9bc7521de0 | |||
a68ebd2b76 | |||
47f7c938ae | |||
842e7e559e | |||
67cca3bc00 | |||
90b1609d4e | |||
abbfae2fc0 | |||
b52b854270 | |||
58b759f652 | |||
74ca756a53 | |||
a62ee7850b | |||
d3a90ccc0d | |||
46b13ee664 | |||
cfa6dc7836 | |||
f969bfa7be | |||
3576214920 | |||
f964fe3750 | |||
e86a883d0a | |||
82d764000a | |||
749c72e6a6 | |||
c3129a40f1 | |||
d04aa89812 | |||
d5f854d376 | |||
63dcb8cfe1 | |||
6c57fa078b | |||
c3cc75feff | |||
d2e6011089 | |||
5a18144366 | |||
8a0a22bfb0 | |||
950b226374 | |||
74e64a4387 | |||
59e4c1cf79 | |||
045ad78bb9 | |||
c0350e5be7 | |||
ea7006eec4 | |||
2b3e38f77e | |||
d04fe5d582 | |||
17ab4caa5e | |||
976bc727dd | |||
484e53cc08 | |||
b09b80933d | |||
93b3419737 | |||
19290fe467 | |||
d2f679030b | |||
053bce7a8e | |||
2f208832a9 | |||
268d7495cc | |||
ce16e61e63 | |||
f92bca58fa | |||
83d541b60d | |||
965efc3a13 | |||
d656c34bd4 | |||
7f151cbeba | |||
bc2f9204e9 | |||
a922a93016 | |||
eb596ba866 | |||
2208545612 | |||
f08a875cd2 | |||
d492d3f738 | |||
c687091ce9 | |||
eb994716e6 | |||
70acc8a7c0 | |||
bf97781232 | |||
099727d671 | |||
6229cdb1ba | |||
b7a663ed20 | |||
3bd97352ba | |||
33e25d9241 | |||
fc11018158 | |||
5e22360cb1 | |||
840348b4eb | |||
450fb2553c | |||
cf04738594 | |||
03757632cf | |||
e818f5a93f | |||
ab9b08770a | |||
40df8b68ad | |||
9f5202fee3 | |||
902ccbd203 | |||
4675da4d16 | |||
86da27a7a1 | |||
fc2a6567da | |||
7c611d9b62 | |||
784c7465d1 | |||
301af7bd7a | |||
09c11a385d | |||
ef6f491d94 | |||
9dcef00fbb | |||
e781e5dd43 | |||
d3e672d811 | |||
dad1554ec2 | |||
30bf96c6cd | |||
a8c16e39b8 | |||
79a7cd2938 | |||
26562e445f | |||
0b678b1f16 | |||
79b5e85b15 | |||
2432491bfc | |||
a09ce3e026 | |||
c52fc843f6 | |||
02240bda25 | |||
0185ef7c83 | |||
7d29b9901c | |||
ae553dfed3 | |||
71c6beadb4 | |||
d939629c09 | |||
0a569146a8 | |||
d5a012d49f | |||
22a11769fa | |||
7dc7ba9977 | |||
fa4059a4b9 | |||
7f4786f9dd | |||
5a6e7a46d1 | |||
9f90749f99 | |||
0dfaf9159d | |||
5d8bda1178 | |||
9ad1e0d529 | |||
389e3397ec | |||
284b95213e | |||
952854f64e | |||
554650c18d | |||
01a2fa7c2d | |||
1257e34487 | |||
a45743f443 | |||
7d03719816 | |||
7c5bbca2fa | |||
cf313939aa | |||
873d4bd3f2 | |||
f43f3fc84b | |||
0e1fed86ba | |||
3fb5d886dc | |||
b57cd8d5c2 | |||
5c1bbc08ca | |||
6ba32b95f3 | |||
d3df113fb0 | |||
06c2ab045a | |||
6d43e0951c | |||
ec14429238 | |||
1dc2c6f183 | |||
984b8f7e6f | |||
0f8448b2c0 | |||
088c546bee | |||
20fff378f0 | |||
4994a7ac85 | |||
a959c69d32 | |||
39244568be | |||
c8fc0bb4f5 | |||
654ad5c71f | |||
7b9d18caea | |||
8d347efec2 | |||
85de6dd52e | |||
c024b39c8b | |||
1f0db48487 | |||
2bc5f475f4 | |||
5abf4c99de | |||
137e519b66 | |||
dcb27e7de8 | |||
d4d5b5a75c | |||
a83b3f8408 | |||
da9af8673f | |||
1b4ba3b396 | |||
eb2f1cbc9e | |||
28f58f72dd | |||
81389401df | |||
c618c5c5f0 | |||
0eaff4c626 | |||
9783c1052d | |||
f732fa9736 | |||
0c2d227da1 | |||
a281efef04 | |||
538dcec348 | |||
0d38c8ae8f | |||
967c1a2da9 | |||
f3da326b77 | |||
153a6e2cb0 | |||
95f37b9d36 | |||
60c37a1fc7 | |||
615c61e230 | |||
ae40b6ba8c | |||
d482427e0d | |||
c41baf3aeb | |||
dd7cb74edc | |||
4eed2c7582 | |||
100e830e04 | |||
af28d82ebc | |||
6285980f98 | |||
a5d19cd31f | |||
9c9998b468 | |||
011eb55a53 | |||
189d31cc29 | |||
d178f3d1b9 | |||
6e9d73ec64 | |||
8d1adf4f80 | |||
d0b7f58e7c | |||
19d24e5644 | |||
461f618b8a | |||
fc875651d3 | |||
5ff14d1fed | |||
80c9c1bb05 | |||
a111d9b18a | |||
df14913c67 | |||
b6c6fef770 | |||
1a2f37b0ec | |||
6f3c662783 | |||
3772137c8f | |||
0d62123a0b | |||
28fed6281f | |||
1ec95d42ba | |||
8adf965d0b | |||
026dd38480 | |||
338c2243e3 | |||
e8d61225f5 | |||
cc356ce67d | |||
364e364429 | |||
46a46877ed | |||
5ee05e3aaa | |||
5568a09f49 | |||
1199c431ff | |||
2c1a897c4e | |||
305f2fa448 | |||
b051685727 | |||
344dd92c85 | |||
4167c65acf | |||
cd6d49860f | |||
8a10fcf7ea | |||
7580bb21c3 | |||
62102236a2 | |||
3b5f96a133 | |||
ce2b711b1f | |||
667fb438cb | |||
7befa94e6d | |||
32d7835119 | |||
726abf6e65 | |||
c154a4bdc8 | |||
88ef1a3c5b | |||
5453925e26 | |||
537e314b49 | |||
ccb7a553c2 | |||
1696a5c8e1 | |||
816cf8f702 | |||
e8167541af | |||
329360aa5b | |||
eb1a276e60 | |||
a53bac1a94 | |||
93bf93d3a1 | |||
4174c8c25c | |||
48a88a8624 | |||
1442748f58 | |||
d17e216f91 | |||
56ed4fe6f2 | |||
9a71e9ba86 | |||
ef478a4a9e | |||
1bd7d40716 | |||
807e9573fb | |||
849d1d7ebd | |||
3fe2545228 | |||
090dfff730 | |||
f94e9449d5 | |||
d8753adc4e | |||
2e17ea99e2 | |||
c4daf8524e | |||
9d16898926 | |||
f4bcc1f2e5 | |||
63e8614ace | |||
5d686b146d | |||
e85758dc5f | |||
d08f090800 | |||
8554473c21 | |||
01fb1bde8b | |||
29e32ffc42 | |||
88bd60a083 | |||
48b7b725b0 | |||
8d8c932d8c | |||
253d355bd2 | |||
e287df1320 | |||
bae0bec1cc | |||
602686a5d2 | |||
af05d94198 | |||
5fa3a7ca44 | |||
9609350789 | |||
9c1e73ffff | |||
50741c70c0 | |||
fc8660df78 | |||
4e5ddca3bd | |||
3bdc90451a | |||
a036b2981a | |||
8fae83dab7 | |||
083f9dd29b | |||
7d5fabbd25 | |||
105f071847 | |||
ef68e5b13d | |||
21afe077d7 | |||
48222ce44c | |||
0922ba938c | |||
3fc66ec525 | |||
44191cd908 | |||
0da0c6bd77 | |||
b5f6e9d01b | |||
6098b196dc | |||
0922349344 | |||
53cdeeff03 | |||
fcdb086daf | |||
d2d9c2dd0f | |||
4241fb9386 | |||
cfd6751777 | |||
5e461e9b6b | |||
946dfdf7b8 | |||
4da9843479 | |||
eccb3c643d | |||
bfa5a51ce8 | |||
9066ad6cdf | |||
f7b513dff2 | |||
3de5f10d52 | |||
07429a862c | |||
2f2bddf020 | |||
ad03adaebf | |||
ac7a5488ee | |||
6de93d4fbb | |||
8a312f76c5 | |||
4a956b5a55 | |||
83d6c3ba88 | |||
52daf6b864 | |||
c8420e152f | |||
1dff19af26 | |||
a1e2eca802 | |||
48b63a26c8 | |||
b23bc4a5b6 | |||
940236b4a4 | |||
b6ef18b0d8 | |||
372484f976 | |||
086cf67e93 | |||
3c8692d06c | |||
efffca83fe | |||
04fe81e001 | |||
d2215c2ba9 | |||
89b1b6e242 | |||
e476d68848 | |||
da8835bc77 | |||
f170c2611c | |||
351b17d1d9 | |||
14e88706df | |||
926e3e2712 | |||
c39043fb9d | |||
578b3ba4f4 | |||
5b0b582039 | |||
e24be913e5 | |||
4d3358ba66 | |||
ffe40fa3a3 | |||
87f93b34a3 | |||
03bd9a5731 | |||
cb82170187 | |||
5b9e16af83 | |||
7b1b2a4bef | |||
1f1a0b7b53 | |||
320acfae89 | |||
1c171d0f12 | |||
22bf3618ea | |||
5f1593f4d0 | |||
9af75bf9b2 | |||
344fa729a5 | |||
33d3d90a93 | |||
24dfc09f35 | |||
e533bc0847 | |||
306333ceba | |||
e96312b470 | |||
fb60b4bca7 | |||
0612e4429d | |||
ee80aa26db | |||
a45e667e9c | |||
1b4a2369bb | |||
224483f6ac | |||
c61574b782 | |||
c92129ac63 | |||
6c71d95932 | |||
e859f5c7a1 | |||
dc402f5f0e | |||
188894c837 | |||
70f99a70a5 | |||
fb4fbd23d8 | |||
f58b2383b9 | |||
05caf1fe28 | |||
704486abc2 | |||
1ec023b435 | |||
fd21eeb477 | |||
edf2b2df6f | |||
9ce338622c | |||
2b35529cbd | |||
554b67a2f0 | |||
012243a880 | |||
d4a348a2b2 | |||
1d4c5cc96f | |||
41bfb96b6b | |||
994d62ac65 | |||
7c72608e1c | |||
2edc06c662 | |||
cb4d66d6fe | |||
f80602b51a | |||
58d8a5ce46 | |||
72a65218be | |||
1b0d5b710e | |||
2a25ac0847 | |||
9aefdf35a1 | |||
231961c017 | |||
ee621fa091 | |||
a69a04cfb6 | |||
b1aed344c7 | |||
3e08d665c7 | |||
4a94c86433 | |||
d4878f6ed3 | |||
d94719ea02 | |||
982b5221b1 | |||
cbdf03450d | |||
7625e591fe | |||
8fdb1e7ec9 | |||
d3b28c42e6 | |||
1b32423881 | |||
7de699c7fa | |||
e9f9670eb5 | |||
3d4e961320 | |||
db2fb33d53 | |||
ff3db04ab7 | |||
c7f6763c48 | |||
b1dd4069db | |||
58c647d433 | |||
333ea4aa53 | |||
3ad59da2a9 | |||
2d9b211eeb | |||
4f5a352985 | |||
6ae3b77c2f | |||
4a7260b1be | |||
f91c77bdc6 | |||
476e938d23 | |||
1ec9d986bb | |||
4b88cfa51a | |||
bc56226a28 | |||
a6e5474fdb | |||
8c7ca2c34d | |||
91fccc6691 | |||
93d1737357 | |||
5ba1ae9ae4 | |||
8cb408bc6e | |||
197a89a37a | |||
d336ead3b1 | |||
662644663e | |||
4c7819effb | |||
8b5b9ee8f1 | |||
89b911a9dc | |||
b673e216b6 | |||
a1b2f0ccf1 | |||
f269facf9d | |||
5a36d280d7 | |||
c39563b123 | |||
548149de8e | |||
d6d4ce0ac4 | |||
83b0239791 | |||
d1fa13d67a | |||
3abd570678 | |||
b0b0781bd7 | |||
1aa28ddee1 | |||
09b50badb1 | |||
7060108a8b | |||
e6f0d5bf44 | |||
399642f958 | |||
781effc34e | |||
324c8f8146 | |||
27e372e38f | |||
87122ce211 | |||
c0c6675423 | |||
fa4aeb5261 | |||
4e51eeb998 | |||
a27c3f09b3 | |||
3e5f117066 | |||
3753fb3ea4 | |||
d3e49cf1e9 | |||
ffcf46a371 | |||
fc5eedbef5 | |||
d78b6c4445 | |||
6e056bb337 | |||
b5c2c1009c | |||
b54029a04a | |||
e30aca7531 | |||
866722b68f | |||
d93f3468d3 | |||
83032e858a | |||
6855e314b3 | |||
2c4a8619a8 | |||
3247d83252 | |||
109ff2d8a5 | |||
48797d12eb | |||
abe66d8af0 | |||
58c9b70b26 | |||
996643bde8 | |||
68dd9a29e8 | |||
68c4b55945 | |||
bab86c9ce2 | |||
5f24e4d705 | |||
66c7b3fcb2 | |||
1ffe29c657 | |||
6b7d4877e6 | |||
80826eb500 | |||
11962facde | |||
c7eccfd804 | |||
ad617e0deb | |||
7ae70d5a4d | |||
62d1a0291e | |||
883dc72fc6 | |||
65b2e9633c | |||
3b923e0d37 | |||
4938cb9bbc | |||
a208564f06 | |||
6c6ca4daf4 | |||
1024da601d | |||
55d05ee590 | |||
66f39e070b | |||
252681001e | |||
a39014b3b1 | |||
bccf7e3f69 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1 +0,0 @@
|
||||
* text=auto eol=lf
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -2,10 +2,4 @@ __pycache__
|
||||
installer
|
||||
installer.tar
|
||||
dist
|
||||
|
||||
# built code for the front end
|
||||
!/ui/frontend/dist
|
||||
ui/frontend/.idea/*
|
||||
ui/frontend/build_src/.idea/*
|
||||
|
||||
.idea/*
|
||||
|
@ -13,12 +13,11 @@ If you would like to contribute to this project, there is a discord for dicussio
|
||||
This is in-flux, but one way to get a development environment running for editing the UI of this project is:
|
||||
(swap `.sh` or `.bat` in instructions depending on your environment, and be sure to adjust any paths to match where you're working)
|
||||
|
||||
1) `git clone` the repository, e.g. to `/projects/stable-diffusion-ui-repo`
|
||||
2) Download the pre-built end user archive from the link on github, and extract it, e.g. to `/projects/stable-diffusion-ui-archive`
|
||||
3) `cd /projects/stable-diffusion-ui-archive` and run the script to set up and start the project, e.g. `start.sh`
|
||||
4) Check you can view and generate images on `localhost:9000`
|
||||
5) Close the server, and edit `/projects/stable-diffusion-ui-archive/scripts/on_env_start.sh`
|
||||
6) Comment out the lines near the bottom that copies the `files/ui` folder, e.g:
|
||||
1) Install the project to a new location using the [usual installation process](https://github.com/cmdr2/stable-diffusion-ui#installation), e.g. to `/projects/stable-diffusion-ui-archive`
|
||||
2) Start the newly installed project, and check that you can view and generate images on `localhost:9000`
|
||||
3) Next, please clone the project repository using `git clone` (e.g. to `/projects/stable-diffusion-ui-repo`)
|
||||
4) Close the server (started in step 2), and edit `/projects/stable-diffusion-ui-archive/scripts/on_env_start.sh` (or `on_env_start.bat`)
|
||||
5) Comment out the lines near the bottom that copies the `files/ui` folder, e.g:
|
||||
|
||||
for `.sh`
|
||||
```
|
||||
@ -33,13 +32,13 @@ REM @xcopy sd-ui-files\ui ui /s /i /Y
|
||||
REM @copy sd-ui-files\scripts\on_sd_start.bat scripts\ /Y
|
||||
REM @copy "sd-ui-files\scripts\Start Stable Diffusion UI.cmd" . /Y
|
||||
```
|
||||
7) Comment out the line at the top of `/projects/stable-diffusion-ui-archive/scripts/on_sd_start.sh` that copies `on_env_start`. For e.g. `@copy sd-ui-files\scripts\on_env_start.bat scripts\ /Y`
|
||||
6) Next, comment out the line at the top of `/projects/stable-diffusion-ui-archive/scripts/on_sd_start.sh` (or `on_sd_start.bat`) that copies `on_env_start`. For e.g. `@rem @copy sd-ui-files\scripts\on_env_start.bat scripts\ /Y`
|
||||
8) Delete the current `ui` folder at `/projects/stable-diffusion-ui-archive/ui`
|
||||
9) Now make a symlink between the repository clone (where you will be making changes) and this archive (where you will be running stable diffusion):
|
||||
`ln -s /projects/stable-diffusion-ui-repo/ui /projects/stable-diffusion-ui-archive/ui`
|
||||
or for Windows
|
||||
`mklink /D \projects\stable-diffusion-ui-archive\ui \projects\stable-diffusion-ui-repo\ui` (link name first, source repo dir second)
|
||||
9) Run the archive again `start.sh` and ensure you can still use the UI.
|
||||
`mklink /J \projects\stable-diffusion-ui-archive\ui \projects\stable-diffusion-ui-repo\ui` (link name first, source repo dir second)
|
||||
9) Run the project again (like in step 2) and ensure you can still use the UI.
|
||||
10) Congrats, now any changes you make in your repo `ui` folder are linked to this running archive of the app and can be previewed in the browser.
|
||||
|
||||
Check the `ui/frontend/build/README.md` for instructions on running and building the React code.
|
||||
@ -47,9 +46,5 @@ Check the `ui/frontend/build/README.md` for instructions on running and building
|
||||
## Development environment for Installer changes
|
||||
Build the Windows installer using Windows, and the Linux installer using Linux. Don't mix the two, and don't use WSL. An Ubuntu VM is fine for building the Linux installer on a Windows host.
|
||||
|
||||
1. Install Miniconda 3 or Anaconda.
|
||||
2. Install `conda install -c conda-forge -y conda-pack`
|
||||
3. Open the Anaconda Prompt. Do not use WSL if you're building for Windows.
|
||||
4. Run `build.bat` or `./build.sh` depending on whether you're in Windows or Linux.
|
||||
5. Compress the `stable-diffusion-ui` folder created inside the `dist` folder. Make a `zip` for Windows, and `tar.xz` for Linux (smaller files, and Linux users already have tar).
|
||||
6. Make a new GitHub release and upload the Windows and Linux installer builds.
|
||||
1. Run `build.bat` or `./build.sh` depending on whether you're in Windows or Linux.
|
||||
2. Make a new GitHub release and upload the Windows and Linux installer builds created inside the `dist` folder.
|
||||
|
113
README.md
113
README.md
@ -1,48 +1,77 @@
|
||||
# Stable Diffusion UI v2
|
||||
### A simple 1-click way to install and use [Stable Diffusion](https://github.com/CompVis/stable-diffusion) on your own computer. No dependencies or technical knowledge required.
|
||||
# Stable Diffusion UI
|
||||
### Easiest way to install and use [Stable Diffusion](https://github.com/CompVis/stable-diffusion) on your own computer. No dependencies or technical knowledge required. 1-click install, powerful features.
|
||||
|
||||
[](https://discord.com/invite/u9yhsFmEkB) (for support, and development discussion) | [Troubleshooting guide for common problems](Troubleshooting.md)
|
||||
|
||||
----
|
||||
|
||||
## Step 1: Download the installer
|
||||
|
||||
<p float="left">
|
||||
<a href="#installation"><img src="https://github.com/cmdr2/stable-diffusion-ui/raw/develop/media/download-win.png" width="200" /></a>
|
||||
<a href="#installation"><img src="https://github.com/cmdr2/stable-diffusion-ui/raw/develop/media/download-linux.png" width="200" /></a>
|
||||
</p>
|
||||
|
||||
[](https://discord.com/invite/u9yhsFmEkB) (for support, and development discussion) | [Troubleshooting guide for common problems](Troubleshooting.md)
|
||||
## Step 2: Run the program
|
||||
- On Windows: Double-click `Start Stable Diffusion UI.cmd`
|
||||
- On Linux: Run `./start.sh` in a terminal
|
||||
|
||||
️🔥🎉 **New!** Task Queue, Negative Prompt, Live Preview, More Samplers, In-Painting, Face Correction (GFPGAN) and Upscaling (RealESRGAN) have been added!
|
||||
## Step 3: There is no step 3!
|
||||
It's simple to get started. You don't need to install or struggle with Python, Anaconda, Docker etc.
|
||||
|
||||
This distribution currently uses Stable Diffusion 1.4. Once the model for 1.5 becomes publicly available, the model in this distribution will be updated.
|
||||
The installer will take care of whatever is needed. A friendly [Discord community](https://discord.com/invite/u9yhsFmEkB) will help you if you face any problems.
|
||||
|
||||
# Features in the new v2 Version:
|
||||
----
|
||||
|
||||
# Easy for new users, powerful features for advanced users
|
||||
### Features:
|
||||
- **No Dependencies or Technical Knowledge Required**: 1-click install for Windows 10/11 and Linux. *No dependencies*, no need for WSL or Docker or Conda or technical setup. Just download and run!
|
||||
- **Face Correction (GFPGAN) and Upscaling (RealESRGAN)**
|
||||
- **In-Painting**
|
||||
- **Clutter-free UI**: a friendly and simple UI, while providing a lot of powerful features
|
||||
- Supports "*Text to Image*" and "*Image to Image*"
|
||||
- **Custom Models**: Use your own `.ckpt` file, by placing it inside the `models/stable-diffusion` folder!
|
||||
- **Live Preview**: See the image as the AI is drawing it
|
||||
- **Task Queue**: Queue up all your ideas, without waiting for the current task to finish
|
||||
- **Negative Prompt**: Specify aspects of the image to *remove*.
|
||||
- **Lots of Samplers:** ddim, plms, heun, euler, euler_a, dpm2, dpm2_a, lms
|
||||
- **In-Painting**: Specify areas of your image to paint into
|
||||
- **Face Correction (GFPGAN) and Upscaling (RealESRGAN)**
|
||||
- **Image Modifiers**: A library of *modifier tags* like *"Realistic"*, *"Pencil Sketch"*, *"ArtStation"* etc. Experiment with various styles quickly.
|
||||
- **New UI**: with cleaner design
|
||||
- **Waifu Model Support**: Just replace the `stable-diffusion\sd-v1-4.ckpt` file after installation with the Waifu model
|
||||
- Supports "*Text to Image*" and "*Image to Image*"
|
||||
- **Loopback**: Use the output image as the input image for the next img2img task
|
||||
- **Negative Prompt**: Specify aspects of the image to *remove*.
|
||||
- **Attention/Emphasis:** () in the prompt increases the model's attention to enclosed words, and [] decreases it
|
||||
- **Weighted Prompts:** Use weights for specific words in your prompt to change their importance, e.g. `red:2.4 dragon:1.2`
|
||||
- **Prompt Matrix:** (in beta) Quickly create multiple variations of your prompt, e.g. `a photograph of an astronaut riding a horse | illustration | cinematic lighting`
|
||||
- **Lots of Samplers:** ddim, plms, heun, euler, euler_a, dpm2, dpm2_a, lms
|
||||
- **Multiple Prompts File:** Queue multiple prompts by entering one prompt per line, or by running a text file
|
||||
- **NSFW Setting**: A setting in the UI to control *NSFW content*
|
||||
- **JPEG/PNG output**
|
||||
- **Save generated images to disk**
|
||||
- **Use CPU setting**: If you don't have a compatible graphics card, but still want to run it on your CPU.
|
||||
- **Auto-updater**: Gets you the latest improvements and bug-fixes to a rapidly evolving project.
|
||||
- **Low Memory Usage**: Creates 512x512 images with less than 4GB of VRAM!
|
||||
- **Developer Console**: A developer-mode for those who want to modify their Stable Diffusion code, and edit the conda environment.
|
||||
|
||||

|
||||
### Easy for new users:
|
||||

|
||||
|
||||
### Powerful features for advanced users:
|
||||

|
||||
|
||||
### Live Preview
|
||||
Useful for judging (and stopping) an image quickly, without waiting for it to finish rendering.
|
||||
|
||||
## Live Preview
|
||||

|
||||
|
||||
### Task Queue
|
||||

|
||||
|
||||
# System Requirements
|
||||
1. Windows 10/11, or Linux. Experimental support for Mac is coming soon.
|
||||
2. An NVIDIA graphics card, preferably with 4GB or more of VRAM. But if you don't have a compatible graphics card, you can still use it with a "Use CPU" setting. It'll be very slow, but it should still work.
|
||||
2. An NVIDIA graphics card, preferably with 4GB or more of VRAM. If you don't have a compatible graphics card, it'll automatically run in the slower "CPU Mode".
|
||||
3. Minimum 8 GB of RAM and 25GB of disk space.
|
||||
|
||||
You do not need anything else. You do not need WSL, Docker or Conda. The installer will take care of it.
|
||||
You don't need to install or struggle with Python, Anaconda, Docker etc. The installer will take care of whatever is needed.
|
||||
|
||||
# Installation
|
||||
1. **Download** [for Windows](https://github.com/cmdr2/stable-diffusion-ui/releases/download/v2.16/stable-diffusion-ui-win64.zip) or [for Linux](https://github.com/cmdr2/stable-diffusion-ui/releases/download/v2.16/stable-diffusion-ui-linux.tar.xz).
|
||||
1. **Download** [for Windows](https://github.com/cmdr2/stable-diffusion-ui/releases/download/v2.3.5/stable-diffusion-ui-windows.zip) or [for Linux](https://github.com/cmdr2/stable-diffusion-ui/releases/download/v2.3.5/stable-diffusion-ui-linux.zip).
|
||||
|
||||
2. **Extract**:
|
||||
- For Windows: After unzipping the file, please move the `stable-diffusion-ui` folder to your `C:` (or any drive like D:, at the top root level), e.g. `C:\stable-diffusion-ui`. This will avoid a common problem with Windows (file path length limits).
|
||||
@ -56,49 +85,19 @@ This will automatically install Stable Diffusion, set it up, and start the inter
|
||||
|
||||
**To Uninstall:** Just delete the `stable-diffusion-ui` folder to uninstall all the downloaded packages.
|
||||
|
||||
|
||||
# Usage
|
||||
Open http://localhost:9000 in your browser (after running step 3 previously). It may take a few moments for the back-end to be ready.
|
||||
|
||||
## With a text description
|
||||
1. Enter a text prompt, like `a photograph of an astronaut riding a horse` in the textbox.
|
||||
2. Press `Make Image`. This will take some time, depending on your system's processing power.
|
||||
3. See the image generated using your prompt.
|
||||
|
||||
## With an image
|
||||
1. Click `Browse..` next to `Initial Image`. Select your desired image.
|
||||
2. An optional text prompt can help you further describe the kind of image you want to generate.
|
||||
3. Press `Make Image`. See the image generated using your prompt.
|
||||
|
||||
You can use Face Correction or Upscaling to improve the image further.
|
||||
|
||||
**Pro tip:** You can also click `Use as Input` on a generated image, to use it as the input image for your next generation. This can be useful for sequentially refining the generated image with a single click.
|
||||
|
||||
**Another tip:** Images with the same aspect ratio of your generated image work best. E.g. 1:1 if you're generating images sized 512x512.
|
||||
|
||||
## Problems? Troubleshooting
|
||||
Please try the common [troubleshooting](Troubleshooting.md) steps. If that doesn't fix it, please ask on the [discord server](https://discord.com/invite/u9yhsFmEkB), or [file an issue](https://github.com/cmdr2/stable-diffusion-ui/issues).
|
||||
|
||||
# Image Settings
|
||||
You can also set the configuration like `seed`, `width`, `height`, `num_outputs`, `num_inference_steps` and `guidance_scale` using the 'show' button next to 'Image settings'.
|
||||
|
||||
Use the same `seed` number to get the same image for a certain prompt. This is useful for refining a prompt without losing the basic image design. Enable the `random images` checkbox to get random images.
|
||||
|
||||

|
||||
|
||||
# System Settings
|
||||
The system settings are reachable via the cogwheel symbol on the top right. It can be used to configure whether all generated images should
|
||||
saved be automically, or to tune the Stable Diffusion image generation.
|
||||
|
||||

|
||||
|
||||
# Image Modifiers
|
||||

|
||||
# How to use?
|
||||
Please use our [guide](https://github.com/cmdr2/stable-diffusion-ui/wiki/How-to-Use) to understand how to use the features in this UI.
|
||||
|
||||
# Bugs reports and code contributions welcome
|
||||
If there are any problems or suggestions, please feel free to ask on the [discord server](https://discord.com/invite/u9yhsFmEkB) or [file an issue](https://github.com/cmdr2/stable-diffusion-ui/issues).
|
||||
|
||||
Also, please feel free to submit a pull request, if you have any code contributions in mind. Join the [discord server](https://discord.com/invite/u9yhsFmEkB) for development-related discussions, and for helping other users.
|
||||
We could really use help on these aspects (click to view tasks that need your help):
|
||||
* [User Interface](https://github.com/users/cmdr2/projects/1/views/1)
|
||||
* [Engine](https://github.com/users/cmdr2/projects/3/views/1)
|
||||
* [Installer](https://github.com/users/cmdr2/projects/4/views/1)
|
||||
* [Documentation](https://github.com/users/cmdr2/projects/5/views/1)
|
||||
|
||||
If you have any code contributions in mind, please feel free to say Hi to us on the [discord server](https://discord.com/invite/u9yhsFmEkB). We use the Discord server for development-related discussions, and for helping users.
|
||||
|
||||
# Disclaimer
|
||||
The authors of this project are not responsible for any content generated using this interface.
|
||||
|
@ -1,75 +1 @@
|
||||
Common issues and their solutions. If these solutions don't work, please feel free to ask at the [discord server](https://discord.com/invite/u9yhsFmEkB) or [file an issue](https://github.com/cmdr2/stable-diffusion-ui/issues).
|
||||
|
||||
## RuntimeError: CUDA out of memory
|
||||
This can happen if your PC has less than 6GB of VRAM.
|
||||
|
||||
Try disabling the "Turbo mode" setting under "Advanced Settings", since that takes an additional 1 GB of VRAM (to increase the speed).
|
||||
|
||||
Additionally, a common reason for this error is that you're using an initial image larger than 768x768 pixels. Try using a smaller initial image.
|
||||
|
||||
Also try generating smaller sized images.
|
||||
|
||||
## basicsr module not found
|
||||
For Windows: Please download and extract basicsr from [here](https://github.com/cmdr2/stable-diffusion-ui/releases/download/v2.16/basicsr-win64.zip), and place the `basicsr` folder inside the `stable-diffusion-ui\stable-diffusion\env\lib\site-packages` folder. Then run the `Start Stable Diffusion UI.cmd` file again.
|
||||
|
||||
For Linux: Please contact on the [discord server](https://discord.com/invite/u9yhsFmEkB).
|
||||
|
||||
## No ldm found, or antlr4 or any other missing module, or ClobberError: This transaction has incompatible packages due to a shared path
|
||||
On Windows, please ensure that you had placed the `stable-diffusion-ui` folder after unzipping to the root of C: or D: (or any drive). For e.g. `C:\stable-diffusion-ui`. **Note:** This has to be done **before** you start the installation process. If you have already installed (and are facing this error), please delete the installed folder, and start fresh by unzipping and placing the folder at the top of your drive.
|
||||
|
||||
This error can also be caused if you already have conda/miniconda/anaconda installed, due to package conflicts. Please open your Anaconda Prompt, and run `conda clean --all` to clean up unused packages.
|
||||
|
||||
If nothing works, this could be due to a corrupted installation. Please try reinstalling this, by deleting the installed folder, and unzipping from the downloaded zip file.
|
||||
|
||||
## Killed uvicorn server:app --app-dir ... --port 9000 --host 0.0.0.0
|
||||
This happens if your PC ran out of RAM. Stable Diffusion requires a lot of RAM, and requires atleast 10 GB of RAM to work well. You can also try closing all other applications before running Stable Diffusion UI.
|
||||
|
||||
## Green image generated
|
||||
This usually happens if you're running NVIDIA 1650 or 1660 Super. To solve this, please close and run the Stable Diffusion command on your computer. If you're using the older Docker-based solution (v1), please upgrade to v2: https://github.com/cmdr2/stable-diffusion-ui/tree/v2#installation
|
||||
|
||||
If you're still seeing this error, please try enabling "Full Precision" under "Advanced Settings" in the Stable Diffusion UI.
|
||||
|
||||
## './docker-compose.yml' is invalid:
|
||||
> ERROR: The Compose file './docker-compose.yml' is invalid because:
|
||||
> services.stability-ai.deploy.resources.reservations value Additional properties are not allowed ('devices' was unexpected)
|
||||
|
||||
Please ensure you have `docker-compose` version 1.29 or higher. Check `docker-compose --version`, and if required [update it to 1.29](https://docs.docker.com/compose/install/). (Thanks [HVRyan](https://github.com/HVRyan))
|
||||
|
||||
## RuntimeError: Found no NVIDIA driver on your system:
|
||||
If you have an NVIDIA GPU and the latest [NVIDIA driver](http://www.nvidia.com/Download/index.aspx), please ensure that you've installed [nvidia-container-toolkit](https://stackoverflow.com/a/58432877). (Thanks [u/exintrovert420](https://www.reddit.com/user/exintrovert420/))
|
||||
|
||||
## Some other process is already running at port 9000 / port 9000 could not be bound
|
||||
You can override the port used. Please change `docker-compose.yml` inside the project directory, and update the line `9000:9000` to `1337:9000` (where 1337 is whichever port number you want).
|
||||
|
||||
After doing this, please restart your server, by running `./server restart`.
|
||||
|
||||
After this, you can access the server at `http://localhost:1337` (where 1337 is the new port you specified earlier).
|
||||
|
||||
## RuntimeError: CUDA error: unknown error
|
||||
Please ensure that you have an NVIDIA GPU and the latest [NVIDIA driver](http://www.nvidia.com/Download/index.aspx), and that you've installed [nvidia-container-toolkit](https://stackoverflow.com/a/58432877).
|
||||
|
||||
Also, if you are using WSL (Windows), please ensure you have the latest WSL kernel by running `wsl --shutdown` and then `wsl --update`. (Thanks [AndrWeisR](https://github.com/AndrWeisR))
|
||||
|
||||
# For support queries
|
||||
## Entering a conda environment in an existing installation
|
||||
This will give you an activated conda environment in the terminal, so you can run commands and force-install any packages, if required.
|
||||
|
||||
Users don't need to have the Anaconda Prompt installed to do this anymore, since the installer bundles a portable version of conda inside it. Just follow these steps.
|
||||
|
||||
**Windows:**
|
||||
1. Open the terminal: Press Win+R, type "cmd", and press "Run"
|
||||
2. Type `cd C:\stable-diffusion-ui` and press enter (or wherever you've installed it)
|
||||
3. Type `installer\Scripts\activate.bat` and press enter
|
||||
4. Type `cd stable-diffusion` and press enter
|
||||
5. Type `conda activate .\env` and press enter
|
||||
6. Type `python --version` and press enter. You should see 3.8.5.
|
||||
|
||||
**Windows:**
|
||||
1. Open the terminal
|
||||
2. Type `cd /path/to/stable-diffusion-ui` and press enter
|
||||
3. Type `installer/bin/activate` and press enter
|
||||
4. Type `cd stable-diffusion` and press enter
|
||||
5. Type `conda activate ./env` and press enter
|
||||
6. Type `python --version` and press enter. You should see 3.8.5.
|
||||
|
||||
This will give you an activated conda environment. To confirm, type `python --version` and press enter. You should see 3.8.5.
|
||||
Moved to https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting
|
||||
|
56
build.bat
56
build.bat
@ -8,40 +8,40 @@
|
||||
set /p answer=Are you a developer of this project (Y/N)?
|
||||
if /i "%answer:~,1%" NEQ "Y" exit /b
|
||||
|
||||
@set PYTHONNOUSERSITE=1
|
||||
mkdir dist\win\stable-diffusion-ui\scripts
|
||||
@REM mkdir dist\linux-mac\stable-diffusion-ui\scripts
|
||||
|
||||
@mkdir dist\stable-diffusion-ui
|
||||
@rem copy the installer files for Windows
|
||||
|
||||
@echo "Downloading components for the installer.."
|
||||
copy scripts\on_env_start.bat dist\win\stable-diffusion-ui\scripts\
|
||||
copy scripts\bootstrap.bat dist\win\stable-diffusion-ui\scripts\
|
||||
copy "scripts\Start Stable Diffusion UI.cmd" dist\win\stable-diffusion-ui\
|
||||
copy LICENSE dist\win\stable-diffusion-ui\
|
||||
copy "CreativeML Open RAIL-M License" dist\win\stable-diffusion-ui\
|
||||
copy "How to install and run.txt" dist\win\stable-diffusion-ui\
|
||||
echo. > dist\win\stable-diffusion-ui\scripts\install_status.txt
|
||||
|
||||
@call conda env create --prefix installer -f environment.yaml
|
||||
@call conda activate .\installer
|
||||
@rem copy the installer files for Linux and Mac
|
||||
|
||||
@echo "Creating a distributable package.."
|
||||
@REM copy scripts\on_env_start.sh dist\linux-mac\stable-diffusion-ui\scripts\
|
||||
@REM copy scripts\bootstrap.sh dist\linux-mac\stable-diffusion-ui\scripts\
|
||||
@REM copy scripts\start.sh dist\linux-mac\stable-diffusion-ui\
|
||||
@REM copy LICENSE dist\linux-mac\stable-diffusion-ui\
|
||||
@REM copy "CreativeML Open RAIL-M License" dist\linux-mac\stable-diffusion-ui\
|
||||
@REM copy "How to install and run.txt" dist\linux-mac\stable-diffusion-ui\
|
||||
@REM echo. > dist\linux-mac\stable-diffusion-ui\scripts\install_status.txt
|
||||
|
||||
@call conda install -c conda-forge -y conda-pack
|
||||
@call conda pack --n-threads -1 --prefix installer --format tar
|
||||
@rem make the zip
|
||||
|
||||
@cd dist\stable-diffusion-ui
|
||||
@mkdir installer
|
||||
cd dist\win
|
||||
call powershell Compress-Archive -Path stable-diffusion-ui -DestinationPath ..\stable-diffusion-ui-windows.zip
|
||||
cd ..\..
|
||||
|
||||
@call tar -xf ..\..\installer.tar -C installer
|
||||
@REM cd dist\linux-mac
|
||||
@REM call powershell Compress-Archive -Path stable-diffusion-ui -DestinationPath ..\stable-diffusion-ui-linux.zip
|
||||
@REM call powershell Compress-Archive -Path stable-diffusion-ui -DestinationPath ..\stable-diffusion-ui-mac.zip
|
||||
@REM cd ..\..
|
||||
|
||||
@mkdir scripts
|
||||
echo "Build ready. Upload the zip files inside the 'dist' folder."
|
||||
|
||||
@copy ..\..\scripts\on_env_start.bat scripts\
|
||||
@copy "..\..\scripts\Start Stable Diffusion UI.cmd" .
|
||||
@copy ..\..\LICENSE .
|
||||
@copy "..\..\CreativeML Open RAIL-M License" .
|
||||
@copy "..\..\How to install and run.txt" .
|
||||
@echo. > scripts\install_status.txt
|
||||
|
||||
@echo "Build ready. Zip the 'dist\stable-diffusion-ui' folder."
|
||||
|
||||
@echo "Cleaning up.."
|
||||
|
||||
@cd ..\..
|
||||
|
||||
@rmdir /s /q installer
|
||||
|
||||
@del installer.tar
|
||||
pause
|
||||
|
60
build.sh
60
build.sh
@ -11,45 +11,39 @@ case $yn in
|
||||
* ) exit;;
|
||||
esac
|
||||
|
||||
export PYTHONNOUSERSITE=1
|
||||
# mkdir -p dist/win/stable-diffusion-ui/scripts
|
||||
mkdir -p dist/linux-mac/stable-diffusion-ui/scripts
|
||||
|
||||
mkdir -p dist/stable-diffusion-ui
|
||||
# copy the installer files for Windows
|
||||
|
||||
echo "Downloading components for the installer.."
|
||||
# cp scripts/on_env_start.bat dist/win/stable-diffusion-ui/scripts/
|
||||
# cp scripts/bootstrap.bat dist/win/stable-diffusion-ui/scripts/
|
||||
# cp "scripts/Start Stable Diffusion UI.cmd" dist/win/stable-diffusion-ui/
|
||||
# cp LICENSE dist/win/stable-diffusion-ui/
|
||||
# cp "CreativeML Open RAIL-M License" dist/win/stable-diffusion-ui/
|
||||
# cp "How to install and run.txt" dist/win/stable-diffusion-ui/
|
||||
# echo "" > dist/win/stable-diffusion-ui/scripts/install_status.txt
|
||||
|
||||
source ~/miniconda3/etc/profile.d/conda.sh
|
||||
# copy the installer files for Linux and Mac
|
||||
|
||||
conda install -c conda-forge -y conda-pack
|
||||
cp scripts/on_env_start.sh dist/linux-mac/stable-diffusion-ui/scripts/
|
||||
cp scripts/bootstrap.sh dist/linux-mac/stable-diffusion-ui/scripts/
|
||||
cp scripts/functions.sh dist/linux-mac/stable-diffusion-ui/scripts/
|
||||
cp scripts/start.sh dist/linux-mac/stable-diffusion-ui/
|
||||
cp LICENSE dist/linux-mac/stable-diffusion-ui/
|
||||
cp "CreativeML Open RAIL-M License" dist/linux-mac/stable-diffusion-ui/
|
||||
cp "How to install and run.txt" dist/linux-mac/stable-diffusion-ui/
|
||||
echo "" > dist/linux-mac/stable-diffusion-ui/scripts/install_status.txt
|
||||
|
||||
conda env create --prefix installer -f environment.yaml
|
||||
conda activate ./installer
|
||||
# make the zip
|
||||
|
||||
echo "Creating a distributable package.."
|
||||
|
||||
conda pack --n-threads -1 --prefix installer --format tar
|
||||
|
||||
cd dist/stable-diffusion-ui
|
||||
mkdir installer
|
||||
|
||||
tar -xf ../../installer.tar -C installer
|
||||
|
||||
mkdir scripts
|
||||
|
||||
cp ../../scripts/on_env_start.sh scripts/
|
||||
cp ../../scripts/start.sh .
|
||||
cp ../../LICENSE .
|
||||
cp "../../CreativeML Open RAIL-M License" .
|
||||
cp "../../How to install and run.txt" .
|
||||
echo "" > scripts/install_status.txt
|
||||
|
||||
chmod u+x start.sh
|
||||
|
||||
echo "Build ready. Zip the 'dist/stable-diffusion-ui' folder."
|
||||
|
||||
echo "Cleaning up.."
|
||||
# cd dist/win
|
||||
# zip -r ../stable-diffusion-ui-windows.zip stable-diffusion-ui
|
||||
# cd ../..
|
||||
|
||||
cd dist/linux-mac
|
||||
zip -r ../stable-diffusion-ui-linux.zip stable-diffusion-ui
|
||||
zip -r ../stable-diffusion-ui-mac.zip stable-diffusion-ui
|
||||
cd ../..
|
||||
|
||||
rm -rf installer
|
||||
|
||||
rm installer.tar
|
||||
echo "Build ready. Upload the zip files inside the 'dist' folder."
|
||||
|
BIN
media/config-v7.jpg
Normal file
BIN
media/config-v7.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
BIN
media/shot-v10-simple.jpg
Normal file
BIN
media/shot-v10-simple.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
BIN
media/shot-v10.jpg
Normal file
BIN
media/shot-v10.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
BIN
media/task-queue-v1.jpg
Normal file
BIN
media/task-queue-v1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 155 KiB |
34
scripts/Developer Console.cmd
Normal file
34
scripts/Developer Console.cmd
Normal file
@ -0,0 +1,34 @@
|
||||
@echo off
|
||||
|
||||
echo "Opening Stable Diffusion UI - Developer Console.." & echo.
|
||||
|
||||
set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@rem set legacy and new installer's PATH, if they exist
|
||||
if exist "installer" set PATH=%cd%\installer;%cd%\installer\Library\bin;%cd%\installer\Scripts;%cd%\installer\Library\usr\bin;%PATH%
|
||||
if exist "installer_files\env" set PATH=%cd%\installer_files\env;%cd%\installer_files\env\Library\bin;%cd%\installer_files\env\Scripts;%cd%\installer_files\Library\usr\bin;%PATH%
|
||||
|
||||
set PYTHONPATH=%cd%\installer;%cd%\installer_files\env
|
||||
|
||||
@rem activate the installer env
|
||||
call conda activate
|
||||
|
||||
@rem Test the environment
|
||||
echo "Environment Info:"
|
||||
call where git
|
||||
call git --version
|
||||
|
||||
call where conda
|
||||
call conda --version
|
||||
|
||||
echo.
|
||||
|
||||
@rem activate the environment
|
||||
call conda activate .\stable-diffusion\env
|
||||
|
||||
call where python
|
||||
call python --version
|
||||
|
||||
echo.
|
||||
|
||||
cmd /k
|
@ -1,19 +1,27 @@
|
||||
@echo off
|
||||
|
||||
@REM Delete the post-activate hook from the old installer
|
||||
if exist "installer\etc\conda\activate.d\post_activate.bat" (
|
||||
echo. > installer\etc\conda\activate.d\post_activate.bat
|
||||
)
|
||||
cd /d %~dp0
|
||||
set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@call installer\Scripts\activate.bat
|
||||
@rem set legacy installer's PATH, if it exists
|
||||
if exist "installer" set PATH=%cd%\installer;%cd%\installer\Library\bin;%cd%\installer\Scripts;%cd%\installer\Library\usr\bin;%PATH%
|
||||
|
||||
@call conda-unpack
|
||||
@rem Setup the packages required for the installer
|
||||
call scripts\bootstrap.bat
|
||||
|
||||
@call conda --version
|
||||
@call git --version
|
||||
@rem set new installer's PATH, if it downloaded any packages
|
||||
if exist "installer_files\env" set PATH=%cd%\installer_files\env;%cd%\installer_files\env\Library\bin;%cd%\installer_files\env\Scripts;%cd%\installer_files\Library\usr\bin;%PATH%
|
||||
|
||||
@cd installer
|
||||
set PYTHONPATH=%cd%\installer;%cd%\installer_files\env
|
||||
|
||||
@call ..\scripts\on_env_start.bat
|
||||
@rem Test the bootstrap
|
||||
call where git
|
||||
call git --version
|
||||
|
||||
call where conda
|
||||
call conda --version
|
||||
|
||||
@rem Download the rest of the installer and UI
|
||||
call scripts\on_env_start.bat
|
||||
|
||||
@pause
|
||||
|
77
scripts/bootstrap.bat
Normal file
77
scripts/bootstrap.bat
Normal file
@ -0,0 +1,77 @@
|
||||
@echo off
|
||||
|
||||
@rem This script will install git and conda (if not found on the PATH variable)
|
||||
@rem using micromamba (an 8mb static-linked single-file binary, conda replacement).
|
||||
@rem For users who already have git and conda, this step will be skipped.
|
||||
|
||||
@rem This enables a user to install this project without manually installing conda and git.
|
||||
|
||||
@rem config
|
||||
set MAMBA_ROOT_PREFIX=%cd%\installer_files\mamba
|
||||
set INSTALL_ENV_DIR=%cd%\installer_files\env
|
||||
set LEGACY_INSTALL_ENV_DIR=%cd%\installer
|
||||
set MICROMAMBA_DOWNLOAD_URL=https://github.com/cmdr2/stable-diffusion-ui/releases/download/v1.1/micromamba.exe
|
||||
set umamba_exists=F
|
||||
|
||||
set OLD_APPDATA=%APPDATA%
|
||||
set OLD_USERPROFILE=%USERPROFILE%
|
||||
set APPDATA=%cd%\installer_files\appdata
|
||||
set USERPROFILE=%cd%\profile
|
||||
|
||||
@rem figure out whether git and conda needs to be installed
|
||||
if exist "%INSTALL_ENV_DIR%" set PATH=%INSTALL_ENV_DIR%;%INSTALL_ENV_DIR%\Library\bin;%INSTALL_ENV_DIR%\Scripts;%INSTALL_ENV_DIR%\Library\usr\bin;%PATH%
|
||||
|
||||
set PACKAGES_TO_INSTALL=
|
||||
|
||||
if not exist "%LEGACY_INSTALL_ENV_DIR%\etc\profile.d\conda.sh" (
|
||||
if not exist "%INSTALL_ENV_DIR%\etc\profile.d\conda.sh" set PACKAGES_TO_INSTALL=%PACKAGES_TO_INSTALL% conda
|
||||
)
|
||||
|
||||
call git --version >.tmp1 2>.tmp2
|
||||
if "%ERRORLEVEL%" NEQ "0" set PACKAGES_TO_INSTALL=%PACKAGES_TO_INSTALL% git
|
||||
|
||||
call "%MAMBA_ROOT_PREFIX%\micromamba.exe" --version >.tmp1 2>.tmp2
|
||||
if "%ERRORLEVEL%" EQU "0" set umamba_exists=T
|
||||
|
||||
@rem (if necessary) install git and conda into a contained environment
|
||||
if "%PACKAGES_TO_INSTALL%" NEQ "" (
|
||||
@rem download micromamba
|
||||
if "%umamba_exists%" == "F" (
|
||||
echo "Downloading micromamba from %MICROMAMBA_DOWNLOAD_URL% to %MAMBA_ROOT_PREFIX%\micromamba.exe"
|
||||
|
||||
mkdir "%MAMBA_ROOT_PREFIX%"
|
||||
call curl -Lk "%MICROMAMBA_DOWNLOAD_URL%" > "%MAMBA_ROOT_PREFIX%\micromamba.exe"
|
||||
|
||||
@REM if "%ERRORLEVEL%" NEQ "0" (
|
||||
@REM echo "There was a problem downloading micromamba. Cannot continue."
|
||||
@REM pause
|
||||
@REM exit /b
|
||||
@REM )
|
||||
|
||||
mkdir "%APPDATA%"
|
||||
mkdir "%USERPROFILE%"
|
||||
|
||||
@rem test the mamba binary
|
||||
echo Micromamba version:
|
||||
call "%MAMBA_ROOT_PREFIX%\micromamba.exe" --version
|
||||
)
|
||||
|
||||
@rem create the installer env
|
||||
if not exist "%INSTALL_ENV_DIR%" (
|
||||
call "%MAMBA_ROOT_PREFIX%\micromamba.exe" create -y --prefix "%INSTALL_ENV_DIR%"
|
||||
)
|
||||
|
||||
echo "Packages to install:%PACKAGES_TO_INSTALL%"
|
||||
|
||||
call "%MAMBA_ROOT_PREFIX%\micromamba.exe" install -y --prefix "%INSTALL_ENV_DIR%" -c conda-forge %PACKAGES_TO_INSTALL%
|
||||
|
||||
if not exist "%INSTALL_ENV_DIR%" (
|
||||
echo "There was a problem while installing%PACKAGES_TO_INSTALL% using micromamba. Cannot continue."
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
)
|
||||
|
||||
@rem revert to the old APPDATA. only needed it for bypassing a bug in micromamba (with special characters)
|
||||
set APPDATA=%OLD_APPDATA%
|
||||
set USERPROFILE=%OLD_USERPROFILE%
|
86
scripts/bootstrap.sh
Executable file
86
scripts/bootstrap.sh
Executable file
@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will install git and conda (if not found on the PATH variable)
|
||||
# using micromamba (an 8mb static-linked single-file binary, conda replacement).
|
||||
# For users who already have git and conda, this step will be skipped.
|
||||
|
||||
# This enables a user to install this project without manually installing conda and git.
|
||||
|
||||
source ./scripts/functions.sh
|
||||
|
||||
set -o pipefail
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
case "${OS_NAME}" in
|
||||
Linux*) OS_NAME="linux";;
|
||||
Darwin*) OS_NAME="osx";;
|
||||
*) echo "Unknown OS: $OS_NAME! This script runs only on Linux or Mac" && exit
|
||||
esac
|
||||
|
||||
OS_ARCH=$(uname -m)
|
||||
case "${OS_ARCH}" in
|
||||
x86_64*) OS_ARCH="64";;
|
||||
arm64*) OS_ARCH="arm64";;
|
||||
*) echo "Unknown system architecture: $OS_ARCH! This script runs only on x86_64 or arm64" && exit
|
||||
esac
|
||||
|
||||
# https://mamba.readthedocs.io/en/latest/installation.html
|
||||
if [ "$OS_NAME" == "linux" ] && [ "$OS_ARCH" == "arm64" ]; then OS_ARCH="aarch64"; fi
|
||||
|
||||
# config
|
||||
export MAMBA_ROOT_PREFIX="$(pwd)/installer_files/mamba"
|
||||
INSTALL_ENV_DIR="$(pwd)/installer_files/env"
|
||||
LEGACY_INSTALL_ENV_DIR="$(pwd)/installer"
|
||||
MICROMAMBA_DOWNLOAD_URL="https://micro.mamba.pm/api/micromamba/${OS_NAME}-${OS_ARCH}/latest"
|
||||
umamba_exists="F"
|
||||
|
||||
# figure out whether git and conda needs to be installed
|
||||
if [ -e "$INSTALL_ENV_DIR" ]; then export PATH="$INSTALL_ENV_DIR/bin:$PATH"; fi
|
||||
|
||||
PACKAGES_TO_INSTALL=""
|
||||
|
||||
if [ ! -e "$LEGACY_INSTALL_ENV_DIR/etc/profile.d/conda.sh" ] && [ ! -e "$INSTALL_ENV_DIR/etc/profile.d/conda.sh" ]; then PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL conda"; fi
|
||||
if ! hash "git" &>/dev/null; then PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL git"; fi
|
||||
|
||||
if "$MAMBA_ROOT_PREFIX/micromamba" --version &>/dev/null; then umamba_exists="T"; fi
|
||||
|
||||
# (if necessary) install git and conda into a contained environment
|
||||
if [ "$PACKAGES_TO_INSTALL" != "" ]; then
|
||||
# download micromamba
|
||||
if [ "$umamba_exists" == "F" ]; then
|
||||
echo "Downloading micromamba from $MICROMAMBA_DOWNLOAD_URL to $MAMBA_ROOT_PREFIX/micromamba"
|
||||
|
||||
mkdir -p "$MAMBA_ROOT_PREFIX"
|
||||
curl -L "$MICROMAMBA_DOWNLOAD_URL" | tar -xvj bin/micromamba -O > "$MAMBA_ROOT_PREFIX/micromamba"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
echo
|
||||
echo "EE micromamba download failed"
|
||||
echo "EE If the lines above contain 'bzip2: Cannot exec', your system doesn't have bzip2 installed"
|
||||
echo "EE If there are network errors, please check your internet setup"
|
||||
fail "micromamba download failed"
|
||||
fi
|
||||
|
||||
chmod u+x "$MAMBA_ROOT_PREFIX/micromamba"
|
||||
|
||||
# test the mamba binary
|
||||
echo "Micromamba version:"
|
||||
"$MAMBA_ROOT_PREFIX/micromamba" --version
|
||||
fi
|
||||
|
||||
# create the installer env
|
||||
if [ ! -e "$INSTALL_ENV_DIR" ]; then
|
||||
"$MAMBA_ROOT_PREFIX/micromamba" create -y --prefix "$INSTALL_ENV_DIR" || fail "unable to create the install environment"
|
||||
fi
|
||||
|
||||
if [ ! -e "$INSTALL_ENV_DIR" ]; then
|
||||
fail "There was a problem while installing$PACKAGES_TO_INSTALL using micromamba. Cannot continue."
|
||||
fi
|
||||
|
||||
echo "Packages to install:$PACKAGES_TO_INSTALL"
|
||||
|
||||
"$MAMBA_ROOT_PREFIX/micromamba" install -y --prefix "$INSTALL_ENV_DIR" -c conda-forge $PACKAGES_TO_INSTALL
|
||||
if [ "$?" != "0" ]; then
|
||||
fail "Installation of the packages '$PACKAGES_TO_INSTALL' failed."
|
||||
fi
|
||||
fi
|
42
scripts/developer_console.sh
Executable file
42
scripts/developer_console.sh
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
|
||||
if [ "$0" == "bash" ]; then
|
||||
echo "Opening Stable Diffusion UI - Developer Console.."
|
||||
echo ""
|
||||
|
||||
# set legacy and new installer's PATH, if they exist
|
||||
if [ -e "installer" ]; then export PATH="$(pwd)/installer/bin:$PATH"; fi
|
||||
if [ -e "installer_files/env" ]; then export PATH="$(pwd)/installer_files/env/bin:$PATH"; fi
|
||||
|
||||
# activate the installer env
|
||||
CONDA_BASEPATH=$(conda info --base)
|
||||
source "$CONDA_BASEPATH/etc/profile.d/conda.sh" # avoids the 'shell not initialized' error
|
||||
|
||||
conda activate
|
||||
|
||||
# test the environment
|
||||
echo "Environment Info:"
|
||||
which git
|
||||
git --version
|
||||
|
||||
which conda
|
||||
conda --version
|
||||
|
||||
echo ""
|
||||
|
||||
# activate the environment
|
||||
CONDA_BASEPATH=$(conda info --base)
|
||||
source "$CONDA_BASEPATH/etc/profile.d/conda.sh" # otherwise conda complains about 'shell not initialized' (needed when running in a script)
|
||||
|
||||
conda activate ./stable-diffusion/env
|
||||
|
||||
which python
|
||||
python --version
|
||||
|
||||
echo ""
|
||||
else
|
||||
file_name=$(basename "${BASH_SOURCE[0]}")
|
||||
bash --init-file "$file_name"
|
||||
fi
|
32
scripts/functions.sh
Normal file
32
scripts/functions.sh
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# utility functions for all scripts
|
||||
#
|
||||
|
||||
fail() {
|
||||
echo
|
||||
echo "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
|
||||
echo
|
||||
if [ "$1" != "" ]; then
|
||||
echo ERROR: $1
|
||||
else
|
||||
echo An error occurred.
|
||||
fi
|
||||
cat <<EOF
|
||||
|
||||
Error downloading Stable Diffusion UI. Sorry about that, please try to:
|
||||
1. Run this installer again.
|
||||
2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting
|
||||
3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB
|
||||
4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues
|
||||
|
||||
Thanks!
|
||||
|
||||
|
||||
EOF
|
||||
read -p "Press any key to continue"
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@cd ..
|
||||
|
||||
if exist "scripts\config.bat" (
|
||||
@call scripts\config.bat
|
||||
)
|
||||
@ -14,7 +12,7 @@ if "%update_branch%"=="" (
|
||||
set update_branch=main
|
||||
)
|
||||
|
||||
@>nul grep -c "conda_sd_ui_deps_installed" scripts\install_status.txt
|
||||
@>nul findstr /m "conda_sd_ui_deps_installed" scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" NEQ "0" (
|
||||
for /f "tokens=*" %%a in ('python -c "import os; parts = os.getcwd().split(os.path.sep); print(len(parts))"') do if "%%a" NEQ "2" (
|
||||
echo. & echo "!!!! WARNING !!!!" & echo.
|
||||
@ -28,14 +26,14 @@ if "%update_branch%"=="" (
|
||||
)
|
||||
)
|
||||
|
||||
@>nul grep -c "sd_ui_git_cloned" scripts\install_status.txt
|
||||
@>nul findstr /m "sd_ui_git_cloned" scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" EQU "0" (
|
||||
@echo "Stable Diffusion UI's git repository was already installed. Updating from %update_branch%.."
|
||||
|
||||
@cd sd-ui-files
|
||||
|
||||
@call git reset --hard
|
||||
@call git checkout "%update_branch%"
|
||||
@call git -c advice.detachedHead=false checkout "%update_branch%"
|
||||
@call git pull
|
||||
|
||||
@cd ..
|
||||
@ -46,16 +44,18 @@ if "%update_branch%"=="" (
|
||||
@call git clone -b "%update_branch%" https://github.com/cmdr2/stable-diffusion-ui.git sd-ui-files && (
|
||||
@echo sd_ui_git_cloned >> scripts\install_status.txt
|
||||
) || (
|
||||
@echo "Error downloading Stable Diffusion UI. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||
@echo "Error downloading Stable Diffusion UI. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||
pause
|
||||
@exit /b
|
||||
)
|
||||
)
|
||||
|
||||
@xcopy sd-ui-files\ui ui /s /i /Y
|
||||
@xcopy sd-ui-files\ui ui /s /i /Y /q
|
||||
@copy sd-ui-files\scripts\on_sd_start.bat scripts\ /Y
|
||||
@copy sd-ui-files\scripts\bootstrap.bat scripts\ /Y
|
||||
@copy "sd-ui-files\scripts\Start Stable Diffusion UI.cmd" . /Y
|
||||
@copy "sd-ui-files\scripts\Developer Console.cmd" . /Y
|
||||
|
||||
@call scripts\on_sd_start.bat
|
||||
|
||||
@pause
|
||||
@pause
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
source ./scripts/functions.sh
|
||||
|
||||
printf "\n\nStable Diffusion UI\n\n"
|
||||
|
||||
if [ -f "scripts/config.sh" ]; then
|
||||
@ -16,7 +18,7 @@ if [ -f "scripts/install_status.txt" ] && [ `grep -c sd_ui_git_cloned scripts/in
|
||||
cd sd-ui-files
|
||||
|
||||
git reset --hard
|
||||
git checkout "$update_branch"
|
||||
git -c advice.detachedHead=false checkout "$update_branch"
|
||||
git pull
|
||||
|
||||
cd ..
|
||||
@ -27,16 +29,16 @@ else
|
||||
if git clone -b "$update_branch" https://github.com/cmdr2/stable-diffusion-ui.git sd-ui-files ; then
|
||||
echo sd_ui_git_cloned >> scripts/install_status.txt
|
||||
else
|
||||
printf "\n\nError downloading Stable Diffusion UI. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "git clone failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ui
|
||||
cp -Rf sd-ui-files/ui .
|
||||
cp sd-ui-files/scripts/on_sd_start.sh scripts/
|
||||
cp sd-ui-files/scripts/bootstrap.sh scripts/
|
||||
cp sd-ui-files/scripts/start.sh .
|
||||
cp sd-ui-files/scripts/developer_console.sh .
|
||||
|
||||
./scripts/on_sd_start.sh
|
||||
|
||||
|
@ -1,13 +1,24 @@
|
||||
@echo off
|
||||
|
||||
@copy sd-ui-files\scripts\on_env_start.bat scripts\ /Y
|
||||
@copy sd-ui-files\scripts\bootstrap.bat scripts\ /Y
|
||||
|
||||
if exist "%cd%\profile" (
|
||||
set USERPROFILE=%cd%\profile
|
||||
)
|
||||
|
||||
@rem activate the installer env
|
||||
call conda activate
|
||||
|
||||
@REM Caution, this file will make your eyes and brain bleed. It's such an unholy mess.
|
||||
@REM Note to self: Please rewrite this in Python. For the sake of your own sanity.
|
||||
|
||||
@REM remove the old version of the dev console script, if it's still present
|
||||
if exist "Open Developer Console.cmd" del "Open Developer Console.cmd"
|
||||
|
||||
@call python -c "import os; import shutil; frm = 'sd-ui-files\\ui\\hotfix\\9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst) if os.path.exists(dst) else print(''); print('Hotfixed broken JSON file from OpenAI');"
|
||||
|
||||
@>nul grep -c "sd_git_cloned" scripts\install_status.txt
|
||||
@>nul findstr /m "sd_git_cloned" scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" EQU "0" (
|
||||
@echo "Stable Diffusion's git repository was already installed. Updating.."
|
||||
|
||||
@ -15,7 +26,7 @@
|
||||
|
||||
@call git reset --hard
|
||||
@call git pull
|
||||
@call git checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
@call git -c advice.detachedHead=false checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
|
||||
@call git apply ..\ui\sd_internal\ddim_callback.patch
|
||||
@call git apply ..\ui\sd_internal\env_yaml.patch
|
||||
@ -27,13 +38,13 @@
|
||||
@call git clone https://github.com/basujindal/stable-diffusion.git && (
|
||||
@echo sd_git_cloned >> scripts\install_status.txt
|
||||
) || (
|
||||
@echo "Error downloading Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||
@echo "Error downloading Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||
pause
|
||||
@exit /b
|
||||
)
|
||||
|
||||
@cd stable-diffusion
|
||||
@call git checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
@call git -c advice.detachedHead=false checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
|
||||
@call git apply ..\ui\sd_internal\ddim_callback.patch
|
||||
@call git apply ..\ui\sd_internal\env_yaml.patch
|
||||
@ -43,7 +54,7 @@
|
||||
|
||||
@cd stable-diffusion
|
||||
|
||||
@>nul grep -c "conda_sd_env_created" ..\scripts\install_status.txt
|
||||
@>nul findstr /m "conda_sd_env_created" ..\scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" EQU "0" (
|
||||
@echo "Packages necessary for Stable Diffusion were already installed"
|
||||
|
||||
@ -56,8 +67,14 @@
|
||||
@REM prevent conda from using packages from the user's home directory, to avoid conflicts
|
||||
@set PYTHONNOUSERSITE=1
|
||||
|
||||
set USERPROFILE=%cd%\profile
|
||||
set TMP=%cd%\tmp
|
||||
set TEMP=%cd%\tmp
|
||||
|
||||
set PYTHONPATH=%cd%;%cd%\env\lib\site-packages
|
||||
|
||||
@call conda env create --prefix env -f environment.yaml || (
|
||||
@echo. & echo "Error installing the packages necessary for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error installing the packages necessary for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -65,13 +82,13 @@
|
||||
@call conda activate .\env
|
||||
|
||||
@call conda install -c conda-forge -y --prefix env antlr4-python3-runtime=4.8 || (
|
||||
@echo. & echo "Error installing antlr4-python3-runtime for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error installing antlr4-python3-runtime for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
||||
for /f "tokens=*" %%a in ('python -c "import torch; import ldm; import transformers; import numpy; import antlr4; print(42)"') do if "%%a" NEQ "42" (
|
||||
@echo. & echo "Dependency test failed! Error installing the packages necessary for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Dependency test failed! Error installing the packages necessary for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -81,7 +98,7 @@
|
||||
|
||||
set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@>nul grep -c "conda_sd_gfpgan_deps_installed" ..\scripts\install_status.txt
|
||||
@>nul findstr /m "conda_sd_gfpgan_deps_installed" ..\scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" EQU "0" (
|
||||
@echo "Packages necessary for GFPGAN (Face Correction) were already installed"
|
||||
) else (
|
||||
@ -89,20 +106,26 @@ set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@set PYTHONNOUSERSITE=1
|
||||
|
||||
set USERPROFILE=%cd%\profile
|
||||
set TMP=%cd%\tmp
|
||||
set TEMP=%cd%\tmp
|
||||
|
||||
set PYTHONPATH=%cd%;%cd%\env\lib\site-packages
|
||||
|
||||
@call pip install -e git+https://github.com/TencentARC/GFPGAN#egg=GFPGAN || (
|
||||
@echo. & echo "Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
||||
@call pip install basicsr==1.4.2 || (
|
||||
@echo. & echo "Error installing the basicsr package necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error installing the basicsr package necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
||||
for /f "tokens=*" %%a in ('python -c "from gfpgan import GFPGANer; print(42)"') do if "%%a" NEQ "42" (
|
||||
@echo. & echo "Dependency test failed! Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Dependency test failed! Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -110,7 +133,7 @@ set PATH=C:\Windows\System32;%PATH%
|
||||
@echo conda_sd_gfpgan_deps_installed >> ..\scripts\install_status.txt
|
||||
)
|
||||
|
||||
@>nul grep -c "conda_sd_esrgan_deps_installed" ..\scripts\install_status.txt
|
||||
@>nul findstr /m "conda_sd_esrgan_deps_installed" ..\scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" EQU "0" (
|
||||
@echo "Packages necessary for ESRGAN (Resolution Upscaling) were already installed"
|
||||
) else (
|
||||
@ -118,14 +141,20 @@ set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@set PYTHONNOUSERSITE=1
|
||||
|
||||
set USERPROFILE=%cd%\profile
|
||||
set TMP=%cd%\tmp
|
||||
set TEMP=%cd%\tmp
|
||||
|
||||
set PYTHONPATH=%cd%;%cd%\env\lib\site-packages
|
||||
|
||||
@call pip install -e git+https://github.com/xinntao/Real-ESRGAN#egg=realesrgan || (
|
||||
@echo. & echo "Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
||||
for /f "tokens=*" %%a in ('python -c "from basicsr.archs.rrdbnet_arch import RRDBNet; from realesrgan import RealESRGANer; print(42)"') do if "%%a" NEQ "42" (
|
||||
@echo. & echo "Dependency test failed! Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Dependency test failed! Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -133,7 +162,7 @@ set PATH=C:\Windows\System32;%PATH%
|
||||
@echo conda_sd_esrgan_deps_installed >> ..\scripts\install_status.txt
|
||||
)
|
||||
|
||||
@>nul grep -c "conda_sd_ui_deps_installed" ..\scripts\install_status.txt
|
||||
@>nul findstr /m "conda_sd_ui_deps_installed" ..\scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" EQU "0" (
|
||||
echo "Packages necessary for Stable Diffusion UI were already installed"
|
||||
) else (
|
||||
@ -141,28 +170,39 @@ set PATH=C:\Windows\System32;%PATH%
|
||||
|
||||
@set PYTHONNOUSERSITE=1
|
||||
|
||||
set USERPROFILE=%cd%\profile
|
||||
set TMP=%cd%\tmp
|
||||
set TEMP=%cd%\tmp
|
||||
|
||||
set PYTHONPATH=%cd%;%cd%\env\lib\site-packages
|
||||
|
||||
@call conda install -c conda-forge -y --prefix env uvicorn fastapi || (
|
||||
echo "Error installing the packages necessary for Stable Diffusion UI. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||
echo "Error installing the packages necessary for Stable Diffusion UI. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
)
|
||||
|
||||
call WHERE uvicorn > .tmp
|
||||
@>nul grep -c "uvicorn" .tmp
|
||||
@>nul findstr /m "uvicorn" .tmp
|
||||
@if "%ERRORLEVEL%" NEQ "0" (
|
||||
@echo. & echo "UI packages not found! Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "UI packages not found! Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
||||
@>nul grep -c "conda_sd_ui_deps_installed" ..\scripts\install_status.txt
|
||||
@>nul findstr /m "conda_sd_ui_deps_installed" ..\scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" NEQ "0" (
|
||||
@echo conda_sd_ui_deps_installed >> ..\scripts\install_status.txt
|
||||
)
|
||||
|
||||
|
||||
|
||||
if not exist "..\models\stable-diffusion" mkdir "..\models\stable-diffusion"
|
||||
if not exist "..\models\vae" mkdir "..\models\vae"
|
||||
echo. > "..\models\stable-diffusion\Put your custom ckpt files here.txt"
|
||||
echo. > "..\models\vae\Put your VAE files here.txt"
|
||||
|
||||
@if exist "sd-v1-4.ckpt" (
|
||||
for %%I in ("sd-v1-4.ckpt") do if "%%~zI" EQU "4265380512" (
|
||||
echo "Data files (weights) necessary for Stable Diffusion were already downloaded. Using the HuggingFace 4 GB Model."
|
||||
@ -188,12 +228,12 @@ call WHERE uvicorn > .tmp
|
||||
@if exist "sd-v1-4.ckpt" (
|
||||
for %%I in ("sd-v1-4.ckpt") do if "%%~zI" NEQ "4265380512" (
|
||||
echo. & echo "Error: The downloaded model file was invalid! Bytes downloaded: %%~zI" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
) else (
|
||||
@echo. & echo "Error downloading the data files (weights) for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error downloading the data files (weights) for Stable Diffusion. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -218,12 +258,12 @@ call WHERE uvicorn > .tmp
|
||||
@if exist "GFPGANv1.3.pth" (
|
||||
for %%I in ("GFPGANv1.3.pth") do if "%%~zI" NEQ "348632874" (
|
||||
echo. & echo "Error: The downloaded GFPGAN model file was invalid! Bytes downloaded: %%~zI" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
) else (
|
||||
@echo. & echo "Error downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -248,12 +288,12 @@ call WHERE uvicorn > .tmp
|
||||
@if exist "RealESRGAN_x4plus.pth" (
|
||||
for %%I in ("RealESRGAN_x4plus.pth") do if "%%~zI" NEQ "67040989" (
|
||||
echo. & echo "Error: The downloaded ESRGAN x4plus model file was invalid! Bytes downloaded: %%~zI" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
) else (
|
||||
@echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -278,12 +318,12 @@ call WHERE uvicorn > .tmp
|
||||
@if exist "RealESRGAN_x4plus_anime_6B.pth" (
|
||||
for %%I in ("RealESRGAN_x4plus_anime_6B.pth") do if "%%~zI" NEQ "17938799" (
|
||||
echo. & echo "Error: The downloaded ESRGAN x4plus_anime model file was invalid! Bytes downloaded: %%~zI" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
) else (
|
||||
@echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
@echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
@ -291,7 +331,37 @@ call WHERE uvicorn > .tmp
|
||||
|
||||
|
||||
|
||||
@>nul grep -c "sd_install_complete" ..\scripts\install_status.txt
|
||||
@if exist "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" (
|
||||
for %%I in ("..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt") do if "%%~zI" EQU "334695179" (
|
||||
echo "Data files (weights) necessary for the default VAE (sd-vae-ft-mse-original) were already downloaded"
|
||||
) else (
|
||||
echo. & echo "The default VAE (sd-vae-ft-mse-original) file present at models\vae\vae-ft-mse-840000-ema-pruned.ckpt is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo.
|
||||
del "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt"
|
||||
)
|
||||
)
|
||||
|
||||
@if not exist "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" (
|
||||
@echo. & echo "Downloading data files (weights) for the default VAE (sd-vae-ft-mse-original).." & echo.
|
||||
|
||||
@call curl -L -k https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt > ..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt
|
||||
|
||||
@if exist "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" (
|
||||
for %%I in ("..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt") do if "%%~zI" NEQ "334695179" (
|
||||
echo. & echo "Error: The downloaded default VAE (sd-vae-ft-mse-original) file was invalid! Bytes downloaded: %%~zI" & echo.
|
||||
echo. & echo "Error downloading the data files (weights) for the default VAE (sd-vae-ft-mse-original). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
) else (
|
||||
@echo. & echo "Error downloading the data files (weights) for the default VAE (sd-vae-ft-mse-original). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo.
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@>nul findstr /m "sd_install_complete" ..\scripts\install_status.txt
|
||||
@if "%ERRORLEVEL%" NEQ "0" (
|
||||
@echo sd_weights_downloaded >> ..\scripts\install_status.txt
|
||||
@echo sd_install_complete >> ..\scripts\install_status.txt
|
||||
@ -306,12 +376,16 @@ call WHERE uvicorn > .tmp
|
||||
@cd ..\..\..
|
||||
@echo PYTHONPATH=%PYTHONPATH%
|
||||
|
||||
call where python
|
||||
call python --version
|
||||
|
||||
@cd ..
|
||||
@set SD_UI_PATH=%cd%\ui
|
||||
@cd stable-diffusion
|
||||
|
||||
@call python --version
|
||||
@if NOT DEFINED SD_UI_BIND_PORT set SD_UI_BIND_PORT=9000
|
||||
@if NOT DEFINED SD_UI_BIND_IP set SD_UI_BIND_IP=0.0.0.0
|
||||
@uvicorn server:app --app-dir "%SD_UI_PATH%" --port %SD_UI_BIND_PORT% --host %SD_UI_BIND_IP%
|
||||
|
||||
@uvicorn server:app --app-dir "%SD_UI_PATH%" --port 9000 --host 0.0.0.0
|
||||
|
||||
@pause
|
||||
@pause
|
||||
|
@ -1,10 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
source ./scripts/functions.sh
|
||||
|
||||
cp sd-ui-files/scripts/on_env_start.sh scripts/
|
||||
cp sd-ui-files/scripts/bootstrap.sh scripts/
|
||||
|
||||
source installer/etc/profile.d/conda.sh
|
||||
# activate the installer env
|
||||
CONDA_BASEPATH=$(conda info --base)
|
||||
source "$CONDA_BASEPATH/etc/profile.d/conda.sh" # avoids the 'shell not initialized' error
|
||||
|
||||
python -c "import os; import shutil; frm = 'sd-ui-files/ui/hotfix/9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst) if os.path.exists(dst) else print(''); print('Hotfixed broken JSON file from OpenAI');"
|
||||
conda activate || fail "Failed to activate conda"
|
||||
|
||||
# remove the old version of the dev console script, if it's still present
|
||||
if [ -e "open_dev_console.sh" ]; then
|
||||
rm "open_dev_console.sh"
|
||||
fi
|
||||
|
||||
python -c "import os; import shutil; frm = 'sd-ui-files/ui/hotfix/9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst) if os.path.exists(dst) else print(''); print('Hotfixed broken JSON file from OpenAI');"
|
||||
|
||||
# Caution, this file will make your eyes and brain bleed. It's such an unholy mess.
|
||||
# Note to self: Please rewrite this in Python. For the sake of your own sanity.
|
||||
@ -16,10 +28,10 @@ if [ -e "scripts/install_status.txt" ] && [ `grep -c sd_git_cloned scripts/insta
|
||||
|
||||
git reset --hard
|
||||
git pull
|
||||
git checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
git -c advice.detachedHead=false checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
|
||||
git apply ../ui/sd_internal/ddim_callback.patch
|
||||
git apply ../ui/sd_internal/env_yaml.patch
|
||||
git apply ../ui/sd_internal/ddim_callback.patch || fail "ddim patch failed"
|
||||
git apply ../ui/sd_internal/env_yaml.patch || fail "yaml patch failed"
|
||||
|
||||
cd ..
|
||||
else
|
||||
@ -28,16 +40,14 @@ else
|
||||
if git clone https://github.com/basujindal/stable-diffusion.git ; then
|
||||
echo sd_git_cloned >> scripts/install_status.txt
|
||||
else
|
||||
printf "\n\nError downloading Stable Diffusion. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "git clone of basujindal/stable-diffusion.git failed"
|
||||
fi
|
||||
|
||||
cd stable-diffusion
|
||||
git checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
git -c advice.detachedHead=false checkout f6cfebffa752ee11a7b07497b8529d5971de916c
|
||||
|
||||
git apply ../ui/sd_internal/ddim_callback.patch
|
||||
git apply ../ui/sd_internal/env_yaml.patch
|
||||
git apply ../ui/sd_internal/ddim_callback.patch || fail "ddim patch failed"
|
||||
git apply ../ui/sd_internal/env_yaml.patch || fail "yaml patch failed"
|
||||
|
||||
cd ..
|
||||
fi
|
||||
@ -47,37 +57,32 @@ cd stable-diffusion
|
||||
if [ `grep -c conda_sd_env_created ../scripts/install_status.txt` -gt "0" ]; then
|
||||
echo "Packages necessary for Stable Diffusion were already installed"
|
||||
|
||||
conda activate ./env
|
||||
conda activate ./env || fail "conda activate failed"
|
||||
else
|
||||
printf "\n\nDownloading packages necessary for Stable Diffusion..\n"
|
||||
printf "\n\n***** This will take some time (depending on the speed of the Internet connection) and may appear to be stuck, but please be patient ***** ..\n\n"
|
||||
|
||||
# prevent conda from using packages from the user's home directory, to avoid conflicts
|
||||
export PYTHONNOUSERSITE=1
|
||||
export PYTHONPATH="$(pwd):$(pwd)/env/lib/site-packages"
|
||||
|
||||
if conda env create --prefix env --force -f environment.yaml ; then
|
||||
echo "Installed. Testing.."
|
||||
else
|
||||
printf "\n\nError installing the packages necessary for Stable Diffusion. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "'conda env create' failed"
|
||||
fi
|
||||
|
||||
conda activate ./env
|
||||
conda activate ./env || fail "conda activate failed"
|
||||
|
||||
if conda install -c conda-forge --prefix ./env -y antlr4-python3-runtime=4.8 ; then
|
||||
echo "Installed. Testing.."
|
||||
else
|
||||
printf "\n\nError installing antlr4-python3-runtime for Stable Diffusion. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Error installing antlr4-python3-runtime"
|
||||
fi
|
||||
|
||||
out_test=`python -c "import torch; import ldm; import transformers; import numpy; import antlr4; print(42)"`
|
||||
if [ "$out_test" != "42" ]; then
|
||||
printf "\n\nDependency test failed! Error installing the packages necessary for Stable Diffusion. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Dependency test failed"
|
||||
fi
|
||||
|
||||
echo conda_sd_env_created >> ../scripts/install_status.txt
|
||||
@ -89,20 +94,20 @@ else
|
||||
printf "\n\nDownloading packages necessary for GFPGAN (Face Correction)..\n"
|
||||
|
||||
export PYTHONNOUSERSITE=1
|
||||
export PYTHONPATH="$(pwd):$(pwd)/env/lib/site-packages"
|
||||
|
||||
if pip install -e git+https://github.com/TencentARC/GFPGAN#egg=GFPGAN ; then
|
||||
echo "Installed. Testing.."
|
||||
else
|
||||
printf "\n\nError installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Error installing the packages necessary for GFPGAN (Face Correction)."
|
||||
fi
|
||||
|
||||
out_test=`python -c "from gfpgan import GFPGANer; print(42)"`
|
||||
if [ "$out_test" != "42" ]; then
|
||||
printf "\n\nDependency test failed! Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
echo "EE The dependency check has failed. This usually means that some system libraries are missing."
|
||||
echo "EE On Debian/Ubuntu systems, this are often these packages: libsm6 libxext6 libxrender-dev"
|
||||
echo "EE Other Linux distributions might have different package names for these libraries."
|
||||
fail "GFPGAN dependency test failed"
|
||||
fi
|
||||
|
||||
echo conda_sd_gfpgan_deps_installed >> ../scripts/install_status.txt
|
||||
@ -114,20 +119,17 @@ else
|
||||
printf "\n\nDownloading packages necessary for ESRGAN (Resolution Upscaling)..\n"
|
||||
|
||||
export PYTHONNOUSERSITE=1
|
||||
export PYTHONPATH="$(pwd):$(pwd)/env/lib/site-packages"
|
||||
|
||||
if pip install -e git+https://github.com/xinntao/Real-ESRGAN#egg=realesrgan ; then
|
||||
echo "Installed. Testing.."
|
||||
else
|
||||
printf "\n\nError installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Error installing the packages necessary for ESRGAN"
|
||||
fi
|
||||
|
||||
out_test=`python -c "from basicsr.archs.rrdbnet_arch import RRDBNet; from realesrgan import RealESRGANer; print(42)"`
|
||||
if [ "$out_test" != "42" ]; then
|
||||
printf "\n\nDependency test failed! Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "ESRGAN dependency test failed"
|
||||
fi
|
||||
|
||||
echo conda_sd_esrgan_deps_installed >> ../scripts/install_status.txt
|
||||
@ -139,19 +141,16 @@ else
|
||||
printf "\n\nDownloading packages necessary for Stable Diffusion UI..\n\n"
|
||||
|
||||
export PYTHONNOUSERSITE=1
|
||||
export PYTHONPATH="$(pwd):$(pwd)/env/lib/site-packages"
|
||||
|
||||
if conda install -c conda-forge --prefix ./env -y uvicorn fastapi ; then
|
||||
echo "Installed. Testing.."
|
||||
else
|
||||
printf "\n\nError installing the packages necessary for Stable Diffusion UI. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "'conda install uvicorn' failed"
|
||||
fi
|
||||
|
||||
if ! command -v uvicorn &> /dev/null; then
|
||||
printf "\n\nUI packages not found! Error installing the packages necessary for Stable Diffusion UI. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "UI packages not found!"
|
||||
fi
|
||||
|
||||
echo conda_sd_ui_deps_installed >> ../scripts/install_status.txt
|
||||
@ -159,8 +158,13 @@ fi
|
||||
|
||||
|
||||
|
||||
mkdir -p "../models/stable-diffusion"
|
||||
mkdir -p "../models/vae"
|
||||
echo "" > "../models/stable-diffusion/Put your custom ckpt files here.txt"
|
||||
echo "" > "../models/vae/Put your VAE files here.txt"
|
||||
|
||||
if [ -f "sd-v1-4.ckpt" ]; then
|
||||
model_size=`ls -l sd-v1-4.ckpt | awk '{print $5}'`
|
||||
model_size=`find "sd-v1-4.ckpt" -printf "%s"`
|
||||
|
||||
if [ "$model_size" -eq "4265380512" ] || [ "$model_size" -eq "7703807346" ] || [ "$model_size" -eq "7703810927" ]; then
|
||||
echo "Data files (weights) necessary for Stable Diffusion were already downloaded"
|
||||
@ -176,23 +180,18 @@ if [ ! -f "sd-v1-4.ckpt" ]; then
|
||||
curl -L -k https://me.cmdr2.org/stable-diffusion-ui/sd-v1-4.ckpt > sd-v1-4.ckpt
|
||||
|
||||
if [ -f "sd-v1-4.ckpt" ]; then
|
||||
model_size=`ls -l sd-v1-4.ckpt | awk '{print $5}'`
|
||||
model_size=`find "sd-v1-4.ckpt" -printf "%s"`
|
||||
if [ ! "$model_size" == "4265380512" ]; then
|
||||
printf "\n\nError: The downloaded model file was invalid! Bytes downloaded: $model_size\n\n"
|
||||
printf "\n\nError downloading the data files (weights) for Stable Diffusion. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "The downloaded model file was invalid! Bytes downloaded: $model_size"
|
||||
fi
|
||||
else
|
||||
printf "\n\nError downloading the data files (weights) for Stable Diffusion. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Error downloading the data files (weights) for Stable Diffusion"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "GFPGANv1.3.pth" ]; then
|
||||
model_size=`ls -l GFPGANv1.3.pth | awk '{print $5}'`
|
||||
model_size=`find "GFPGANv1.3.pth" -printf "%s"`
|
||||
|
||||
if [ "$model_size" -eq "348632874" ]; then
|
||||
echo "Data files (weights) necessary for GFPGAN (Face Correction) were already downloaded"
|
||||
@ -208,23 +207,18 @@ if [ ! -f "GFPGANv1.3.pth" ]; then
|
||||
curl -L -k https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth > GFPGANv1.3.pth
|
||||
|
||||
if [ -f "GFPGANv1.3.pth" ]; then
|
||||
model_size=`ls -l GFPGANv1.3.pth | awk '{print $5}'`
|
||||
model_size=`find "GFPGANv1.3.pth" -printf "%s"`
|
||||
if [ ! "$model_size" -eq "348632874" ]; then
|
||||
printf "\n\nError: The downloaded GFPGAN model file was invalid! Bytes downloaded: $model_size\n\n"
|
||||
printf "\n\nError downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "The downloaded GFPGAN model file was invalid! Bytes downloaded: $model_size"
|
||||
fi
|
||||
else
|
||||
printf "\n\nError downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Error downloading the data files (weights) for GFPGAN (Face Correction)."
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "RealESRGAN_x4plus.pth" ]; then
|
||||
model_size=`ls -l RealESRGAN_x4plus.pth | awk '{print $5}'`
|
||||
model_size=`find "RealESRGAN_x4plus.pth" -printf "%s"`
|
||||
|
||||
if [ "$model_size" -eq "67040989" ]; then
|
||||
echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus were already downloaded"
|
||||
@ -240,23 +234,18 @@ if [ ! -f "RealESRGAN_x4plus.pth" ]; then
|
||||
curl -L -k https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth > RealESRGAN_x4plus.pth
|
||||
|
||||
if [ -f "RealESRGAN_x4plus.pth" ]; then
|
||||
model_size=`ls -l RealESRGAN_x4plus.pth | awk '{print $5}'`
|
||||
model_size=`find "RealESRGAN_x4plus.pth" -printf "%s"`
|
||||
if [ ! "$model_size" -eq "67040989" ]; then
|
||||
printf "\n\nError: The downloaded ESRGAN x4plus model file was invalid! Bytes downloaded: $model_size\n\n"
|
||||
printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "The downloaded ESRGAN x4plus model file was invalid! Bytes downloaded: $model_size"
|
||||
fi
|
||||
else
|
||||
printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fail "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "RealESRGAN_x4plus_anime_6B.pth" ]; then
|
||||
model_size=`ls -l RealESRGAN_x4plus_anime_6B.pth | awk '{print $5}'`
|
||||
model_size=`find "RealESRGAN_x4plus_anime_6B.pth" -printf "%s"`
|
||||
|
||||
if [ "$model_size" -eq "17938799" ]; then
|
||||
echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus_anime were already downloaded"
|
||||
@ -272,15 +261,42 @@ if [ ! -f "RealESRGAN_x4plus_anime_6B.pth" ]; then
|
||||
curl -L -k https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth > RealESRGAN_x4plus_anime_6B.pth
|
||||
|
||||
if [ -f "RealESRGAN_x4plus_anime_6B.pth" ]; then
|
||||
model_size=`ls -l RealESRGAN_x4plus_anime_6B.pth | awk '{print $5}'`
|
||||
model_size=`find "RealESRGAN_x4plus_anime_6B.pth" -printf "%s"`
|
||||
if [ ! "$model_size" -eq "17938799" ]; then
|
||||
printf "\n\nError: The downloaded ESRGAN x4plus_anime model file was invalid! Bytes downloaded: $model_size\n\n"
|
||||
printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
fail "The downloaded ESRGAN x4plus_anime model file was invalid! Bytes downloaded: $model_size"
|
||||
fi
|
||||
else
|
||||
fail "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime."
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "../models/vae/vae-ft-mse-840000-ema-pruned.ckpt" ]; then
|
||||
model_size=`find ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt -printf "%s"`
|
||||
|
||||
if [ "$model_size" -eq "334695179" ]; then
|
||||
echo "Data files (weights) necessary for the default VAE (sd-vae-ft-mse-original) were already downloaded"
|
||||
else
|
||||
printf "\n\nThe model file present at models/vae/vae-ft-mse-840000-ema-pruned.ckpt is invalid. It is only $model_size bytes in size. Re-downloading.."
|
||||
rm ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "../models/vae/vae-ft-mse-840000-ema-pruned.ckpt" ]; then
|
||||
echo "Downloading data files (weights) for the default VAE (sd-vae-ft-mse-original).."
|
||||
|
||||
curl -L -k https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt > ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
|
||||
if [ -f "../models/vae/vae-ft-mse-840000-ema-pruned.ckpt" ]; then
|
||||
model_size=`find ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt -printf "%s"`
|
||||
if [ ! "$model_size" -eq "334695179" ]; then
|
||||
printf "\n\nError: The downloaded default VAE (sd-vae-ft-mse-original) file was invalid! Bytes downloaded: $model_size\n\n"
|
||||
printf "\n\nError downloading the data files (weights) for the default VAE (sd-vae-ft-mse-original). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fi
|
||||
else
|
||||
printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
printf "\n\nError downloading the data files (weights) for the default VAE (sd-vae-ft-mse-original). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n"
|
||||
read -p "Press any key to continue"
|
||||
exit
|
||||
fi
|
||||
@ -295,15 +311,16 @@ fi
|
||||
printf "\n\nStable Diffusion is ready!\n\n"
|
||||
|
||||
SD_PATH=`pwd`
|
||||
export PYTHONPATH="$SD_PATH;$SD_PATH/env/lib/python3.8/site-packages"
|
||||
export PYTHONPATH="$SD_PATH:$SD_PATH/env/lib/python3.8/site-packages"
|
||||
echo "PYTHONPATH=$PYTHONPATH"
|
||||
|
||||
which python
|
||||
python --version
|
||||
|
||||
cd ..
|
||||
export SD_UI_PATH=`pwd`/ui
|
||||
cd stable-diffusion
|
||||
|
||||
python --version
|
||||
|
||||
uvicorn server:app --app-dir "$SD_UI_PATH" --port 9000 --host 0.0.0.0
|
||||
uvicorn server:app --app-dir "$SD_UI_PATH" --port ${SD_UI_BIND_PORT:-9000} --host ${SD_UI_BIND_IP:-0.0.0.0}
|
||||
|
||||
read -p "Press any key to continue"
|
||||
|
20
scripts/start.sh
Normal file → Executable file
20
scripts/start.sh
Normal file → Executable file
@ -1,10 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
source installer/bin/activate
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
|
||||
conda-unpack
|
||||
# set legacy installer's PATH, if it exists
|
||||
if [ -e "installer" ]; then export PATH="$(pwd)/installer/bin:$PATH"; fi
|
||||
|
||||
conda --version
|
||||
git --version
|
||||
# Setup the packages required for the installer
|
||||
scripts/bootstrap.sh || exit 1
|
||||
|
||||
# set new installer's PATH, if it downloaded any packages
|
||||
if [ -e "installer_files/env" ]; then export PATH="$(pwd)/installer_files/env/bin:$PATH"; fi
|
||||
|
||||
# Test the bootstrap
|
||||
which git
|
||||
git --version || exit 1
|
||||
|
||||
which conda
|
||||
conda --version || exit 1
|
||||
|
||||
# Download the rest of the installer and UI
|
||||
scripts/on_env_start.sh
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 91 KiB |
Binary file not shown.
Before Width: | Height: | Size: 47 KiB |
File diff suppressed because it is too large
Load Diff
@ -1,87 +0,0 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
|
||||
plugins: ["react"],
|
||||
|
||||
extends: [
|
||||
"prettier",
|
||||
"plugin:react/recommended",
|
||||
"standard-with-typescript",
|
||||
"plugin:i18next/recommended",
|
||||
"plugin:i18n-json/recommended",
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// general things turned off for now
|
||||
"no-debugger": "warn",
|
||||
"eol-last": "off",
|
||||
"comma-dangle": ["off", "always-multiline"],
|
||||
"no-void": ["off"],
|
||||
"array-callback-return": ["off"],
|
||||
"spaced-comment": ["off"],
|
||||
"padded-blocks": ["off"],
|
||||
"no-multiple-empty-lines": ["off", { max: 2, maxEOF: 1 }],
|
||||
quotes: ["off", "double"],
|
||||
semi: ["off", "always"],
|
||||
yoda: ["off"],
|
||||
eqeqeq: ["off"],
|
||||
"react/display-name": "warn",
|
||||
|
||||
// TS THINGS WE DONT WANT
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
|
||||
// these are things that fight with prettier
|
||||
"@typescript-eslint/comma-dangle": "off",
|
||||
"@typescript-eslint/space-before-function-paren": "off",
|
||||
"@typescript-eslint/quotes": "off",
|
||||
"@typescript-eslint/semi": "off",
|
||||
"@typescript-eslint/brace-style": "off",
|
||||
"@typescript-eslint/indent": "off",
|
||||
"@typescript-eslint/member-delimiter-style": "off",
|
||||
|
||||
// TS WARNINGS WE WANT
|
||||
"@typescript-eslint/no-unused-vars": "warn",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
|
||||
// i18n stuff no string literal works but turned off for now
|
||||
"i18next/no-literal-string": "off",
|
||||
// still need to figure out how to get this to work
|
||||
// it should error if we dont haev all the keys in the translation file
|
||||
"i18n-json/identical-keys": [
|
||||
"error",
|
||||
{
|
||||
filePath: {
|
||||
"home.json/": path.resolve("./Translation/locales/en/home.json"),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.ts", "*.tsx"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.json"], // Specify it only for TypeScript files
|
||||
},
|
||||
},
|
||||
],
|
||||
// eslint-disable-next-line semi
|
||||
};
|
18
ui/frontend/build_src/.gitignore
vendored
18
ui/frontend/build_src/.gitignore
vendored
@ -1,18 +0,0 @@
|
||||
# local ignores - We could move these to the global ignores,
|
||||
# but I think it makes sense to keep them here
|
||||
|
||||
# env
|
||||
*.local
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# installed dependencies
|
||||
node_modules
|
||||
|
@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/png" href="/media/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="icon" type="image/png" href="/media/favicon-32x32.png" sizes="32x32">
|
||||
<meta name="color-scheme" content="dark light" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
|
||||
<title>Stable Diffusion UI</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The react app entry point. Currently no ui just poc importing and logging -->
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
8225
ui/frontend/build_src/package-lock.json
generated
8225
ui/frontend/build_src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,56 +0,0 @@
|
||||
{
|
||||
"name": "react-ts",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"pretty": "prettier --write .",
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build --emptyOutDir",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.2",
|
||||
"@tanstack/react-location": "^3.7.4",
|
||||
"@tanstack/react-query": "^4.2.3",
|
||||
"@tanstack/react-query-devtools": "^4.2.3",
|
||||
"@vanilla-extract/css": "^1.9.0",
|
||||
"@vanilla-extract/css-utils": "^0.1.2",
|
||||
"@vanilla-extract/recipes": "^0.2.5",
|
||||
"@vanilla-extract/vite-plugin": "^3.5.0",
|
||||
"i18next": "^21.9.2",
|
||||
"immer": "^9.0.15",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^11.18.6",
|
||||
"uuid": "^9.0.0",
|
||||
"zustand": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18",
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.37.0",
|
||||
"@typescript-eslint/parser": "^5.37.0",
|
||||
"@vitejs/plugin-react": "^2.0.1",
|
||||
"eslint": "^8.23.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-standard-with-typescript": "^23.0.0",
|
||||
"eslint-plugin-i18n-json": "^4.0.0",
|
||||
"eslint-plugin-i18next": "^6.0.0-4",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.2.5",
|
||||
"eslint-plugin-promise": "^6.0.1",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.8.3",
|
||||
"vite": "^3.0.7",
|
||||
"vite-plugin-eslint": "^1.8.1"
|
||||
},
|
||||
"overrides": {
|
||||
"@vanilla-extract/vite-plugin": {
|
||||
"vite": "^3"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
tabWidth: 2,
|
||||
semi: true,
|
||||
trailingComma: "es5",
|
||||
endOfLine: "lf",
|
||||
};
|
@ -1,21 +0,0 @@
|
||||
import React from "react";
|
||||
import { ReactLocation, Router } from "@tanstack/react-location";
|
||||
import Home from "./pages/Home";
|
||||
import Settings from "./pages/Settings";
|
||||
import "./Translation/config";
|
||||
const location = new ReactLocation();
|
||||
|
||||
function App() {
|
||||
|
||||
return (
|
||||
<Router
|
||||
location={location}
|
||||
routes={[
|
||||
{ path: "/", element: <Home /> },
|
||||
{ path: "/settings", element: <Settings /> },
|
||||
]}
|
||||
></Router>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -1,32 +0,0 @@
|
||||
import i18n from "i18next";
|
||||
// this should be updated to an interface
|
||||
import ENTranslation from "./locales/en/home.json";
|
||||
import ESTranslation from "./locales/es/home.json";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
export const resources = {
|
||||
en: {
|
||||
translation: ENTranslation,
|
||||
},
|
||||
es: {
|
||||
translation: ESTranslation,
|
||||
},
|
||||
} as const;
|
||||
i18n
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
lng: "en",
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
resources,
|
||||
})
|
||||
.then(() => {
|
||||
console.log("i18n initialized");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("i18n initialization failed", err);
|
||||
})
|
||||
.finally(() => {
|
||||
console.log("i18n initialization finished");
|
||||
});
|
@ -1,110 +0,0 @@
|
||||
{
|
||||
"title": "Stable Diffusion UI",
|
||||
"description": "",
|
||||
"navbar": {
|
||||
"home": "Home",
|
||||
"history": "History",
|
||||
"community": "Community",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"land-cre": {
|
||||
"cp": "Create Profile",
|
||||
"cp-place": "Profile name",
|
||||
"pp": "Profile Picture",
|
||||
"pp-disc": "",
|
||||
"ast": "Automatically save to",
|
||||
"ast-disc": "File path to auto save your creations",
|
||||
"place": "File path",
|
||||
"cre": "Create"
|
||||
},
|
||||
"land-pre": {
|
||||
"user": "Username",
|
||||
"add": "Add Profile"
|
||||
},
|
||||
"home": {
|
||||
"status-starting": "Stable Diffusion is starting...",
|
||||
"status-ready": "Stable Diffusion is ready to use!",
|
||||
"status-error": "Stable Diffusion is not running!",
|
||||
"editor-title": "Prompt",
|
||||
"initial-img-txt": "Initial Image: (optional)",
|
||||
"initial-img-btn": "Browse...",
|
||||
"initial-img-text2": "No file selected.",
|
||||
"make-img-btn": "Make Image",
|
||||
"make-img-btn-stop": "Stop"
|
||||
},
|
||||
"in-paint": {
|
||||
"txt": "In-Painting (select the area which the AI will paint into)",
|
||||
"clear": "Clear"
|
||||
},
|
||||
"settings": {
|
||||
"base-img": "Use base image:",
|
||||
"seed": "Seed:",
|
||||
"amount-of-img": "Amount of images to make:",
|
||||
"how-many": "How many at once:",
|
||||
"stream-img": "Stream images (this will slow down image generation):",
|
||||
"width": "Width:",
|
||||
"height": "Height:",
|
||||
"sampler": "Sampler:",
|
||||
"steps": "Number of inference steps:",
|
||||
"guide-scale": "Guidance Scale:",
|
||||
"prompt-str": "Prompt Strength:",
|
||||
"live-preview": "Show a live preview of the image (disable this for faster image generation)",
|
||||
"fix-face": "Fix incorrect faces and eyes (uses GFPGAN)",
|
||||
"ups": "Upscale the image to 4x resolution using:",
|
||||
"no-ups": "No Upscaling",
|
||||
"corrected": "Show only the corrected/upscaled image"
|
||||
},
|
||||
"tags": {
|
||||
"txt": "Image Modifiers (art styles, tags etc)"
|
||||
},
|
||||
"preview-prompt": {
|
||||
"part1": "Type a prompt and press the \"Make Image\" button.",
|
||||
"part2": "You can set an \"Initial Image\" if you want to guide the AI.\n",
|
||||
"part3": "You can also add modifiers like \"Realistic\", \"Pencil Sketch\", \"ArtStation\" etc by browsing through the \"Image Modifiers\" section and selecting the desired modifiers.\n",
|
||||
"part4": "Click \"Advanced Settings\" for additional settings like seed, image size, number of images to generate etc.",
|
||||
"part5": "Enjoy! :)"
|
||||
},
|
||||
"current-task": "Current task",
|
||||
"recent-create": "Recently Created",
|
||||
"popup": {
|
||||
"use-btn": "Use Image",
|
||||
"use-btn2": "Use Image and Tags"
|
||||
},
|
||||
"history": {
|
||||
"fave": "Favorites Only",
|
||||
"search": "Search"
|
||||
},
|
||||
"advanced-settings": {
|
||||
"sound": "Play sound on task completion",
|
||||
"sound-disc": "Will play a sound so user can hear when image is done.",
|
||||
"turbo": "Turbo mode",
|
||||
"turbo-disc": "Generates images faster, but uses an additional 1 GB of GPU memory",
|
||||
"cpu": "Use CPU instead of GPU",
|
||||
"cpu-disc": "Warning: this will be *very* slow",
|
||||
"gpu": "Use full precision",
|
||||
"gpu-disc": "(for GPU-only. warning: this will consume more VRAM)",
|
||||
"beta": "Beta Features",
|
||||
"beta-disc": "Get the latest features immediately (but could be less stable). \nPlease restart the program after changing this.",
|
||||
"save": "SAVE"
|
||||
},
|
||||
"storage": {
|
||||
"ast": "Automatically save to",
|
||||
"ast-disc": "File path to auto save your creations",
|
||||
"place": "File path",
|
||||
"cps": "Cross profile sharing",
|
||||
"cps-disc": "Profiles will see suggestions from each other.",
|
||||
"acb": "Allow cloud backup",
|
||||
"acb-disc": "A button will show up for images on hover",
|
||||
"acb-place": "Choose your",
|
||||
"acc-api": "Api key",
|
||||
"acb-api-place": "Your API key",
|
||||
"save": "SAVE"
|
||||
},
|
||||
"import": {
|
||||
"imp-btn": "IMPORT",
|
||||
"exp-btn": "EXPORT",
|
||||
"disc": "It is a good idea to leave the exported file as it is. Otherwise it may not import correctly",
|
||||
"disc:2": "When importing, only profiles that are not already present on the will be added."
|
||||
},
|
||||
"about": "If you found this project useful and want to help keep it alive, please to help cover the cost of development and maintenance! Thank you for your support!\n\nPlease feel free to join the discord community or file an issue if you have any problems or suggestions in using this interface.\n\nDisclaimer: The authors of this project are not responsible for any content generated using this interface.\n\nThis license of this software forbids you from sharing any content that violates any laws, produce any harm to a person, disseminate any personal information that would be meant for harm,\nspread misinformation and target vulnerable groups. For the full list of restrictions please read the license.\n\nBy using this software, you consent to the terms and conditions of the license.\n"
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
{
|
||||
"title": "Stable Diffusion UI",
|
||||
"description": "",
|
||||
"navbar": {
|
||||
"home": "Home",
|
||||
"history": "History",
|
||||
"community": "Community",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"land-cre": {
|
||||
"cp": "Create Profile",
|
||||
"cp-place": "Profile name",
|
||||
"pp": "Profile Picture",
|
||||
"pp-disc": "",
|
||||
"ast": "Automatically save to",
|
||||
"ast-disc": "File path to auto save your creations",
|
||||
"place": "File path",
|
||||
"cre": "Create"
|
||||
},
|
||||
"land-pre": {
|
||||
"user": "Username",
|
||||
"add": "Add Profile"
|
||||
},
|
||||
"home": {
|
||||
"status-starting": "Stable Diffusion is starting...",
|
||||
"status-ready": "Stable Diffusion is ready to use!",
|
||||
"status-error": "Stable Diffusion is not running!",
|
||||
"editor-title": "Prompt",
|
||||
"initial-img-txt": "Initial Image: (optional)",
|
||||
"initial-img-btn": "Browse...",
|
||||
"initial-img-text2": "No file selected.",
|
||||
"make-img-btn": "Make Image",
|
||||
"make-img-btn-stop": "Stop"
|
||||
},
|
||||
"in-paint": {
|
||||
"txt": "In-Painting (select the area which the AI will paint into)",
|
||||
"clear": "Clear"
|
||||
},
|
||||
"settings": {
|
||||
"base-img": "Use base image:",
|
||||
"seed": "Seed:",
|
||||
"amount-of-img": "Amount of images to make:",
|
||||
"how-many": "How many at once:",
|
||||
"width": "Width:",
|
||||
"height": "Height:",
|
||||
"steps": "Number of inference steps:",
|
||||
"guide-scale": "Guidance Scale:",
|
||||
"prompt-str": "Prompt Strength:",
|
||||
"live-preview": "Show a live preview of the image (disable this for faster image generation)",
|
||||
"fix-face": "Fix incorrect faces and eyes (uses GFPGAN)",
|
||||
"ups": "Upscale the image to 4x resolution using:",
|
||||
"no-ups": "No Upscaling",
|
||||
"corrected": "Show only the corrected/upscaled image"
|
||||
},
|
||||
"tags": {
|
||||
"txt": "Image Modifiers (art styles, tags etc)"
|
||||
},
|
||||
"preview-prompt": {
|
||||
"part1": "Type a prompt and press the \"Make Image\" button.",
|
||||
"part2": "You can set an \"Initial Image\" if you want to guide the AI.\n",
|
||||
"part3": "You can also add modifiers like \"Realistic\", \"Pencil Sketch\", \"ArtStation\" etc by browsing through the \"Image Modifiers\" section and selecting the desired modifiers.\n",
|
||||
"part4": "Click \"Advanced Settings\" for additional settings like seed, image size, number of images to generate etc.",
|
||||
"part5": "Enjoy! :)"
|
||||
},
|
||||
"current-task": "Current task",
|
||||
"recent-create": "Recently Created",
|
||||
"popup": {
|
||||
"use-btn": "Use Image",
|
||||
"use-btn2": "Use Image and Tags"
|
||||
},
|
||||
"history": {
|
||||
"fave": "Favorites Only",
|
||||
"search": "Search"
|
||||
},
|
||||
"advanced-settings": {
|
||||
"sound": "Play sound on task completion",
|
||||
"sound-disc": "Will play a sound so user can hear when image is done.",
|
||||
"turbo": "Turbo mode",
|
||||
"turbo-disc": "Generates images faster, but uses an additional 1 GB of GPU memory",
|
||||
"cpu": "Use CPU instead of GPU",
|
||||
"cpu-disc": "Warning: this will be *very* slow",
|
||||
"gpu": "Use full precision",
|
||||
"gpu-disc": "(for GPU-only. warning: this will consume more VRAM)",
|
||||
"beta": "Beta Features",
|
||||
"beta-disc": "Get the latest features immediately (but could be less stable). \nPlease restart the program after changing this.",
|
||||
"save": "SAVE"
|
||||
},
|
||||
"storage": {
|
||||
"ast": "Automatically save to",
|
||||
"ast-disc": "File path to auto save your creations",
|
||||
"place": "File path",
|
||||
"cps": "Cross profile sharing",
|
||||
"cps-disc": "Profiles will see suggestions from each other.",
|
||||
"acb": "Allow cloud backup",
|
||||
"acb-disc": "A button will show up for images on hover",
|
||||
"acb-place": "Choose your",
|
||||
"acc-api": "Api key",
|
||||
"acb-api-place": "Your API key",
|
||||
"save": "SAVE"
|
||||
},
|
||||
"import": {
|
||||
"imp-btn": "IMPORT",
|
||||
"exp-btn": "EXPORT",
|
||||
"disc": "It is a good idea to leave the exported file as it is. Otherwise it may not import correctly",
|
||||
"disc:2": "When importing, only profiles that are not already present on the will be added."
|
||||
},
|
||||
"about": "If you found this project useful and want to help keep it alive, please to help cover the cost of development and maintenance! Thank you for your support!\n\nPlease feel free to join the discord community or file an issue if you have any problems or suggestions in using this interface.\n\nDisclaimer: The authors of this project are not responsible for any content generated using this interface.\n\nThis license of this software forbids you from sharing any content that violates any laws, produce any harm to a person, disseminate any personal information that would be meant for harm,\nspread misinformation and target vulnerable groups. For the full list of restrictions please read the license.\n\nBy using this software, you consent to the terms and conditions of the license.\n"
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
/**
|
||||
* basic server health
|
||||
*/
|
||||
|
||||
import type { SAMPLER_OPTIONS } from "../stores/imageCreateStore";
|
||||
|
||||
// when we are on dev we want to specifiy 9000 as the port for the backend
|
||||
// when we are on prod we want be realtive to the current url
|
||||
export const API_URL = import.meta.env.DEV ? "http://localhost:9000" : "";
|
||||
|
||||
export const HEALTH_PING_INTERVAL = 5000; // 5 seconds
|
||||
export const healthPing = async () => {
|
||||
const pingUrl = `${API_URL}/ping`;
|
||||
const response = await fetch(pingUrl);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* the local list of modifications
|
||||
*/
|
||||
export const loadModifications = async () => {
|
||||
const response = await fetch(`${API_URL}/modifiers.json`);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getSaveDirectory = async () => {
|
||||
const response = await fetch(`${API_URL}/output_dir`);
|
||||
const data = await response.json();
|
||||
return data[0];
|
||||
};
|
||||
|
||||
export const KEY_CONFIG = "config";
|
||||
export const getConfig = async () => {
|
||||
const response = await fetch(`${API_URL}/app_config`);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
|
||||
export const KEY_TOGGLE_CONFIG = "toggle_config";
|
||||
export const toggleBetaConfig = async (branch: string) => {
|
||||
const response = await fetch(`${API_URL}/app_config`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
update_branch: branch,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* post a new request for an image
|
||||
*/
|
||||
// TODO; put hese some place better
|
||||
export interface ImageRequest {
|
||||
session_id: string;
|
||||
prompt: string;
|
||||
negative_prompt: string;
|
||||
seed: number;
|
||||
num_outputs: number;
|
||||
num_inference_steps: number;
|
||||
guidance_scale: number;
|
||||
width:
|
||||
| 128
|
||||
| 192
|
||||
| 256
|
||||
| 320
|
||||
| 384
|
||||
| 448
|
||||
| 512
|
||||
| 576
|
||||
| 640
|
||||
| 704
|
||||
| 768
|
||||
| 832
|
||||
| 896
|
||||
| 960
|
||||
| 1024;
|
||||
height:
|
||||
| 128
|
||||
| 192
|
||||
| 256
|
||||
| 320
|
||||
| 384
|
||||
| 448
|
||||
| 512
|
||||
| 576
|
||||
| 640
|
||||
| 704
|
||||
| 768
|
||||
| 832
|
||||
| 896
|
||||
| 960
|
||||
| 1024;
|
||||
// allow_nsfw: boolean
|
||||
turbo: boolean;
|
||||
use_cpu: boolean;
|
||||
use_full_precision: boolean;
|
||||
save_to_disk_path: null | string;
|
||||
use_face_correction: null | "GFPGANv1.3";
|
||||
use_upscale: null | "RealESRGAN_x4plus" | "RealESRGAN_x4plus_anime_6B" | "";
|
||||
show_only_filtered_image: boolean;
|
||||
init_image: undefined | string;
|
||||
prompt_strength: undefined | number;
|
||||
mask: undefined | string;
|
||||
sampler: typeof SAMPLER_OPTIONS[number];
|
||||
stream_progress_updates: true;
|
||||
stream_image_progress: boolean;
|
||||
|
||||
}
|
||||
|
||||
export interface ImageOutput {
|
||||
data: string;
|
||||
path_abs: string | null;
|
||||
seed: number;
|
||||
}
|
||||
|
||||
export interface ImageReturnType {
|
||||
output: ImageOutput[];
|
||||
request: ImageRequest;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export const MakeImageKey = "MakeImage";
|
||||
export const doMakeImage = async (reqBody: ImageRequest) => {
|
||||
const res = await fetch(`${API_URL}/image`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(reqBody),
|
||||
});
|
||||
return res;
|
||||
};
|
||||
|
||||
export const doStopImage = async () => {
|
||||
|
||||
const response = await fetch(`${API_URL}/image/stop`);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
@ -1,140 +0,0 @@
|
||||
// would prefer to use a var here, but it doesn't work
|
||||
// vars: {
|
||||
// '--button-base-saturation': vars.colorMod.saturation.normal,
|
||||
// '--button-base-lightness': vars.colorMod.lightness.normal,
|
||||
// },
|
||||
|
||||
|
||||
import { recipe } from "@vanilla-extract/recipes";
|
||||
import { vars } from "../../styles/theme/index.css";
|
||||
|
||||
export const buttonStyle = recipe({
|
||||
|
||||
base: {
|
||||
fontSize: vars.fonts.sizes.Subheadline,
|
||||
fontWeight: "bold",
|
||||
color: vars.colors.text.normal,
|
||||
padding: vars.spacing.small,
|
||||
border: "0",
|
||||
borderRadius: vars.trim.smallBorderRadius,
|
||||
},
|
||||
|
||||
variants: {
|
||||
color: {
|
||||
primary: {
|
||||
// @ts-expect-error
|
||||
'--button-hue': vars.brandHue,
|
||||
'--button-base-saturation': vars.colorMod.saturation.normal,
|
||||
'--button-base-lightness': vars.colorMod.lightness.normal,
|
||||
},
|
||||
secondary: {
|
||||
// @ts-expect-error
|
||||
'--button-hue': vars.secondaryHue,
|
||||
'--button-base-saturation': vars.colorMod.saturation.normal,
|
||||
'--button-base-lightness': vars.colorMod.lightness.normal,
|
||||
},
|
||||
tertiary: {
|
||||
// @ts-expect-error
|
||||
'--button-hue': vars.tertiaryHue,
|
||||
'--button-base-saturation': vars.colorMod.saturation.normal,
|
||||
'--button-base-lightness': vars.colorMod.lightness.normal,
|
||||
},
|
||||
cancel: {
|
||||
// @ts-expect-error
|
||||
'--button-hue': vars.errorHue,
|
||||
'--button-base-saturation': vars.colorMod.saturation.normal,
|
||||
'--button-base-lightness': vars.colorMod.lightness.normal,
|
||||
},
|
||||
accent: {
|
||||
// @ts-expect-error
|
||||
'--button-hue': vars.backgroundAccentHue,
|
||||
'--button-base-saturation': vars.backgroundAccentSaturation,
|
||||
'--button-base-lightness': vars.backgroundAccentLightness,
|
||||
},
|
||||
clear: {
|
||||
backgroundColor: "transparent",
|
||||
},
|
||||
},
|
||||
|
||||
type: {
|
||||
fill: {
|
||||
backgroundColor: `hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
border: `1px solid hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
":hover": {
|
||||
backgroundColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
},
|
||||
":active": {
|
||||
backgroundColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
|
||||
":focus": {
|
||||
backgroundColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
|
||||
":disabled": {
|
||||
backgroundColor: `hsl(var(--button-hue),${vars.colorMod.saturation.dim},${vars.colorMod.lightness.dim})`,
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.dim},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
},
|
||||
outline: {
|
||||
backgroundColor: "transparent",
|
||||
border: `1px solid hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
":hover": {
|
||||
borderColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
},
|
||||
|
||||
":active": {
|
||||
borderColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
|
||||
":focus": {
|
||||
borderColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
|
||||
":disabled": {
|
||||
borderColor: `hsl(var(--button-hue),${vars.colorMod.saturation.dim},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
},
|
||||
action: {
|
||||
backgroundColor: "transparent",
|
||||
color: `hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
textDecoration: "underline",
|
||||
":hover": {
|
||||
color: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
},
|
||||
|
||||
":active": {
|
||||
color: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
|
||||
":focus": {
|
||||
color: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
|
||||
":disabled": {
|
||||
color: `hsl(var(--button-hue),${vars.colorMod.saturation.dim},${vars.colorMod.lightness.dim})`,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
size: {
|
||||
slim: {
|
||||
padding: vars.spacing.min,
|
||||
fontSize: vars.fonts.sizes.Caption,
|
||||
},
|
||||
large: {
|
||||
width: "100%",
|
||||
fontSize: vars.fonts.sizes.Headline,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
defaultVariants: {
|
||||
color: "primary",
|
||||
type: "fill",
|
||||
},
|
||||
|
||||
});
|
@ -1,51 +0,0 @@
|
||||
import { recipe } from "@vanilla-extract/recipes";
|
||||
import { vars } from "../../styles/theme/index.css";
|
||||
|
||||
export const card = recipe({
|
||||
|
||||
base: {
|
||||
color: vars.colors.text.normal,
|
||||
padding: vars.spacing.medium,
|
||||
},
|
||||
|
||||
variants: {
|
||||
backing: {
|
||||
normal: {
|
||||
background: vars.backgroundMain,
|
||||
},
|
||||
light: {
|
||||
background: vars.backgroundLight,
|
||||
},
|
||||
dark: {
|
||||
background: vars.backgroundDark,
|
||||
},
|
||||
},
|
||||
|
||||
rounded: {
|
||||
true: {
|
||||
borderRadius: vars.trim.smallBorderRadius,
|
||||
},
|
||||
},
|
||||
|
||||
info: {
|
||||
true: {
|
||||
background: vars.backgroundDark,
|
||||
border: `1px solid ${vars.backgroundAccentMain}`,
|
||||
},
|
||||
},
|
||||
|
||||
level: {
|
||||
flat: {},
|
||||
1: { boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)" },
|
||||
2: { boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)" },
|
||||
3: { boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)" },
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
backing: "light",
|
||||
level: 'flat',
|
||||
rounded: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { recipe } from "@vanilla-extract/recipes";
|
||||
import { vars } from "../../styles/theme/index.css";
|
||||
|
||||
|
||||
export const card = recipe({
|
||||
base: {
|
||||
background: vars.backgroundMain,
|
||||
color: vars.colors.text.normal,
|
||||
padding: vars.spacing.medium,
|
||||
borderRadius: vars.trim.smallBorderRadius,
|
||||
},
|
||||
variants: {
|
||||
level: {
|
||||
1: { boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)" },
|
||||
2: { boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)" },
|
||||
3: { boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)" },
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
level: 1,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
// import { recipe } from "@vanilla-extract/recipes";
|
||||
import { vars } from "../../styles/theme/index.css";
|
||||
|
||||
import {
|
||||
card
|
||||
} from "./card.css";
|
||||
|
||||
export const PopoverMain = style({
|
||||
position: 'relative'
|
||||
});
|
||||
|
||||
export const PopoverButtonStyle = style({
|
||||
backgroundColor: "transparent",
|
||||
border: "0 none",
|
||||
cursor: "pointer",
|
||||
padding: vars.spacing.none,
|
||||
fontSize: vars.fonts.sizes.Subheadline,
|
||||
});
|
||||
|
||||
globalStyle(`${PopoverButtonStyle} > i`, {
|
||||
marginRight: vars.spacing.small,
|
||||
});
|
||||
|
||||
export const PopoverPanelMain = style([card(
|
||||
{
|
||||
backing: 'dark',
|
||||
level: 2,
|
||||
}
|
||||
), {
|
||||
position: 'absolute',
|
||||
top: '100%',
|
||||
right: '0',
|
||||
zIndex: '1',
|
||||
}]);
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { style, } from "@vanilla-extract/css";
|
||||
|
||||
// import { recipe } from "@vanilla-extract/recipes";
|
||||
import { vars } from "../../styles/theme/index.css";
|
||||
|
||||
export const SwitchGroupMain = style({
|
||||
});
|
||||
|
||||
export const SwitchMain = style({
|
||||
});
|
||||
|
||||
export const SwitchLabel = style({
|
||||
});
|
||||
|
||||
export const SwitchEnabled = style({
|
||||
});
|
||||
|
||||
export const SwitchPill = style({
|
||||
});
|
@ -1,60 +0,0 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
import { recipe } from "@vanilla-extract/recipes";
|
||||
import { vars } from "../../styles/theme/index.css";
|
||||
|
||||
export const tabStyles = recipe({
|
||||
base: {
|
||||
background: vars.backgroundMain,
|
||||
color: vars.colors.text.normal,
|
||||
padding: vars.spacing.small,
|
||||
borderRadius: `${vars.trim.smallBorderRadius} ${vars.trim.smallBorderRadius} 0 0`,
|
||||
border: `1px solid ${vars.backgroundLight}`,
|
||||
borderBottom: 'none',
|
||||
marginLeft: vars.spacing.small,
|
||||
boxShadow: `0px -1px 4px -2px ${vars.backgroundAccentMain} inset`,
|
||||
width: 'fit-content',
|
||||
':focus': {
|
||||
outline: 'none',
|
||||
},
|
||||
},
|
||||
|
||||
variants: {
|
||||
selected: {
|
||||
true: {
|
||||
background: vars.backgroundLight,
|
||||
color: vars.colors.text.normal,
|
||||
boxShadow: `0px -1px 4px -2px ${vars.backgroundDark} inset`,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const tabPanelStyles = recipe({
|
||||
base: {
|
||||
color: vars.colors.text.normal,
|
||||
// borderRadius: `0 0 ${vars.trim.smallBorderRadius} ${vars.trim.smallBorderRadius}`,
|
||||
background: vars.backgroundLight,
|
||||
padding: vars.spacing.medium,
|
||||
flexGrow: 1,
|
||||
overflow: 'auto',
|
||||
// "::-webkit-scrollbar": {
|
||||
// width: "4px",
|
||||
// },
|
||||
|
||||
},
|
||||
variants: {
|
||||
|
||||
backing: {
|
||||
normal: {
|
||||
background: vars.backgroundMain,
|
||||
},
|
||||
light: {
|
||||
background: vars.backgroundLight,
|
||||
},
|
||||
dark: {
|
||||
background: vars.backgroundDark,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,34 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../styles/theme/index.css";
|
||||
import {
|
||||
tabPanelStyles,
|
||||
} from "../../_recipes/tabs_headless.css";
|
||||
|
||||
|
||||
export const TabpanelScrollFlop = style([tabPanelStyles(), {
|
||||
direction: 'rtl',
|
||||
// position: 'relative',
|
||||
overflow: 'overlay',
|
||||
"::-webkit-scrollbar": {
|
||||
position: 'absolute',
|
||||
width: "6px",
|
||||
backgroundColor: vars.backgroundAccentMain,
|
||||
},
|
||||
|
||||
"::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: vars.backgroundDark,
|
||||
borderRadius: "4px",
|
||||
},
|
||||
|
||||
|
||||
// "::-webkit-scrollbar-button: {
|
||||
// backgroundColor: vars.backgroundDark,
|
||||
// }
|
||||
|
||||
|
||||
}]);
|
||||
|
||||
globalStyle(`${TabpanelScrollFlop} > *`, {
|
||||
direction: 'ltr',
|
||||
|
||||
});
|
@ -1,61 +0,0 @@
|
||||
import React, { Fragment } from "react";
|
||||
import { Tab } from '@headlessui/react';
|
||||
|
||||
|
||||
|
||||
import CreationPanel from "../../organisms/creationPanel";
|
||||
import QueueDisplay from "../../organisms/queueDisplay";
|
||||
|
||||
import ProcessingStatus from "../../molecules/queueStatusTab";
|
||||
|
||||
import {
|
||||
tabStyles,
|
||||
} from "../../_recipes/tabs_headless.css";
|
||||
|
||||
import {
|
||||
TabpanelScrollFlop
|
||||
} from "./creationTabs.css";
|
||||
|
||||
export default function CreationTabs() {
|
||||
|
||||
return (
|
||||
<Tab.Group>
|
||||
<Tab.List>
|
||||
<Tab as={Fragment}>
|
||||
{({ selected }) => (
|
||||
<button
|
||||
className={tabStyles({
|
||||
selected,
|
||||
})}
|
||||
>
|
||||
Create
|
||||
</button>
|
||||
)}
|
||||
</Tab>
|
||||
|
||||
<Tab as={Fragment}>
|
||||
{({ selected }) => (
|
||||
|
||||
<button
|
||||
className={tabStyles({
|
||||
selected,
|
||||
})}
|
||||
>
|
||||
<ProcessingStatus></ProcessingStatus>
|
||||
</button>
|
||||
)}
|
||||
</Tab>
|
||||
|
||||
|
||||
</Tab.List>
|
||||
<Tab.Panels className={TabpanelScrollFlop}>
|
||||
<Tab.Panel>
|
||||
<CreationPanel></CreationPanel>
|
||||
</Tab.Panel>
|
||||
<Tab.Panel>
|
||||
<QueueDisplay></QueueDisplay>
|
||||
</Tab.Panel>
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
);
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../styles/theme/index.css";
|
||||
|
||||
import {
|
||||
tabStyles
|
||||
} from "../../_recipes/tabs_headless.css";
|
||||
|
||||
|
||||
export const basicDisplayLayout = style({
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 250px",
|
||||
gridTemplateRows: "1fr 250px",
|
||||
gridTemplateAreas: `
|
||||
"content info"
|
||||
"history history"`,
|
||||
|
||||
overflow: "hidden",
|
||||
|
||||
selectors: {
|
||||
'&[data-hide-info]': {
|
||||
gridTemplateColumns: "1fr",
|
||||
gridTemplateRows: "1fr 250px",
|
||||
// gridTemplateAreas: `
|
||||
// "content"
|
||||
// "history"`,
|
||||
},
|
||||
'&[data-hide-history]': {
|
||||
gridTemplateColumns: "1fr 250px",
|
||||
gridTemplateRows: "1fr 0px",
|
||||
// gridTemplateAreas: `
|
||||
// "content info"`,
|
||||
},
|
||||
'&[data-hide-info][data-hide-history]': {
|
||||
gridTemplateColumns: "1fr 0px",
|
||||
gridTemplateRows: "1fr 0px",
|
||||
// gridTemplateAreas: `
|
||||
// "content"`,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
// "@media": {
|
||||
// "screen and (max-width: 800px)": {
|
||||
// gridTemplateColumns: "1fr",
|
||||
// gridTemplateRows: "100px 300px 1fr",
|
||||
// gridTemplateAreas: `
|
||||
// "header"
|
||||
// "create"
|
||||
// "display"
|
||||
// `,
|
||||
// },
|
||||
// },
|
||||
|
||||
});
|
||||
|
||||
// globalStyle(`${basicDisplayLayout}.hideHistory`, {
|
||||
|
||||
// });
|
||||
|
||||
export const contentLayout = style({
|
||||
gridArea: "content",
|
||||
});
|
||||
|
||||
export const infoLayout = style({
|
||||
gridArea: "info",
|
||||
position: "relative",
|
||||
});
|
||||
|
||||
export const historyLayout = style({
|
||||
gridArea: "history",
|
||||
position: "relative",
|
||||
});
|
||||
|
||||
globalStyle(`${historyLayout} > button`, {
|
||||
position: "absolute",
|
||||
top: '-29px',
|
||||
});
|
||||
|
||||
export const displayContainer = style({
|
||||
flexGrow: 1,
|
||||
overflow: 'auto',
|
||||
display: "flex",
|
||||
});
|
||||
|
||||
export const displayData = style({
|
||||
width: '250px',
|
||||
height: '100%',
|
||||
backgroundColor: 'rebeccapurple',
|
||||
position: 'relative',
|
||||
});
|
||||
|
||||
export const DataTab = style([tabStyles(), {
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
left: '0',
|
||||
|
||||
// pretty sure this is a magic number
|
||||
transformOrigin: '37% 275%',
|
||||
transform: 'rotate(-90deg)',
|
||||
}]);
|
||||
|
||||
|
||||
// export const previousImages = style({
|
||||
// minHeight: '250px',
|
||||
// });
|
@ -1,65 +0,0 @@
|
||||
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { Transition } from '@headlessui/react'
|
||||
|
||||
import CurrentDisplay from "../../organisms/currentDisplay";
|
||||
import CompletedImages from "../../organisms/completedImages";
|
||||
import CurrentInfo from "../../organisms/currentInfo";
|
||||
|
||||
|
||||
import {
|
||||
tabStyles
|
||||
} from "../../_recipes/tabs_headless.css";
|
||||
|
||||
import {
|
||||
basicDisplayLayout,
|
||||
contentLayout,
|
||||
infoLayout,
|
||||
historyLayout
|
||||
} from "./basicDisplay.css";
|
||||
|
||||
export default function BasicDisplay() {
|
||||
|
||||
const [isShowingHistory, setIsShowingHistory] = useState(true)
|
||||
|
||||
const layoutRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if (layoutRef.current != undefined) {
|
||||
// set the hide-history data attribute
|
||||
if (isShowingHistory) {
|
||||
layoutRef.current.removeAttribute('data-hide-history');
|
||||
}
|
||||
else {
|
||||
// layoutRef.current.dataset.hideHistory = "true";
|
||||
layoutRef.current.setAttribute('data-hide-history', '');
|
||||
}
|
||||
}
|
||||
}, [layoutRef, isShowingHistory]);
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={layoutRef}
|
||||
className={basicDisplayLayout}
|
||||
>
|
||||
<div className={contentLayout}>
|
||||
<CurrentDisplay></CurrentDisplay>
|
||||
</div>
|
||||
|
||||
{/* <div className={infoLayout}>
|
||||
<CurrentInfo ></CurrentInfo>
|
||||
</div> */}
|
||||
|
||||
<div className={historyLayout}>
|
||||
<button
|
||||
className={tabStyles({})}
|
||||
onClick={() => setIsShowingHistory((isShowingHistory) => !isShowingHistory)}>
|
||||
{isShowingHistory ? "Hide History" : "Show History"}
|
||||
</button>
|
||||
<CompletedImages></CompletedImages>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import React from "react";
|
||||
import { API_URL } from "../../../api";
|
||||
|
||||
const url = `${API_URL}/ding.mp3`;
|
||||
|
||||
const AudioDing = React.forwardRef((props, ref) => (
|
||||
// @ts-expect-error
|
||||
<audio ref={ref} style={{ display: "none" }}>
|
||||
<source src={url} type="audio/mp3" />
|
||||
</audio>
|
||||
));
|
||||
|
||||
AudioDing.displayName = "AudioDing";
|
||||
|
||||
export default AudioDing;
|
||||
|
@ -1,73 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import {
|
||||
KEY_CONFIG,
|
||||
getConfig,
|
||||
KEY_TOGGLE_CONFIG,
|
||||
toggleBetaConfig,
|
||||
} from "../../../api";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function BetaMode() {
|
||||
const { t } = useTranslation();
|
||||
// gate for the toggle
|
||||
const [shouldSetCofig, setShouldSetConfig] = useState(false);
|
||||
// next branch to get
|
||||
const [branchToGetNext, setBranchToGetNext] = useState("beta");
|
||||
|
||||
// our basic config
|
||||
const { status: configStatus, data: configData } = useQuery(
|
||||
[KEY_CONFIG],
|
||||
getConfig
|
||||
);
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// the toggle config
|
||||
const { status: toggleStatus, data: toggleData } = useQuery(
|
||||
[KEY_TOGGLE_CONFIG],
|
||||
async () => await toggleBetaConfig(branchToGetNext),
|
||||
{
|
||||
enabled: shouldSetCofig,
|
||||
}
|
||||
);
|
||||
|
||||
// this is also in the Header Display
|
||||
// TODO: make this a custom hook
|
||||
useEffect(() => {
|
||||
if (configStatus === "success") {
|
||||
const { update_branch: updateBranch } = configData;
|
||||
|
||||
if (updateBranch === "main") {
|
||||
setBranchToGetNext("beta");
|
||||
} else {
|
||||
// setIsBeta(true);
|
||||
setBranchToGetNext("main");
|
||||
}
|
||||
}
|
||||
}, [configStatus, configData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (toggleStatus === "success") {
|
||||
if (toggleData[0] === "OK") {
|
||||
// force a refetch of the config
|
||||
void queryClient.invalidateQueries([KEY_CONFIG])
|
||||
}
|
||||
setShouldSetConfig(false);
|
||||
}
|
||||
}, [toggleStatus, toggleData, setShouldSetConfig]);
|
||||
|
||||
return (
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={branchToGetNext === "main"}
|
||||
onChange={(e) => {
|
||||
setShouldSetConfig(true);
|
||||
}}
|
||||
/>🔥
|
||||
{t("advanced-settings.beta")} {t("advanced-settings.beta-disc")}
|
||||
</label>
|
||||
);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import React from "react";
|
||||
import { doStopImage } from "../../../api";
|
||||
import { useRequestQueue } from "../../../stores/requestQueueStore";
|
||||
|
||||
import {
|
||||
buttonStyle
|
||||
} from "../../_recipes/button.css";
|
||||
|
||||
|
||||
export default function ClearQueue() {
|
||||
|
||||
const hasQueue = useRequestQueue((state) => state.hasAnyQueue());
|
||||
const clearQueue = useRequestQueue((state) => state.clearQueue);
|
||||
|
||||
const stopAll = async () => {
|
||||
try {
|
||||
clearQueue();
|
||||
const res = await doStopImage();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button className={buttonStyle(
|
||||
{
|
||||
color: "cancel",
|
||||
size: "large",
|
||||
}
|
||||
)}
|
||||
disabled={!hasQueue} onClick={() => void stopAll()}>
|
||||
STOP ALL
|
||||
</button>
|
||||
);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
export const DrawImageMain = style({
|
||||
position: "relative",
|
||||
});
|
||||
|
||||
globalStyle(`${DrawImageMain} > canvas`, {
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
});
|
||||
|
||||
globalStyle(`${DrawImageMain} > canvas:first-of-type`, {
|
||||
opacity: ".7",
|
||||
});
|
||||
|
||||
globalStyle(`${DrawImageMain} > img`, {
|
||||
top: "0",
|
||||
left: "0",
|
||||
});
|
@ -1,194 +0,0 @@
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
|
||||
import {
|
||||
DrawImageMain,
|
||||
} from "./drawImage.css";
|
||||
|
||||
// https://github.com/embiem/react-canvas-draw
|
||||
|
||||
interface DrawImageProps {
|
||||
imageData: string;
|
||||
brushSize: number;
|
||||
|
||||
brushShape: string;
|
||||
brushColor: string;
|
||||
isErasing: boolean;
|
||||
setData: (data: string) => void;
|
||||
}
|
||||
|
||||
export default function DrawImage({
|
||||
imageData,
|
||||
brushSize,
|
||||
brushShape,
|
||||
brushColor,
|
||||
isErasing,
|
||||
setData,
|
||||
}: DrawImageProps) {
|
||||
const drawingRef = useRef<HTMLCanvasElement>(null);
|
||||
const cursorRef = useRef<HTMLCanvasElement>(null);
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
|
||||
const [canvasWidth, setCanvasWidth] = useState(512);
|
||||
const [canvasHeight, setCanvasHeight] = useState(512);
|
||||
|
||||
useEffect(() => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
setCanvasWidth(img.width);
|
||||
setCanvasHeight(img.height);
|
||||
};
|
||||
img.src = imageData;
|
||||
}, [imageData]);
|
||||
|
||||
useEffect(() => {
|
||||
// when the brush color changes, change the color of all the
|
||||
// drawn pixels to the new color
|
||||
if (drawingRef.current != null) {
|
||||
const ctx = drawingRef.current.getContext("2d");
|
||||
if (ctx != null) {
|
||||
|
||||
const imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
|
||||
const data = imageData.data;
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
if (data[i + 3] > 0) {
|
||||
data[i] = parseInt(brushColor, 16);
|
||||
data[i + 1] = parseInt(brushColor, 16);
|
||||
data[i + 2] = parseInt(brushColor, 16);
|
||||
}
|
||||
}
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
}
|
||||
}
|
||||
}, [brushColor]);
|
||||
|
||||
const _handleMouseDown = (
|
||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
||||
) => {
|
||||
const {
|
||||
nativeEvent: { offsetX, offsetY },
|
||||
} = e;
|
||||
|
||||
setIsUpdating(true);
|
||||
};
|
||||
|
||||
const _handleMouseUp = (
|
||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
||||
) => {
|
||||
setIsUpdating(false);
|
||||
const canvas = drawingRef.current;
|
||||
if (canvas != null) {
|
||||
const data = canvas.toDataURL();
|
||||
setData(data);
|
||||
}
|
||||
};
|
||||
|
||||
const _drawCanvas = (x: number, y: number, brushSize: number, brushShape: string, brushColor: string | CanvasGradient | CanvasPattern) => {
|
||||
const canvas = drawingRef.current;
|
||||
if (canvas != null) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (ctx != null) {
|
||||
if (isErasing) {
|
||||
// stack overflow https://stackoverflow.com/questions/10396991/clearing-circular-regions-from-html5-canvas
|
||||
const offset = brushSize / 2;
|
||||
ctx.clearRect(x - offset, y - offset, brushSize, brushSize);
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = brushSize;
|
||||
// @ts-expect-error
|
||||
ctx.lineCap = brushShape;
|
||||
ctx.strokeStyle = brushColor;
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const _drawCursor = (
|
||||
x: number,
|
||||
y: number,
|
||||
brushSize: number,
|
||||
brushShape: string,
|
||||
brushColor: string
|
||||
) => {
|
||||
const canvas = cursorRef.current;
|
||||
if (canvas != null) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (ctx != null) {
|
||||
ctx.beginPath();
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
if (isErasing) {
|
||||
const offset = brushSize / 2;
|
||||
// draw a quare
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "butt";
|
||||
ctx.strokeStyle = brushColor;
|
||||
ctx.moveTo(x - offset, y - offset);
|
||||
ctx.lineTo(x + offset, y - offset);
|
||||
ctx.lineTo(x + offset, y + offset);
|
||||
ctx.lineTo(x - offset, y + offset);
|
||||
ctx.lineTo(x - offset, y - offset);
|
||||
ctx.stroke();
|
||||
} else {
|
||||
ctx.lineWidth = brushSize;
|
||||
// @ts-expect-error
|
||||
ctx.lineCap = brushShape;
|
||||
ctx.strokeStyle = brushColor;
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const _handleMouseMove = (
|
||||
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
|
||||
) => {
|
||||
const {
|
||||
nativeEvent: { offsetX: x, offsetY: y },
|
||||
} = e;
|
||||
|
||||
_drawCursor(x, y, brushSize, brushShape, brushColor);
|
||||
|
||||
if (isUpdating) {
|
||||
_drawCanvas(x, y, brushSize, brushShape, brushColor);
|
||||
}
|
||||
};
|
||||
|
||||
// function for external use
|
||||
const fillCanvas = () => {
|
||||
const canvas = drawingRef.current;
|
||||
if (canvas != null) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (ctx != null) {
|
||||
ctx.fillStyle = brushColor;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={DrawImageMain}>
|
||||
<img src={imageData} />
|
||||
<canvas
|
||||
ref={drawingRef}
|
||||
width={canvasWidth}
|
||||
height={canvasHeight}
|
||||
></canvas>
|
||||
<canvas
|
||||
ref={cursorRef}
|
||||
width={canvasWidth}
|
||||
height={canvasHeight}
|
||||
onMouseDown={_handleMouseDown}
|
||||
onMouseUp={_handleMouseUp}
|
||||
onMouseMove={_handleMouseMove}
|
||||
></canvas>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
export const generatedImageMain = style({
|
||||
position: "relative",
|
||||
});
|
||||
|
||||
globalStyle(`${generatedImageMain} img`, {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
});
|
@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import { ImageRequest } from "../../../api";
|
||||
|
||||
import {
|
||||
generatedImageMain,
|
||||
} from "./generatedImage.css";
|
||||
|
||||
interface GeneretaedImageProps {
|
||||
imageData: string | undefined;
|
||||
metadata: ImageRequest | undefined;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function GeneratedImage({
|
||||
imageData,
|
||||
metadata,
|
||||
className,
|
||||
}: GeneretaedImageProps) {
|
||||
return (
|
||||
<div className={[generatedImageMain, className].join(" ")}>
|
||||
<img src={imageData} alt={metadata!.prompt} />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import React, { useEffect, useRef } from "react";
|
||||
|
||||
import { useImageCreate } from "../../../stores/imageCreateStore";
|
||||
import {
|
||||
QueueStatus,
|
||||
useRequestQueue
|
||||
} from "../../../stores/requestQueueStore";
|
||||
|
||||
import {
|
||||
FetchingStates,
|
||||
useImageFetching
|
||||
} from "../../../stores/imageFetchingStore";
|
||||
|
||||
|
||||
import { useImageDisplay } from "../../../stores/imageDisplayStore";
|
||||
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { useRandomSeed } from "../../../utils";
|
||||
import {
|
||||
ImageRequest,
|
||||
ImageReturnType,
|
||||
ImageOutput,
|
||||
doMakeImage,
|
||||
} from "../../../api";
|
||||
|
||||
import {
|
||||
buttonStyle
|
||||
} from "../../_recipes/button.css";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import AudioDing from "../../molecules/audioDing";
|
||||
|
||||
const idDelim = "_batch";
|
||||
|
||||
export default function MakeButton() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const dingRef = useRef<HTMLAudioElement>();
|
||||
|
||||
const parallelCount = useImageCreate((state) => state.parallelCount);
|
||||
const builtRequest = useImageCreate((state) => state.builtRequest);
|
||||
const isRandomSeed = useImageCreate((state) => state.isRandomSeed());
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const isSoundEnabled = useImageCreate((state) => state.isSoundEnabled());
|
||||
|
||||
const addtoQueue = useRequestQueue((state) => state.addtoQueue);
|
||||
const hasQueue = useRequestQueue((state) => state.hasPendingQueue());
|
||||
const { id, options } = useRequestQueue((state) => state.firstInQueue());
|
||||
const updateQueueStatus = useRequestQueue((state) => state.updateStatus);
|
||||
|
||||
const status = useImageFetching((state) => state.status);
|
||||
const setStatus = useImageFetching((state) => state.setStatus);
|
||||
const setStep = useImageFetching((state) => state.setStep);
|
||||
const setTotalSteps = useImageFetching((state) => state.setTotalSteps);
|
||||
const addProgressImage = useImageFetching((state) => state.addProgressImage);
|
||||
const setStartTime = useImageFetching((state) => state.setStartTime);
|
||||
const setNowTime = useImageFetching((state) => state.setNowTime);
|
||||
const resetForFetching = useImageFetching((state) => state.resetForFetching);
|
||||
const appendData = useImageFetching((state) => state.appendData);
|
||||
|
||||
const updateDisplay = useImageDisplay((state) => state.updateDisplay);
|
||||
|
||||
const hackJson = (jsonStr: string, id: string) => {
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(jsonStr);
|
||||
const { status, request, output: outputs } = parsed as ImageReturnType;
|
||||
|
||||
|
||||
if (status === 'succeeded') {
|
||||
|
||||
updateQueueStatus(id, QueueStatus.complete);
|
||||
outputs.forEach((output: any, index: number) => {
|
||||
|
||||
const { data, seed } = output as ImageOutput;
|
||||
const seedReq = {
|
||||
...request,
|
||||
seed,
|
||||
};
|
||||
const batchId = `${id}${idDelim}-${seed}-${index}`;
|
||||
updateDisplay(batchId, data, seedReq);
|
||||
});
|
||||
}
|
||||
|
||||
else {
|
||||
console.warn(`Unexpected status: ${status}`);
|
||||
updateQueueStatus(id, QueueStatus.error);
|
||||
}
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
updateQueueStatus(id, QueueStatus.error);
|
||||
console.warn("Error HACKING JSON: ", e)
|
||||
}
|
||||
}
|
||||
|
||||
const parseRequest = async (id: string, reader: ReadableStreamDefaultReader<Uint8Array>) => {
|
||||
const decoder = new TextDecoder();
|
||||
let finalJSON = '';
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
const jsonStr = decoder.decode(value);
|
||||
if (done) {
|
||||
setStatus(FetchingStates.COMPLETE);
|
||||
hackJson(finalJSON, id);
|
||||
if (isSoundEnabled) {
|
||||
void dingRef.current?.play();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const update = JSON.parse(jsonStr);
|
||||
const { status } = update;
|
||||
|
||||
if (status === "progress") {
|
||||
setStatus(FetchingStates.PROGRESSING);
|
||||
const { progress: { step, total_steps }, output: outputs } = update;
|
||||
setStep(step);
|
||||
setTotalSteps(total_steps);
|
||||
|
||||
if (step === 0) {
|
||||
setStartTime();
|
||||
}
|
||||
else {
|
||||
setNowTime();
|
||||
}
|
||||
|
||||
if (void 0 !== outputs) {
|
||||
outputs.forEach((output: any) => {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
const timePath = `${output.path}?t=${new Date().getTime()}`
|
||||
addProgressImage(timePath);
|
||||
});
|
||||
}
|
||||
|
||||
} else if (status === "succeeded") {
|
||||
// TODO this should be the the new out instead of the try catch
|
||||
// wait for the path to come back instead of the data
|
||||
setStatus(FetchingStates.SUCCEEDED);
|
||||
}
|
||||
else if (status === 'failed') {
|
||||
console.warn('failed');
|
||||
console.warn(update);
|
||||
}
|
||||
else {
|
||||
console.warn("UNKNOWN ?", update);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// console.log('EXPECTED PARSE ERRROR')
|
||||
finalJSON += jsonStr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const startStream = async (id: string, req: ImageRequest) => {
|
||||
|
||||
try {
|
||||
updateQueueStatus(id, QueueStatus.processing);
|
||||
resetForFetching();
|
||||
const res = await doMakeImage(req);
|
||||
const reader = res.body?.getReader();
|
||||
|
||||
if (void 0 !== reader) {
|
||||
void parseRequest(id, reader);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log('TOP LINE STREAM ERROR')
|
||||
updateQueueStatus(id, QueueStatus.error);
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const queueImageRequest = (req: ImageRequest) => {
|
||||
// the actual number of request we will make
|
||||
const requests = [];
|
||||
// the number of images we will make
|
||||
let { num_outputs } = req;
|
||||
if (parallelCount > num_outputs) {
|
||||
requests.push(num_outputs);
|
||||
} else {
|
||||
// while we have at least 1 image to make
|
||||
while (num_outputs >= 1) {
|
||||
// subtract the parallel count from the number of images to make
|
||||
num_outputs -= parallelCount;
|
||||
|
||||
// if we are still 0 or greater we can make the full parallel count
|
||||
if (num_outputs <= 0) {
|
||||
requests.push(parallelCount);
|
||||
}
|
||||
// otherwise we can only make the remaining images
|
||||
else {
|
||||
requests.push(Math.abs(num_outputs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requests.forEach((num, index) => {
|
||||
// get the seed we want to use
|
||||
let seed = req.seed;
|
||||
if (index !== 0) {
|
||||
// we want to use a random seed for subsequent requests
|
||||
seed = useRandomSeed();
|
||||
}
|
||||
// add the request to the queue
|
||||
addtoQueue(uuidv4(), {
|
||||
...req,
|
||||
// updated the number of images to make
|
||||
num_outputs: num,
|
||||
// update the seed
|
||||
seed,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const makeImageQueue = async () => {
|
||||
// potentially update the seed
|
||||
if (isRandomSeed) {
|
||||
// update the seed for the next time we click the button
|
||||
setRequestOption("seed", useRandomSeed());
|
||||
}
|
||||
// the request that we have built
|
||||
const req = builtRequest();
|
||||
queueImageRequest(req);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const makeImages = async (options: ImageRequest) => {
|
||||
// removeFirstInQueue();
|
||||
await startStream(id ?? "", options);
|
||||
}
|
||||
|
||||
if (status === FetchingStates.PROGRESSING || status === FetchingStates.FETCHING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasQueue) {
|
||||
|
||||
if (options === undefined) {
|
||||
console.log('req is undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
makeImages(options).catch((e) => {
|
||||
console.log('HAS QUEUE ERROR');
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
}, [hasQueue, status, id, options, startStream]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className={buttonStyle({
|
||||
size: "large",
|
||||
})}
|
||||
onClick={() => {
|
||||
void makeImageQueue();
|
||||
}}
|
||||
>
|
||||
{t("home.make-img-btn")}
|
||||
</button>
|
||||
<AudioDing ref={dingRef}></AudioDing>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {
|
||||
ModifierPreview,
|
||||
useImageCreate
|
||||
} from "../../../stores/imageCreateStore";
|
||||
|
||||
import { API_URL } from "../../../api";
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
} from "../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
ModifierTagMain,
|
||||
ModifierActions,
|
||||
tagPreview,
|
||||
TagText,
|
||||
TagToggle,
|
||||
} from "./modifierTags.css";
|
||||
|
||||
interface ModifierTagProps {
|
||||
name: string;
|
||||
category: string;
|
||||
previews: ModifierPreview[];
|
||||
}
|
||||
|
||||
export default function ModifierTag({ name, category, previews }: ModifierTagProps) {
|
||||
|
||||
const previewType: 'portrait' | 'landscape' = "portrait";
|
||||
|
||||
const [showActions, setShowActions] = useState(false);
|
||||
|
||||
const handleHover = () => {
|
||||
setShowActions(true);
|
||||
};
|
||||
|
||||
const handleLeave = () => {
|
||||
setShowActions(false);
|
||||
};
|
||||
|
||||
const addCreateTag = useImageCreate((state) => state.addCreateTag);
|
||||
const setPositivePrompt = () => {
|
||||
addCreateTag({ id: uuidv4(), name, type: 'positive' });
|
||||
}
|
||||
const setNegativePrompt = () => {
|
||||
addCreateTag({ id: uuidv4(), name, type: 'negative' });
|
||||
}
|
||||
|
||||
|
||||
const hasTag = useImageCreate((state) => state.hasTag(category, name))
|
||||
? "selected"
|
||||
: "";
|
||||
const toggleTag = useImageCreate((state) => state.toggleTag);
|
||||
|
||||
const _toggleTag = () => {
|
||||
toggleTag(category, name);
|
||||
};
|
||||
|
||||
// , hasTag].join(" ")
|
||||
return (
|
||||
<div className={ModifierTagMain}
|
||||
onMouseEnter={handleHover}
|
||||
onMouseLeave={handleLeave}>
|
||||
<p className={!showActions ? TagText : TagToggle}>{name}</p>
|
||||
{showActions && (
|
||||
<div className={ModifierActions}>
|
||||
<button onClick={setPositivePrompt}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-plus'].join(" ")}></i>
|
||||
</button>
|
||||
<button onClick={setNegativePrompt}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-minus'].join(" ")}></i>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{/* <div className={tagPreview}>
|
||||
{previews.map((preview) => {
|
||||
if (preview.name !== previewType) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<img
|
||||
key={preview.name}
|
||||
src={`${API_URL}/media/modifier-thumbnails/${preview.path}`}
|
||||
alt={preview.name}
|
||||
title={preview.name}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from '../../../styles/theme/index.css';
|
||||
|
||||
import { card } from '../../_recipes/card.css';
|
||||
|
||||
export const ModifierTagMain = style([
|
||||
card({
|
||||
backing: 'normal',
|
||||
level: 1,
|
||||
info: true
|
||||
}), {
|
||||
position: "relative",
|
||||
width: "fit-content",
|
||||
borderColor: `hsl(${vars.brandHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
padding: vars.spacing.small,
|
||||
}
|
||||
]);
|
||||
|
||||
globalStyle(`${ModifierTagMain}.selected`, {
|
||||
backgroundColor: "rgb(131, 11, 121)",
|
||||
})
|
||||
|
||||
globalStyle(`${ModifierTagMain} p`, {
|
||||
margin: 0,
|
||||
textAlign: "center",
|
||||
marginBottom: "2px",
|
||||
});
|
||||
|
||||
|
||||
export const TagText = style({
|
||||
opacity: 1,
|
||||
});
|
||||
|
||||
export const TagToggle = style({
|
||||
opacity: 0.3,
|
||||
});
|
||||
|
||||
|
||||
export const ModifierActions = style({
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
});
|
||||
|
||||
globalStyle(`${ModifierActions} button`, {
|
||||
flexGrow: 1,
|
||||
backgroundColor: "transparent",
|
||||
border: "none",
|
||||
boxShadow: `inset 0 0 24px 0px rgb(255 255 255 / 50%)`,
|
||||
borderRadius: "5px",
|
||||
padding: "0",
|
||||
});
|
||||
|
||||
export const tagPreview = style({
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
});
|
||||
|
||||
globalStyle(`${tagPreview} img`, {
|
||||
width: "90px",
|
||||
height: "100%",
|
||||
objectFit: "cover",
|
||||
objectPosition: "center",
|
||||
});
|
||||
|
@ -1,68 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { useImageCreate } from "../../../stores/imageCreateStore";
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
} from "../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
PromptTagMain,
|
||||
TagToggle,
|
||||
TagRemoveButton,
|
||||
PromptTagText,
|
||||
PromptTagToggle
|
||||
} from "./promptTag.css";
|
||||
|
||||
interface PromptTagProps {
|
||||
id: string;
|
||||
name: string;
|
||||
category?: string;
|
||||
previews?: string[];
|
||||
type: string;
|
||||
};
|
||||
|
||||
export default function PromptTag({ id, name, category, previews, type }: PromptTagProps) {
|
||||
|
||||
const [showToggle, setShowToggle] = useState(false);
|
||||
|
||||
const removeCreateTag = useImageCreate((state) => state.removeCreateTag);
|
||||
const changeCreateTagType = useImageCreate((state) => state.changeCreateTagType);
|
||||
|
||||
const handleHover = () => {
|
||||
setShowToggle(true);
|
||||
};
|
||||
|
||||
const handleLeave = () => {
|
||||
setShowToggle(false);
|
||||
};
|
||||
|
||||
const toggleType = () => {
|
||||
if (type === 'positive') {
|
||||
changeCreateTagType(id, 'negative');
|
||||
}
|
||||
else {
|
||||
changeCreateTagType(id, 'positive');
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
console.log('remove');
|
||||
removeCreateTag(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={handleHover}
|
||||
onMouseLeave={handleLeave}
|
||||
className={[PromptTagMain, type].join(' ')}>
|
||||
<p className={!showToggle ? PromptTagText : PromptTagToggle}>{name}</p>
|
||||
{showToggle && <button className={TagToggle} onClick={toggleType}>
|
||||
{type === 'positive' ? <i className={[IconFont, 'fa-solid', 'fa-minus'].join(" ")}></i> : <i className={[IconFont, 'fa-solid', 'fa-plus'].join(" ")}></i>}
|
||||
</button>}
|
||||
{showToggle && <button className={TagRemoveButton} onClick={handleRemove}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-close'].join(" ")}></i>
|
||||
</button>}
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import { style, globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
import { XButton } from "../../../styles/shared.css";
|
||||
import { vars } from '../../../styles/theme/index.css';
|
||||
import { card } from '../../_recipes/card.css';
|
||||
|
||||
|
||||
export const PromptTagMain = style([
|
||||
card({
|
||||
backing: 'normal',
|
||||
level: 1,
|
||||
info: true
|
||||
}), {
|
||||
position: "relative",
|
||||
width: "fit-content",
|
||||
backgroundColor: `hsl(${vars.backgroundLight}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
padding: vars.spacing.small,
|
||||
}
|
||||
]);
|
||||
|
||||
export const PromptTagText = style({
|
||||
opacity: 1,
|
||||
fontSize: vars.fonts.sizes.Plain,
|
||||
});
|
||||
|
||||
export const PromptTagToggle = style({
|
||||
opacity: 0.3,
|
||||
fontSize: vars.fonts.sizes.Plain,
|
||||
});
|
||||
|
||||
globalStyle(`${PromptTagMain}.positive`, {
|
||||
borderColor: `hsl(${vars.brandHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
||||
|
||||
globalStyle(`${PromptTagMain}.negative`, {
|
||||
borderColor: `hsl(${vars.errorHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
||||
|
||||
export const TagToggle = style({
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
right: "0",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
border: "none",
|
||||
backgroundColor: "transparent",
|
||||
boxShadow: `inset 0 0 24px 0px rgb(255 255 255 / 50%)`,
|
||||
});
|
||||
|
||||
export const TagRemoveButton = style([XButton, {
|
||||
top: '-4px',
|
||||
left: '4px',
|
||||
padding: '0',
|
||||
}]);
|
@ -1,70 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { FetchingStates, useImageFetching } from "../../../stores/imageFetchingStore";
|
||||
import { useRequestQueue } from "../../../stores/requestQueueStore";
|
||||
|
||||
export default function QueueStatusTab() {
|
||||
|
||||
|
||||
const [showBasicQueue, setShowBasicQueue] = useState(true);
|
||||
|
||||
const hasPendingQueue = useRequestQueue((state) => state.hasPendingQueue());
|
||||
const pendingRequests = useRequestQueue((state) => state.pendingRequests());
|
||||
|
||||
const status = useImageFetching((state) => state.status);
|
||||
|
||||
const step = useImageFetching((state) => state.step);
|
||||
const totalSteps = useImageFetching((state) => state.totalSteps);
|
||||
|
||||
const startTime = useImageFetching((state) => state.timeStarted);
|
||||
const timeNow = useImageFetching((state) => state.timeNow);
|
||||
const [timeRemaining, setTimeRemaining] = useState(0);
|
||||
|
||||
const [percent, setPercent] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (totalSteps > 0) {
|
||||
setPercent(Math.round((step / totalSteps) * 100));
|
||||
} else {
|
||||
setPercent(0);
|
||||
}
|
||||
}, [step, totalSteps]);
|
||||
|
||||
useEffect(() => {
|
||||
// find the remaining time
|
||||
const timeTaken = +timeNow - +startTime;
|
||||
const timePerStep = step == 0 ? 0 : timeTaken / step;
|
||||
const totalTime = timePerStep * totalSteps;
|
||||
const timeRemaining = (totalTime - timeTaken) / 1000;
|
||||
// @ts-expect-error
|
||||
setTimeRemaining(timeRemaining.toPrecision(3));
|
||||
|
||||
}, [step, totalSteps, startTime, timeNow, setTimeRemaining]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasPendingQueue) {
|
||||
setShowBasicQueue(false);
|
||||
}
|
||||
}, [status, hasPendingQueue]);
|
||||
|
||||
// {/* {showBasicQueue
|
||||
// ? <> */}
|
||||
// Queue
|
||||
// {/* </>
|
||||
// : <>
|
||||
// <span>Percent: {percent}%</span>
|
||||
// </>npm
|
||||
// } */}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>Queue </span>
|
||||
{hasPendingQueue && <span> Items Remaining: {pendingRequests.length} </span>}
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
import { doStopImage } from "../../../api";
|
||||
|
||||
|
||||
import {
|
||||
buttonStyle
|
||||
} from "../../_recipes/button.css";
|
||||
|
||||
export default function StopButton() {
|
||||
|
||||
const stopMake = async () => {
|
||||
try {
|
||||
const res = await doStopImage();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
return <button className={buttonStyle(
|
||||
{
|
||||
color: "cancel",
|
||||
size: "large",
|
||||
}
|
||||
)} onClick={() => void stopMake()}>Stop</button>;
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
import { vars } from "../../../styles/theme/index.css";
|
||||
import {
|
||||
card as cardStyle,
|
||||
} from '../../_recipes/card.css'
|
||||
|
||||
export const completedImagesMain = style({
|
||||
position: "relative",
|
||||
});
|
||||
|
||||
// globalStyle(`${completedImagesMain} > button`, {
|
||||
// position: "absolute",
|
||||
// top: '-29px',
|
||||
// });
|
||||
|
||||
export const completedImagesContent = style([cardStyle(), {
|
||||
height: "250px",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
padding: vars.spacing.medium,
|
||||
borderRadius: 0,
|
||||
}]);
|
||||
|
||||
export const completedImagesList = style({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
flexWrap: "nowrap",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
overflow: "auto",
|
||||
paddingLeft: vars.spacing.none,
|
||||
});
|
||||
|
||||
globalStyle(`${completedImagesContent} li`, {
|
||||
position: "relative",
|
||||
});
|
||||
|
||||
globalStyle(`${completedImagesContent} > li:first-of-type`, {
|
||||
marginLeft: vars.spacing.medium,
|
||||
});
|
||||
|
||||
globalStyle(`${completedImagesContent} > li:last-of-type`, {
|
||||
marginRight: 0,
|
||||
});
|
||||
|
||||
export const imageContain = style({
|
||||
width: "206px",
|
||||
backgroundColor: "black",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexShrink: 0,
|
||||
border: "0 none",
|
||||
padding: "0",
|
||||
marginLeft: vars.spacing.medium,
|
||||
cursor: "pointer",
|
||||
});
|
||||
|
||||
globalStyle(`${imageContain} img`, {
|
||||
width: "100%",
|
||||
objectFit: "contain",
|
||||
});
|
@ -1,87 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
|
||||
import { useImageDisplay } from "../../../stores/imageDisplayStore";
|
||||
|
||||
import {
|
||||
completedImagesMain,
|
||||
completedImagesContent,
|
||||
completedImagesList,
|
||||
imageContain,
|
||||
} from "./completedImages.css";
|
||||
|
||||
import {
|
||||
buttonStyle
|
||||
} from "../../_recipes/button.css";
|
||||
|
||||
// import { Transition } from '@headlessui/react'
|
||||
|
||||
|
||||
// import {
|
||||
// tabStyles
|
||||
// } from "../../_recipes/tabs_headless.css";
|
||||
|
||||
export default function CompletedImages(
|
||||
|
||||
) {
|
||||
|
||||
const [isShowing, setIsShowing] = useState(false)
|
||||
|
||||
|
||||
const images = useImageDisplay((state) => state.images);
|
||||
const setCurrentImage = useImageDisplay((state) => state.setCurrentImage);
|
||||
const clearDisplay = useImageDisplay((state) => state.clearDisplay);
|
||||
|
||||
const removeImagesAll = () => {
|
||||
clearDisplay();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={completedImagesMain}>
|
||||
{/* <button
|
||||
className={tabStyles({})}
|
||||
onClick={() => setIsShowing((isShowing) => !isShowing)}>
|
||||
{isShowing ? "Hide History" : "Show History"}
|
||||
</button> */}
|
||||
{/* <Transition
|
||||
show={isShowing}
|
||||
> */}
|
||||
|
||||
<div className={completedImagesContent}>
|
||||
{/* Adjust the dom do we dont do this check twice */}
|
||||
{images != null && images.length > 0 && (
|
||||
<button
|
||||
className={buttonStyle()}
|
||||
onClick={() => {
|
||||
removeImagesAll();
|
||||
}}
|
||||
>
|
||||
REMOVE ALL
|
||||
</button>
|
||||
)}
|
||||
<ul className={completedImagesList}>
|
||||
{images?.map((image, index) => {
|
||||
if (void 0 === image) {
|
||||
console.warn(`image ${index} is undefined`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<li key={image.id}>
|
||||
<button
|
||||
className={imageContain}
|
||||
onClick={() => {
|
||||
setCurrentImage(image);
|
||||
}}
|
||||
>
|
||||
<img src={image.data} alt={image.info.prompt} />
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
{/* </Transition> */}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
import { vars } from "../../../../styles/theme/index.css";
|
||||
|
||||
export const AdvancedSettingsList = style({
|
||||
paddingLeft: 0,
|
||||
listStyleType: "none",
|
||||
});
|
||||
|
||||
export const AdvancedSettingGrouping = style({
|
||||
marginTop: vars.spacing.small,
|
||||
});
|
@ -1,119 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useImageCreate } from "../../../../../stores/imageCreateStore";
|
||||
|
||||
import { useCreateUI } from "../../creationPanelUIStore";
|
||||
|
||||
import {
|
||||
SettingItem,
|
||||
} from "../../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../../_recipes/button.css";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function ImprovementSettings() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// these are conditionals that should be retired and inferred from the store
|
||||
const isUsingFaceCorrection = useImageCreate((state) =>
|
||||
state.isUsingFaceCorrection()
|
||||
);
|
||||
|
||||
const isUsingUpscaling = useImageCreate((state) => state.isUsingUpscaling());
|
||||
|
||||
const useUpscale = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("use_upscale")
|
||||
);
|
||||
|
||||
const filteredOnly = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("show_only_filtered_image")
|
||||
);
|
||||
|
||||
const toggleUseFaceCorrection = useImageCreate(
|
||||
(state) => state.toggleUseFaceCorrection
|
||||
);
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const improvementOpen = useCreateUI(
|
||||
(state) => state.isOpenAdvImprovementSettings
|
||||
);
|
||||
|
||||
const toggleImprovementOpen = useCreateUI(
|
||||
(state) => state.toggleAdvImprovementSettings
|
||||
);
|
||||
|
||||
const [isFilteringDisabled, setIsFilteringDisabled] = useState(false);
|
||||
// should probably be a store selector
|
||||
useEffect(() => {
|
||||
// if either are true we arent disabled
|
||||
if (isUsingFaceCorrection || useUpscale != "") {
|
||||
setIsFilteringDisabled(false);
|
||||
} else {
|
||||
setIsFilteringDisabled(true);
|
||||
}
|
||||
}, [isUsingFaceCorrection, isUsingUpscaling, setIsFilteringDisabled]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className={buttonStyle({
|
||||
type: 'action',
|
||||
color: 'accent',
|
||||
})}
|
||||
onClick={toggleImprovementOpen}
|
||||
>
|
||||
Improvement Settings
|
||||
</button>
|
||||
{improvementOpen && (
|
||||
<>
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isUsingFaceCorrection}
|
||||
onChange={(e) => toggleUseFaceCorrection()}
|
||||
/>
|
||||
Fix incorrect faces and eyes (uses GFPGAN)
|
||||
</label>
|
||||
</div>
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.ups")}
|
||||
<select
|
||||
id="upscale_model"
|
||||
name="upscale_model"
|
||||
value={useUpscale}
|
||||
onChange={(e) => {
|
||||
setRequestOption("use_upscale", e.target.value);
|
||||
}}
|
||||
>
|
||||
<option value="">{t("settings.no-ups")}</option>
|
||||
<option value="RealESRGAN_x4plus">RealESRGAN_x4plus</option>
|
||||
<option value="RealESRGAN_x4plus_anime_6B">
|
||||
RealESRGAN_x4plus_anime_6B
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
disabled={isFilteringDisabled}
|
||||
type="checkbox"
|
||||
checked={filteredOnly}
|
||||
onChange={(e) =>
|
||||
setRequestOption("show_only_filtered_image", e.target.checked)
|
||||
}
|
||||
/>
|
||||
{t("settings.corrected")}
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useCreateUI } from "../creationPanelUIStore";
|
||||
|
||||
|
||||
|
||||
import {
|
||||
card
|
||||
} from '../../../_recipes/card.css';
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../_recipes/button.css";
|
||||
|
||||
import {
|
||||
AdvancedSettingsList,
|
||||
AdvancedSettingGrouping,
|
||||
} from "./advancedsettings.css";
|
||||
|
||||
import ImprovementSettings from "./improvementSettings";
|
||||
import PropertySettings from "./propertySettings";
|
||||
import WorkflowSettings from "./workflowSettings";
|
||||
|
||||
function SettingsList() {
|
||||
return (
|
||||
<ul className={AdvancedSettingsList}>
|
||||
<li className={AdvancedSettingGrouping}>
|
||||
<ImprovementSettings />
|
||||
</li>
|
||||
<li className={AdvancedSettingGrouping}>
|
||||
<PropertySettings />
|
||||
</li>
|
||||
<li className={AdvancedSettingGrouping}>
|
||||
<WorkflowSettings />
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AdvancedSettings() {
|
||||
const advancedSettingsIsOpen = useCreateUI(
|
||||
(state) => state.isOpenAdvancedSettings
|
||||
);
|
||||
|
||||
const toggleAdvancedSettingsIsOpen = useCreateUI(
|
||||
(state) => state.toggleAdvancedSettings
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={card(
|
||||
{
|
||||
level: 1,
|
||||
backing: 'normal'
|
||||
}
|
||||
)}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={toggleAdvancedSettingsIsOpen}
|
||||
className={buttonStyle({
|
||||
type: 'action',
|
||||
color: 'secondary',
|
||||
size: 'large'
|
||||
})}
|
||||
>
|
||||
Advanced Settings
|
||||
</button>
|
||||
{advancedSettingsIsOpen && <SettingsList />}
|
||||
</div >
|
||||
);
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
import React from "react";
|
||||
import { useImageCreate, SAMPLER_OPTIONS } from "../../../../../stores/imageCreateStore";
|
||||
import { useCreateUI } from "../../creationPanelUIStore";
|
||||
|
||||
import {
|
||||
SettingItem,
|
||||
} from "../../../../../styles/shared.css";
|
||||
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../../_recipes/button.css";
|
||||
|
||||
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// todo: move this someplace more global
|
||||
const IMAGE_DIMENSIONS = [
|
||||
{ value: 128, label: "128 (*)" },
|
||||
{ value: 192, label: "192" },
|
||||
{ value: 256, label: "256 (*)" },
|
||||
{ value: 320, label: "320" },
|
||||
{ value: 384, label: "384" },
|
||||
{ value: 448, label: "448" },
|
||||
{ value: 512, label: "512 (*)" },
|
||||
{ value: 576, label: "576" },
|
||||
{ value: 640, label: "640" },
|
||||
{ value: 704, label: "704" },
|
||||
{ value: 768, label: "768 (*)" },
|
||||
{ value: 832, label: "832" },
|
||||
{ value: 896, label: "896" },
|
||||
{ value: 960, label: "960" },
|
||||
{ value: 1024, label: "1024 (*)" },
|
||||
];
|
||||
|
||||
export default function PropertySettings() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
const toggleUseRandomSeed = useImageCreate(
|
||||
(state) => state.toggleUseRandomSeed
|
||||
);
|
||||
const isRandomSeed = useImageCreate((state) => state.isRandomSeed());
|
||||
|
||||
const seed = useImageCreate((state) => state.getValueForRequestKey("seed"));
|
||||
const steps = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("num_inference_steps")
|
||||
);
|
||||
const guidanceScale = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("guidance_scale")
|
||||
);
|
||||
|
||||
const initImage = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("init_image")
|
||||
);
|
||||
|
||||
const promptStrength = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("prompt_strength")
|
||||
);
|
||||
|
||||
const width = useImageCreate((state) => state.getValueForRequestKey("width"));
|
||||
const height = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("height")
|
||||
);
|
||||
|
||||
const sampler = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("sampler")
|
||||
);
|
||||
|
||||
const propertyOpen = useCreateUI((state) => state.isOpenAdvPropertySettings);
|
||||
const togglePropertyOpen = useCreateUI(
|
||||
(state) => state.toggleAdvPropertySettings
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button type="button" className={buttonStyle({
|
||||
type: 'action',
|
||||
color: 'accent',
|
||||
})} onClick={togglePropertyOpen}>
|
||||
Property Settings
|
||||
</button>
|
||||
{propertyOpen && (
|
||||
<>
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
Seed:
|
||||
<input
|
||||
size={10}
|
||||
value={seed}
|
||||
onChange={(e) => setRequestOption("seed", e.target.value)}
|
||||
disabled={isRandomSeed}
|
||||
placeholder="random"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isRandomSeed}
|
||||
onChange={(e) => toggleUseRandomSeed()}
|
||||
/>{" "}
|
||||
Random Image
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.steps")}{" "}
|
||||
<input
|
||||
value={steps}
|
||||
onChange={(e) => {
|
||||
setRequestOption("num_inference_steps", e.target.value);
|
||||
}}
|
||||
size={4}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.guide-scale")}
|
||||
<input
|
||||
value={guidanceScale}
|
||||
onChange={(e) =>
|
||||
setRequestOption("guidance_scale", e.target.value)
|
||||
}
|
||||
type="range"
|
||||
min="0"
|
||||
max="20"
|
||||
step=".1"
|
||||
/>
|
||||
</label>
|
||||
<span>{guidanceScale}</span>
|
||||
</div>
|
||||
|
||||
{void 0 !== initImage && (
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.prompt-str")}{" "}
|
||||
<input
|
||||
value={promptStrength}
|
||||
onChange={(e) =>
|
||||
setRequestOption("prompt_strength", e.target.value)
|
||||
}
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
step=".05"
|
||||
/>
|
||||
</label>
|
||||
<span>{promptStrength}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.width")}
|
||||
<select
|
||||
value={width}
|
||||
onChange={(e) => setRequestOption("width", e.target.value)}
|
||||
>
|
||||
{IMAGE_DIMENSIONS.map((dimension) => (
|
||||
<option
|
||||
key={`width-option_${dimension.value}`}
|
||||
value={dimension.value}
|
||||
>
|
||||
{dimension.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
{t("settings.height")}
|
||||
<select
|
||||
value={height}
|
||||
onChange={(e) => setRequestOption("height", e.target.value)}
|
||||
>
|
||||
{IMAGE_DIMENSIONS.map((dimension) => (
|
||||
<option
|
||||
key={`height-option_${dimension.value}`}
|
||||
value={dimension.value}
|
||||
>
|
||||
{dimension.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.sampler")}
|
||||
<select
|
||||
value={sampler}
|
||||
onChange={(e) => setRequestOption("sampler", e.target.value)}
|
||||
>
|
||||
{SAMPLER_OPTIONS.map((sampler) => (
|
||||
<option key={`sampler-option_${sampler}`} value={sampler}>
|
||||
{sampler}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
import React from "react";
|
||||
import { useImageCreate } from "../../../../../stores/imageCreateStore";
|
||||
|
||||
import { useCreateUI } from "../../creationPanelUIStore";
|
||||
|
||||
import {
|
||||
SettingItem,
|
||||
} from "../../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../../_recipes/button.css";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function WorkflowSettings() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const numOutputs = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("num_outputs")
|
||||
);
|
||||
const parallelCount = useImageCreate((state) => state.parallelCount);
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
const setParallelCount = useImageCreate((state) => state.setParallelCount);
|
||||
const shouldStreamImages = useImageCreate((state) => state.getValueForRequestKey("stream_image_progress"));
|
||||
|
||||
const workflowOpen = useCreateUI((state) => state.isOpenAdvWorkflowSettings);
|
||||
const toggleWorkflowOpen = useCreateUI(
|
||||
(state) => state.toggleAdvWorkflowSettings
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button type="button" className={buttonStyle({
|
||||
type: 'action',
|
||||
color: 'accent',
|
||||
})} onClick={toggleWorkflowOpen}>
|
||||
Workflow Settings
|
||||
</button>
|
||||
{workflowOpen && (
|
||||
<>
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.amount-of-img")}{" "}
|
||||
<input
|
||||
type="number"
|
||||
value={numOutputs}
|
||||
onChange={(e) =>
|
||||
setRequestOption("num_outputs", parseInt(e.target.value, 10))
|
||||
}
|
||||
size={4}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.how-many")}
|
||||
<input
|
||||
type="number"
|
||||
value={parallelCount}
|
||||
onChange={(e) => setParallelCount(parseInt(e.target.value, 10))}
|
||||
size={4}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className={SettingItem}>
|
||||
<label>
|
||||
{t("settings.stream-img")}
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={shouldStreamImages}
|
||||
onChange={(e) =>
|
||||
setRequestOption("stream_image_progress", e.target.checked)
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
import { card } from "../../../_recipes/card.css";
|
||||
|
||||
|
||||
export const CreationBasicMain = style([
|
||||
card({
|
||||
backing: 'normal',
|
||||
level: 1
|
||||
}), {
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
}]
|
||||
);
|
||||
|
||||
export const PromptDisplay = style({});
|
||||
|
||||
globalStyle(`${CreationBasicMain} > *`, {
|
||||
marginBottom: '10px'
|
||||
});
|
@ -1,37 +0,0 @@
|
||||
import React, { ChangeEvent } from "react";
|
||||
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
||||
|
||||
import {
|
||||
CreationBasicMain,
|
||||
PromptDisplay,
|
||||
} from "./basicCreation.css";
|
||||
|
||||
import MakeButton from "../../../molecules/makeButton";
|
||||
|
||||
import PromptCreator from "./promptCreator";
|
||||
// import CreationActions from "./creationActions";
|
||||
import SeedImage from "./seedImage";
|
||||
import ActiveTags from "./promptCreator/activeTags";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function BasicCreation() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const promptText = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("prompt")
|
||||
);
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const handlePromptChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setRequestOption("prompt", event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={CreationBasicMain}>
|
||||
<MakeButton></MakeButton>
|
||||
<PromptCreator></PromptCreator>
|
||||
<SeedImage></SeedImage>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
import { vars } from '../../../../../../styles/theme/index.css';
|
||||
export const ActiveTagListMain = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: '10px',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflow: 'visible',
|
||||
scrollbarWidth: 'none',
|
||||
msOverflowStyle: 'none',
|
||||
'::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import { useImageCreate } from "../../../../../../stores/imageCreateStore";
|
||||
import ModifierTag from "../../../../../molecules/modifierTag";
|
||||
|
||||
// import {
|
||||
// card
|
||||
// } from '../../../../../_recipes/card.css';
|
||||
|
||||
|
||||
|
||||
import PromptTag from "../../../../../molecules/promptTag";
|
||||
|
||||
import {
|
||||
ActiveTagListMain
|
||||
} from "./activeTags.css";
|
||||
|
||||
|
||||
export default function ActiveTags() {
|
||||
const selectedtags = useImageCreate((state) => state.selectedTags());
|
||||
|
||||
const createTags = useImageCreate((state) => state.createTags);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul className={ActiveTagListMain}>
|
||||
{createTags.map((tag) => {
|
||||
console.log(tag);
|
||||
return (
|
||||
<li key={tag.id}>
|
||||
{/* @ts-expect-error */}
|
||||
<PromptTag id={tag.id} name={tag.name} category={tag?.category} previews={tag?.previews} type={tag.type} />
|
||||
</li>)
|
||||
}
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
import React, { useState, ChangeEvent, KeyboardEventHandler, Fragment } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { Switch } from '@headlessui/react'
|
||||
|
||||
import { useImageCreate } from "../../../../../stores/imageCreateStore";
|
||||
|
||||
import ActiveTags from "./activeTags";
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
} from "../../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../../_recipes/button.css";
|
||||
|
||||
import {
|
||||
PromptCreatorMain,
|
||||
ToggleGroupMain,
|
||||
ToggleMain,
|
||||
ToggleLabel,
|
||||
ToggleEnabled,
|
||||
TogglePill,
|
||||
buttonRow,
|
||||
} from "./promptCreator.css";
|
||||
|
||||
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { type } from "os";
|
||||
|
||||
interface TagTypeProps {
|
||||
positive: boolean;
|
||||
setPositive: (positive: boolean) => void;
|
||||
};
|
||||
|
||||
function TagTypeToggle({ positive, setPositive }: TagTypeProps) {
|
||||
return (
|
||||
<Switch.Group as={Fragment}>
|
||||
<div className={ToggleGroupMain}>
|
||||
<Switch.Label> Type </Switch.Label>
|
||||
<Switch className={ToggleMain} checked={positive} onChange={setPositive}>
|
||||
<span
|
||||
className={TogglePill}
|
||||
>
|
||||
{positive
|
||||
? <i className={[IconFont, 'fa-solid', 'fa-plus'].join(" ")}></i>
|
||||
: <i className={[IconFont, 'fa-solid', 'fa-minus'].join(" ")}></i>}
|
||||
</span>
|
||||
</Switch>
|
||||
</div>
|
||||
</Switch.Group>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PromptCreator() {
|
||||
|
||||
const [positive, setPositive] = useState(true)
|
||||
const [tagText, setTagText] = useState('An astronaut riding a horse');
|
||||
|
||||
const addCreateTag = useImageCreate((state) => state.addCreateTag);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const checkForEnter = (event: KeyboardEventHandler<HTMLInputElement>) => {
|
||||
// @ts-expect-error
|
||||
if (event.key === "Enter") {
|
||||
if (tagText !== '') {
|
||||
const type = positive ? "positive" : "negative";
|
||||
|
||||
tagText.split(',').map((tag) => tag.trim()).forEach((tag) => {
|
||||
addCreateTag({ id: uuidv4(), name: tag, type });
|
||||
});
|
||||
//debugger;
|
||||
|
||||
setTagText('');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={PromptCreatorMain}>
|
||||
<div>
|
||||
<p>{t("home.editor-title")}</p>
|
||||
{/* @ts-expect-error */}
|
||||
<input value={tagText} onKeyDown={checkForEnter} onChange={(event) => {
|
||||
setTagText(event.target.value)
|
||||
}}></input>
|
||||
</div>
|
||||
<div className={buttonRow}>
|
||||
<button
|
||||
className={buttonStyle(
|
||||
{
|
||||
size: 'slim'
|
||||
}
|
||||
)}
|
||||
onClick={() => {
|
||||
}}
|
||||
>
|
||||
Add Prompt
|
||||
</button>
|
||||
|
||||
<TagTypeToggle positive={positive} setPositive={setPositive}></TagTypeToggle>
|
||||
</div>
|
||||
<ActiveTags></ActiveTags>
|
||||
</div >
|
||||
);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import { style, globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
import { vars } from "../../../../../styles/theme/index.css";
|
||||
|
||||
export const PromptCreatorMain = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
marginBottom: 0,
|
||||
});
|
||||
|
||||
globalStyle(`${PromptCreatorMain} input`, {
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
globalStyle(`${PromptCreatorMain} > div`, {
|
||||
marginBottom: vars.spacing.small,
|
||||
});
|
||||
|
||||
export const ToggleGroupMain = style({
|
||||
// '--toggle-size': '30px',
|
||||
});
|
||||
|
||||
export const ToggleMain = style({
|
||||
background: vars.backgroundDark,
|
||||
height: '22px',
|
||||
borderRadius: '15px',
|
||||
width: '34px',
|
||||
border: 0,
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
padding: 0,
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: `0 0 2px 0 ${vars.backgroundDark}`,
|
||||
});
|
||||
|
||||
export const ToggleLabel = style({
|
||||
});
|
||||
|
||||
export const ToggleEnabled = style({
|
||||
});
|
||||
|
||||
globalStyle(`${ToggleMain}[data-headlessui-state="checked"]`, {
|
||||
background: vars.backgroundLight,
|
||||
});
|
||||
|
||||
export const TogglePill = style({
|
||||
display: 'inline-flex',
|
||||
height: '18px',
|
||||
width: '30px',
|
||||
borderRadius: '15px',
|
||||
background: vars.backgroundDark,
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
});
|
||||
|
||||
globalStyle(`${ToggleMain}[data-headlessui-state="checked"] ${TogglePill}`, {
|
||||
background: vars.backgroundAccentMain,
|
||||
});
|
||||
|
||||
globalStyle(`${TogglePill} p`, {
|
||||
color: vars.colors.text.normal,
|
||||
});
|
||||
|
||||
|
||||
export const buttonRow = style({
|
||||
marginTop: vars.spacing.small,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
});
|
||||
|
||||
globalStyle(`${buttonRow} > button`, {
|
||||
flexGrow: 1,
|
||||
marginRight: vars.spacing.medium,
|
||||
});
|
@ -1,108 +0,0 @@
|
||||
import React, { useRef, ChangeEvent } from "react";
|
||||
|
||||
|
||||
|
||||
import { XButton } from "../../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
ImageInputDisplay,
|
||||
InputLabel,
|
||||
ImageInput,
|
||||
ImageFixer,
|
||||
} from "./seedImage.css";
|
||||
|
||||
import {
|
||||
buttonStyle
|
||||
} from "../../../../_recipes/button.css";
|
||||
|
||||
import { useImageCreate } from "../../../../../stores/imageCreateStore";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// TODO : figure out why this needs props to be passed in.. fixes a type error
|
||||
// when the component is used in the parent component
|
||||
export default function SeedImage(_props: any) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const imageInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const initImage = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("init_image")
|
||||
);
|
||||
|
||||
const isInPaintingMode = useImageCreate((state) => state.isInpainting);
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const _startFileSelect = () => {
|
||||
imageInputRef.current?.click();
|
||||
};
|
||||
const _handleFileSelect = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
// @ts-expect-error
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (void 0 !== file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
if (e.target != null) {
|
||||
setRequestOption("init_image", e.target.result);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleInpainting = useImageCreate((state) => state.toggleInpainting);
|
||||
|
||||
const _handleClearImage = () => {
|
||||
setRequestOption("init_image", undefined);
|
||||
|
||||
setRequestOption("mask", undefined);
|
||||
if (isInPaintingMode) {
|
||||
toggleInpainting();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={ImageInputDisplay}>
|
||||
<div>
|
||||
<label className={InputLabel}>
|
||||
<b>{t("home.initial-img-txt")}</b>
|
||||
</label>
|
||||
<input
|
||||
ref={imageInputRef}
|
||||
className={ImageInput}
|
||||
name="init_image"
|
||||
type="file"
|
||||
onChange={_handleFileSelect}
|
||||
/>
|
||||
<button className={buttonStyle()} onClick={_startFileSelect}>
|
||||
{t("home.initial-img-btn")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className={ImageFixer}>
|
||||
{void 0 !== initImage && (
|
||||
<>
|
||||
<div>
|
||||
<img src={initImage} width="100" height="100" />
|
||||
<button className={XButton} onClick={_handleClearImage}>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
onChange={(e) => {
|
||||
toggleInpainting();
|
||||
}}
|
||||
checked={isInPaintingMode}
|
||||
></input>
|
||||
{t("in-paint.txt")}
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { style } from "@vanilla-extract/css";
|
||||
|
||||
import { vars } from "../../../../../styles/theme/index.css";
|
||||
|
||||
export const ImageInputDisplay = style({
|
||||
display: "flex",
|
||||
});
|
||||
|
||||
export const InputLabel = style({
|
||||
marginBottom: vars.spacing.small,
|
||||
display: "block",
|
||||
});
|
||||
|
||||
export const ImageInput = style({
|
||||
display: "none",
|
||||
});
|
||||
|
||||
|
||||
// this is needed to fix an issue with the image input text
|
||||
// when that is a drag an drop we can remove this
|
||||
export const ImageFixer = style({
|
||||
marginLeft: "20px",
|
||||
});
|
@ -1,21 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import { useCreateUI } from "../../creationPanelUIStore";
|
||||
|
||||
export default function ShowQueue() {
|
||||
|
||||
const showQueue = useCreateUI((state) => state.showQueue);
|
||||
const toggleQueue = useCreateUI((state) => state.toggleQueue);
|
||||
|
||||
return (
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={showQueue}
|
||||
onChange={() => toggleQueue()}
|
||||
>
|
||||
</input>
|
||||
Display Queue
|
||||
</label>
|
||||
);
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../styles/theme/index.css";
|
||||
export const CreationPaneMain = style({
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
});
|
||||
|
||||
globalStyle(`${CreationPaneMain} > div`, {
|
||||
marginBottom: vars.spacing.medium,
|
||||
});
|
||||
|
||||
export const InpaintingSlider = style({
|
||||
position: "absolute",
|
||||
top: "10px",
|
||||
left: "400px",
|
||||
zIndex: 1,
|
||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||
});
|
@ -1,89 +0,0 @@
|
||||
import create from "zustand";
|
||||
import produce from "immer";
|
||||
import { persist } from "zustand/middleware";
|
||||
|
||||
export interface ImageCreationUIOptions {
|
||||
isOpenAdvancedSettings: boolean;
|
||||
isOpenAdvImprovementSettings: boolean;
|
||||
isOpenAdvPropertySettings: boolean;
|
||||
isOpenAdvWorkflowSettings: boolean;
|
||||
isOpenImageModifier: boolean;
|
||||
showQueue: boolean;
|
||||
|
||||
toggleAdvancedSettings: () => void;
|
||||
toggleAdvImprovementSettings: () => void;
|
||||
toggleAdvPropertySettings: () => void;
|
||||
toggleAdvWorkflowSettings: () => void;
|
||||
|
||||
toggleImageModifier: () => void;
|
||||
toggleQueue: () => void;
|
||||
|
||||
}
|
||||
|
||||
export const useCreateUI = create<ImageCreationUIOptions>(
|
||||
//@ts-expect-error
|
||||
persist(
|
||||
(set, get) => ({
|
||||
isOpenAdvancedSettings: false,
|
||||
isOpenAdvImprovementSettings: false,
|
||||
isOpenAdvPropertySettings: false,
|
||||
isOpenAdvWorkflowSettings: false,
|
||||
isOpenImageModifier: false,
|
||||
showQueue: false,
|
||||
|
||||
toggleAdvancedSettings: () => {
|
||||
set(
|
||||
produce((state: ImageCreationUIOptions) => {
|
||||
state.isOpenAdvancedSettings = !state.isOpenAdvancedSettings;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
toggleAdvImprovementSettings: () => {
|
||||
set(
|
||||
produce((state: ImageCreationUIOptions) => {
|
||||
state.isOpenAdvImprovementSettings =
|
||||
!state.isOpenAdvImprovementSettings;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
toggleAdvPropertySettings: () => {
|
||||
set(
|
||||
produce((state: ImageCreationUIOptions) => {
|
||||
state.isOpenAdvPropertySettings = !state.isOpenAdvPropertySettings;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
toggleAdvWorkflowSettings: () => {
|
||||
set(
|
||||
produce((state: ImageCreationUIOptions) => {
|
||||
state.isOpenAdvWorkflowSettings = !state.isOpenAdvWorkflowSettings;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
toggleImageModifier: () => {
|
||||
set(
|
||||
produce((state: ImageCreationUIOptions) => {
|
||||
state.isOpenImageModifier = !state.isOpenImageModifier;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
toggleQueue: () => {
|
||||
set(
|
||||
produce((state: ImageCreationUIOptions) => {
|
||||
state.showQueue = !state.showQueue;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
}),
|
||||
{
|
||||
name: "createUI",
|
||||
// getStorage: () => localStorage,
|
||||
}
|
||||
)
|
||||
);
|
@ -1,33 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../../styles/theme/index.css";
|
||||
|
||||
export const ImagerModifierGroups = style({
|
||||
// marginBottom: vars.spacing.small,
|
||||
paddingLeft: 0,
|
||||
listStyleType: "none",
|
||||
});
|
||||
|
||||
globalStyle(`${ImagerModifierGroups} li`, {
|
||||
marginTop: vars.spacing.medium,
|
||||
});
|
||||
|
||||
export const ImageModifierGrouping = style({
|
||||
marginTop: vars.spacing.medium,
|
||||
});
|
||||
|
||||
globalStyle(`${ImageModifierGrouping} h4`, {
|
||||
fontSize: vars.fonts.sizes.Plain,
|
||||
});
|
||||
|
||||
|
||||
export const ModifierListStyle = style({
|
||||
paddingLeft: 0,
|
||||
listStyleType: "none",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: vars.spacing.small,
|
||||
});
|
||||
|
||||
globalStyle(`${ModifierListStyle} li`, {
|
||||
margin: 0,
|
||||
});
|
@ -1,115 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import {
|
||||
MenuButton,
|
||||
} from "../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
card
|
||||
} from '../../../_recipes/card.css';
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../_recipes/button.css";
|
||||
|
||||
import {
|
||||
ImagerModifierGroups,
|
||||
ImageModifierGrouping,
|
||||
ModifierListStyle,
|
||||
} from "./imageModifiers.css";
|
||||
|
||||
import { ModifierObject, useImageCreate } from "../../../../stores/imageCreateStore";
|
||||
import { useCreateUI } from "../creationPanelUIStore";
|
||||
|
||||
import ModifierTag from "../../../molecules/modifierTag";
|
||||
|
||||
interface ModifierListProps {
|
||||
category: string;
|
||||
tags: ModifierObject[];
|
||||
}
|
||||
|
||||
function ModifierList({ tags, category }: ModifierListProps) {
|
||||
return (
|
||||
<ul className={ModifierListStyle}>
|
||||
{tags.map((tag) => (
|
||||
<li key={tag.modifier}>
|
||||
<ModifierTag category={category} name={tag.modifier} previews={tag.previews} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
interface ModifierGroupingProps {
|
||||
title: string;
|
||||
category: string;
|
||||
tags: ModifierObject[];
|
||||
}
|
||||
|
||||
function ModifierGrouping({ title, category, tags }: ModifierGroupingProps) {
|
||||
// doing this localy for now, but could move to a store
|
||||
// and persist if we wanted to
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
const _toggleExpand = () => {
|
||||
setIsExpanded(!isExpanded);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={ImageModifierGrouping}>
|
||||
<button type="button" className={buttonStyle({
|
||||
type: 'action',
|
||||
color: 'accent',
|
||||
})} onClick={_toggleExpand}>
|
||||
<h4>{title}</h4>
|
||||
</button>
|
||||
{isExpanded && <ModifierList category={category} tags={tags} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ImageModifers() {
|
||||
const allModifiers = useImageCreate((state) => state.allModifiers);
|
||||
|
||||
const imageModifierIsOpen = useCreateUI((state) => state.isOpenImageModifier);
|
||||
const toggleImageModifiersIsOpen = useCreateUI(
|
||||
(state) => state.toggleImageModifier
|
||||
);
|
||||
|
||||
const handleClick = () => {
|
||||
toggleImageModifiersIsOpen();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={card(
|
||||
{
|
||||
level: 1,
|
||||
backing: 'normal'
|
||||
}
|
||||
)}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClick}
|
||||
className={buttonStyle({
|
||||
type: 'action',
|
||||
color: 'secondary',
|
||||
size: 'large'
|
||||
})}
|
||||
>
|
||||
Image Modifiers
|
||||
</button>
|
||||
|
||||
{imageModifierIsOpen && (
|
||||
<ul className={ImagerModifierGroups}>
|
||||
{allModifiers.map((item, index) => {
|
||||
return (
|
||||
<li key={item.category}>
|
||||
<ModifierGrouping title={item.category} category={item.category} tags={item.modifiers} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
const Mockifiers = [
|
||||
[
|
||||
"Drawing Style",
|
||||
[
|
||||
"Cel Shading",
|
||||
"Children's Drawing",
|
||||
"Crosshatch",
|
||||
"Detailed and Intricate",
|
||||
"Doodle",
|
||||
"Dot Art",
|
||||
"Line Art",
|
||||
"Sketch",
|
||||
],
|
||||
],
|
||||
["Visual Style", ["2D", "8-bit", "16-bit", "Anaglyph", "Anime", "CGI"]],
|
||||
];
|
||||
|
||||
export default Mockifiers;
|
@ -1,43 +0,0 @@
|
||||
import React, { ChangeEvent } from "react";
|
||||
|
||||
import BasicCreation from "./basicCreation";
|
||||
import AdvancedSettings from "./advancedSettings";
|
||||
import ImageModifiers from "./imageModifiers";
|
||||
import InpaintingPanel from "./inpaintingPanel";
|
||||
|
||||
import QueueDisplay from "../queueDisplay";
|
||||
|
||||
// this works but causes type errors so its not worth it for now
|
||||
// import { useImageCreate } from "@stores/imageCreateStore.ts";
|
||||
|
||||
import { useImageCreate } from "../../../stores/imageCreateStore";
|
||||
import { useRequestQueue } from "../../../stores/requestQueueStore";
|
||||
|
||||
|
||||
import {
|
||||
CreationPaneMain,
|
||||
InpaintingSlider,
|
||||
} from "./creationPanel.css";
|
||||
|
||||
|
||||
export default function CreationPanel() {
|
||||
const isInPaintingMode = useImageCreate((state) => state.isInpainting);
|
||||
|
||||
const hasQueue = useRequestQueue((state) => state.hasAnyQueue());
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={CreationPaneMain}>
|
||||
<BasicCreation></BasicCreation>
|
||||
<AdvancedSettings></AdvancedSettings>
|
||||
<ImageModifiers></ImageModifiers>
|
||||
</div>
|
||||
|
||||
{isInPaintingMode && (
|
||||
<div className={InpaintingSlider}>
|
||||
<InpaintingPanel></InpaintingPanel>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
import React, { useRef, useState, ChangeEvent } from "react";
|
||||
import DrawImage from "../../../molecules/drawImage";
|
||||
|
||||
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
||||
|
||||
import {
|
||||
InpaintingPanelMain,
|
||||
InpaintingControls,
|
||||
InpaintingControlRow,
|
||||
} from "./inpaintingPanel.css";
|
||||
|
||||
export default function InpaintingPanel() {
|
||||
// no idea if this is the right typing
|
||||
// const drawingRef = useRef(null);
|
||||
|
||||
const [brushSize, setBrushSize] = useState("20");
|
||||
const [brushShape, setBrushShape] = useState("round");
|
||||
const [brushColor, setBrushColor] = useState("#fff");
|
||||
const [isErasing, setIsErasing] = useState(false);
|
||||
|
||||
const initImage = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("init_image")
|
||||
);
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const setMask = (data: string) => {
|
||||
setRequestOption("mask", data);
|
||||
}
|
||||
|
||||
|
||||
const _handleBrushMask = () => {
|
||||
setIsErasing(false);
|
||||
};
|
||||
|
||||
const _handleBrushErase = () => {
|
||||
setIsErasing(true);
|
||||
};
|
||||
|
||||
|
||||
const _handleBrushSize = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
setBrushSize(event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={InpaintingPanelMain}>
|
||||
<DrawImage
|
||||
// ref={drawingRef}
|
||||
imageData={initImage}
|
||||
// @ts-expect-error
|
||||
brushSize={brushSize}
|
||||
brushShape={brushShape}
|
||||
brushColor={brushColor}
|
||||
isErasing={isErasing}
|
||||
setData={setMask}
|
||||
/>
|
||||
<div className={InpaintingControls}>
|
||||
<div className={InpaintingControlRow}>
|
||||
<button onClick={_handleBrushMask}>Mask</button>
|
||||
<button onClick={_handleBrushErase}>Erase</button>
|
||||
{/* <button disabled onClick={_handleFillMask}>
|
||||
Fill
|
||||
</button>
|
||||
<button disabled onClick={_handleClearAll}>
|
||||
Clear
|
||||
</button> */}
|
||||
|
||||
<label>
|
||||
Brush Size
|
||||
<input
|
||||
type="range"
|
||||
min="1"
|
||||
max="100"
|
||||
value={brushSize}
|
||||
onChange={_handleBrushSize}
|
||||
></input>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className={InpaintingControlRow}>
|
||||
<button
|
||||
onClick={() => {
|
||||
setBrushShape("round");
|
||||
}}
|
||||
>
|
||||
Cirle Brush
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setBrushShape("square");
|
||||
}}
|
||||
>
|
||||
Square Brush
|
||||
</button>
|
||||
|
||||
{/* <button
|
||||
onClick={() => {
|
||||
setBrushColor("#000");
|
||||
}}
|
||||
>
|
||||
Dark Brush
|
||||
</button> */}
|
||||
{/* <button
|
||||
onClick={() => {
|
||||
setBrushColor("#fff");
|
||||
}}
|
||||
>
|
||||
Light Brush
|
||||
</button> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import { style } from "@vanilla-extract/css";
|
||||
|
||||
export const InpaintingPanelMain = style({
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
padding: "10px 10px",
|
||||
});
|
||||
|
||||
export const InpaintingControls = style({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
width: "100%",
|
||||
flexWrap: "wrap",
|
||||
});
|
||||
|
||||
export const InpaintingControlRow = style({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-evenly",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
|
||||
":first-of-type": {
|
||||
margin: "10px 0",
|
||||
},
|
||||
});
|
@ -1,12 +0,0 @@
|
||||
import { style } from '@vanilla-extract/css'
|
||||
|
||||
// handles all 3
|
||||
export const currentDisplayMain = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
padding: '0 0 0 0',
|
||||
})
|
@ -1,40 +0,0 @@
|
||||
import { style, globalStyle } from '@vanilla-extract/css'
|
||||
|
||||
import { vars } from '../../../../styles/theme/index.css'
|
||||
|
||||
export const imageDisplayMain = style({
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
});
|
||||
|
||||
export const imageDisplayContainer = style({
|
||||
height: '100%',
|
||||
width: '80%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
});
|
||||
|
||||
export const imageDisplayCenter = style({
|
||||
width: '100%',
|
||||
maxWidth: '1000px',
|
||||
position: 'relative',
|
||||
});
|
||||
|
||||
export const imageDisplayContent = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
});
|
||||
|
||||
globalStyle(`${imageDisplayContent} > div`, {
|
||||
marginBottom: vars.spacing.medium,
|
||||
});
|
||||
|
||||
globalStyle(`${imageDisplayContent} p`, {
|
||||
marginBottom: vars.spacing.small,
|
||||
});
|
||||
|
||||
globalStyle(`${imageDisplayContent} button`, {
|
||||
marginRight: vars.spacing.medium,
|
||||
});
|
@ -1,100 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import React from "react";
|
||||
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
||||
import { CompletedImagesType } from "../../../../stores/imageDisplayStore";
|
||||
|
||||
import GeneratedImage from "../../../molecules/generatedImage";
|
||||
|
||||
import {
|
||||
imageDisplayMain,
|
||||
imageDisplayContainer,
|
||||
imageDisplayCenter,
|
||||
imageDisplayContent,
|
||||
} from './imageDisplay.css';
|
||||
|
||||
|
||||
import {
|
||||
buttonStyle
|
||||
} from "../../../_recipes/button.css";
|
||||
|
||||
export default function ImageDisplay({ info, data }: CompletedImagesType) {
|
||||
|
||||
const createFileName = () => {
|
||||
const {
|
||||
prompt,
|
||||
negative_prompt,
|
||||
seed,
|
||||
num_inference_steps,
|
||||
guidance_scale,
|
||||
use_face_correction,
|
||||
use_upscale,
|
||||
width,
|
||||
height,
|
||||
} = info;
|
||||
|
||||
// Most important information is the prompt
|
||||
let underscoreName = prompt.replace(/[^a-zA-Z0-9]/g, "_");
|
||||
underscoreName = underscoreName.substring(0, 100);
|
||||
// name and the top level metadata
|
||||
let fileName = `${underscoreName}_Seed-${seed}_Steps-${num_inference_steps}_Guidance-${guidance_scale}`;
|
||||
// Add the face correction and upscale
|
||||
if (typeof use_face_correction == "string") {
|
||||
fileName += `_FaceCorrection-${use_face_correction}`;
|
||||
}
|
||||
if (typeof use_upscale == "string") {
|
||||
fileName += `_Upscale-${use_upscale}`;
|
||||
}
|
||||
// Add the width and height
|
||||
fileName += `_${width}x${height}`;
|
||||
// add the file extension
|
||||
fileName += ".png";
|
||||
// return fileName
|
||||
return fileName;
|
||||
};
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const _handleSave = () => {
|
||||
const link = document.createElement("a");
|
||||
link.download = createFileName();
|
||||
link.href = data ?? "";
|
||||
link.click();
|
||||
};
|
||||
|
||||
const _handleUseAsInput = () => {
|
||||
setRequestOption("init_image", data);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={imageDisplayMain}>
|
||||
|
||||
<div className={imageDisplayContainer}>
|
||||
|
||||
<div className={imageDisplayCenter}>
|
||||
|
||||
<div className={imageDisplayContent}>
|
||||
<div>
|
||||
<p> {info?.prompt}</p>
|
||||
<p> {info?.negative_prompt}</p>
|
||||
<div>
|
||||
<button className={buttonStyle(
|
||||
|
||||
)} onClick={_handleSave}>Save</button>
|
||||
<button className={buttonStyle(
|
||||
{
|
||||
color: "secondary",
|
||||
type: "outline",
|
||||
}
|
||||
)} onClick={_handleUseAsInput}>Use as Input</button>
|
||||
</div>
|
||||
</div>
|
||||
<GeneratedImage imageData={data} metadata={info}></GeneratedImage>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { FetchingStates, useImageFetching } from "../../../stores/imageFetchingStore";
|
||||
import { useImageDisplay } from "../../../stores/imageDisplayStore";
|
||||
|
||||
import { API_URL } from "../../../api";
|
||||
|
||||
import {
|
||||
currentDisplayMain,
|
||||
} from './currentDisplay.css';
|
||||
|
||||
import ImageDisplay from "./imageDisplay";
|
||||
|
||||
const IdleDisplay = () => {
|
||||
return (
|
||||
<h4 className="no-image">Try Making a new image!</h4>
|
||||
);
|
||||
};
|
||||
|
||||
const LoadingDisplay = ({ images }: { images: string[] }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{images.map((image, index) => {
|
||||
if (index == images.length - 1) {
|
||||
return (
|
||||
<img src={`${API_URL}${image}`} key={index} />
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default function CurrentDisplay() {
|
||||
|
||||
const status = useImageFetching((state) => state.status);
|
||||
const currentImage = useImageDisplay((state) => state.currentImage);
|
||||
|
||||
const progressImages = useImageFetching((state) => state.progressImages);
|
||||
|
||||
return (
|
||||
<div className={currentDisplayMain}>
|
||||
|
||||
{(currentImage == null) && <IdleDisplay />}
|
||||
{/* {(status === FetchingStates.FETCHING || status === FetchingStates.PROGRESSING) && <LoadingDisplay />}
|
||||
{(currentImage != null) && <ImageDisplay info={currentImage?.info} data={currentImage?.data} />} */}
|
||||
|
||||
{
|
||||
(progressImages.length > 0)
|
||||
? <LoadingDisplay images={progressImages} />
|
||||
: (currentImage != null) && <ImageDisplay info={currentImage?.info} data={currentImage?.data} />
|
||||
}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import { style } from '@vanilla-extract/css'
|
||||
|
||||
import {
|
||||
card as cardStyles,
|
||||
} from '../../_recipes/card.css'
|
||||
|
||||
export const currentInfoMain = style([
|
||||
cardStyles(
|
||||
{
|
||||
backing: 'dark',
|
||||
}
|
||||
),
|
||||
{
|
||||
// display: 'flex',
|
||||
// flexDirection: 'column',
|
||||
// justifyContent: 'center',
|
||||
// alignItems: 'center',
|
||||
// height: '100%',
|
||||
width: '250px',
|
||||
padding: '0 0 0 0',
|
||||
},
|
||||
])
|
@ -1,7 +0,0 @@
|
||||
import React from "react";
|
||||
import { currentInfoMain } from "./currentInfo.css";
|
||||
export default function CurrentInfo() {
|
||||
return <div className={
|
||||
currentInfoMain
|
||||
}> current info</div>;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
import { vars } from "../../../styles/theme/index.css";
|
||||
|
||||
export const FooterDisplayMain = style({
|
||||
color: vars.colors.text.normal,
|
||||
fontSize: vars.fonts.sizes.Caption,
|
||||
|
||||
display: "inline-block",
|
||||
// marginTop: vars.spacing.medium,
|
||||
// marginBottom: vars.spacing.medium,
|
||||
// TODO move this to the theme
|
||||
padding: vars.spacing.small,
|
||||
boxShadow:
|
||||
"0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15)",
|
||||
});
|
||||
|
||||
export const CoffeeButton = style({
|
||||
height: "23px",
|
||||
transform: "translateY(25%)",
|
||||
});
|
||||
|
||||
globalStyle(`${FooterDisplayMain} a`, {
|
||||
color: vars.colors.link,
|
||||
textDecoration: "none",
|
||||
});
|
||||
|
||||
globalStyle(`${FooterDisplayMain} a:hover`, {
|
||||
textDecoration: "underline",
|
||||
});
|
||||
|
||||
globalStyle(`${FooterDisplayMain} a:visited`, {
|
||||
color: vars.colors.link,
|
||||
});
|
||||
|
||||
globalStyle(`${FooterDisplayMain} a:active`, {
|
||||
color: vars.colors.link,
|
||||
});
|
||||
|
||||
globalStyle(`${FooterDisplayMain} a:focus`, {
|
||||
color: vars.colors.link,
|
||||
});
|
||||
|
||||
globalStyle(`${FooterDisplayMain} p`, {
|
||||
margin: vars.spacing.min,
|
||||
});
|
||||
|
||||
// .footer-display {
|
||||
// color: #ffffff;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// }
|
||||
|
||||
// #coffeeButton {
|
||||
// height: 23px;
|
||||
// transform: translateY(25%);
|
||||
// }
|
@ -1,71 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
FooterDisplayMain,
|
||||
CoffeeButton,
|
||||
} from "./footerDisplay.css";
|
||||
|
||||
import { API_URL } from "../../../api";
|
||||
|
||||
export default function FooterDisplay() {
|
||||
return (
|
||||
<div className={FooterDisplayMain}>
|
||||
<p>
|
||||
If you found this project useful and want to help keep it alive, please{" "}
|
||||
<a
|
||||
href="https://ko-fi.com/cmdr2_stablediffusion_ui"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={`${API_URL}/kofi.png`} className={CoffeeButton} />
|
||||
</a>{" "}
|
||||
to help cover the cost of development and maintenance! Thank you for
|
||||
your support!
|
||||
</p>
|
||||
<p>
|
||||
Please feel free to join the{" "}
|
||||
<a
|
||||
href="https://discord.com/invite/u9yhsFmEkB"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
discord community
|
||||
</a>{" "}
|
||||
or{" "}
|
||||
<a
|
||||
href="https://github.com/cmdr2/stable-diffusion-ui/issues"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
file an issue
|
||||
</a>{" "}
|
||||
if you have any problems or suggestions in using this interface.
|
||||
</p>
|
||||
<div id="footer-legal">
|
||||
<p>
|
||||
<b>Disclaimer:</b> The authors of this project are not responsible for
|
||||
any content generated using this interface.
|
||||
</p>
|
||||
<p>
|
||||
This license of this software forbids you from sharing any content
|
||||
that violates any laws, produce any harm to a person, disseminate any
|
||||
personal information that would be meant for harm, <br />
|
||||
spread misinformation and target vulnerable groups. For the full list
|
||||
of restrictions please read{" "}
|
||||
<a
|
||||
href="https://github.com/cmdr2/stable-diffusion-ui/blob/main/LICENSE"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
the license
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
By using this software, you consent to the terms and conditions of the
|
||||
license.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../styles/theme/index.css";
|
||||
|
||||
export const HeaderDisplayMain = style({
|
||||
color: vars.colors.text.normal,
|
||||
display: "flex",
|
||||
justifyContent: "space-between"
|
||||
});
|
||||
|
||||
globalStyle(`${HeaderDisplayMain} > h1`, {
|
||||
fontSize: vars.fonts.sizes.Title,
|
||||
fontWeight: "bold",
|
||||
marginRight: vars.spacing.medium,
|
||||
});
|
||||
|
||||
|
||||
export const HeaderTitle = style({
|
||||
marginLeft: vars.spacing.large,
|
||||
});
|
||||
|
||||
export const HeaderLinks = style({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexGrow: 1,
|
||||
justifyContent: "space-between",
|
||||
maxWidth: "300px",
|
||||
marginRight: vars.spacing.large,
|
||||
});
|
@ -1,5 +0,0 @@
|
||||
import { style } from "@vanilla-extract/css";
|
||||
|
||||
export const HelpContent = style({
|
||||
width: '300px',
|
||||
});
|
@ -1,61 +0,0 @@
|
||||
import React from "react";
|
||||
import { Popover } from '@headlessui/react';
|
||||
// import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
PopoverMain,
|
||||
PopoverButtonStyle,
|
||||
PopoverPanelMain,
|
||||
} from "../../../_recipes/popover_headless.css";
|
||||
|
||||
import {
|
||||
card
|
||||
} from '../../../_recipes/card.css';
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
SettingItem
|
||||
} from "../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
HelpContent
|
||||
} from "./helpOptions.css";
|
||||
|
||||
export default function HelpOptions() {
|
||||
|
||||
return (
|
||||
<Popover className={PopoverMain}>
|
||||
<Popover.Button className={PopoverButtonStyle}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-comments'].join(" ")}></i>
|
||||
Help & Community
|
||||
</Popover.Button>
|
||||
|
||||
<Popover.Panel className={PopoverPanelMain}>
|
||||
<div className={HelpContent}>
|
||||
<ul>
|
||||
<li className={SettingItem}>
|
||||
<a href="https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" target="_blank" rel="noreferrer">
|
||||
<i className={[IconFont, 'fa-solid', 'fa-circle-question'].join(" ")}></i> Usual Problems and Solutions
|
||||
</a>
|
||||
</li>
|
||||
<li className={SettingItem}>
|
||||
<a href="https://discord.com/invite/u9yhsFmEkB" target="_blank" rel="noreferrer">
|
||||
<i className={[IconFont, 'fa-brands', 'fa-discord'].join(" ")}></i> Discord user Community
|
||||
</a>
|
||||
</li>
|
||||
<li className={SettingItem}>
|
||||
<a href="https://old.reddit.com/r/StableDiffusionUI/" target="_blank" rel="noreferrer">
|
||||
<i className={[IconFont, 'fa-brands', 'fa-reddit'].join(" ")}></i> Reddit Community
|
||||
</a>
|
||||
</li>
|
||||
<li className={SettingItem}>
|
||||
<a href="https://github.com/cmdr2/stable-diffusion-ui " target="_blank" rel="noreferrer">
|
||||
<i className={[IconFont, 'fa-brands', 'fa-github'].join(" ")}></i> Source Code on Github
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
};
|
@ -1,62 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { KEY_CONFIG, getConfig } from "../../../api";
|
||||
|
||||
import StatusDisplay from "./statusDisplay";
|
||||
|
||||
import HelpOptions from "./helpOptions";
|
||||
import SystemSettings from "./systemSettings";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
HeaderDisplayMain,
|
||||
HeaderTitle,
|
||||
HeaderLinks,
|
||||
} from "./headerDisplay.css";
|
||||
|
||||
// import LanguageDropdown from "./languageDropdown";
|
||||
|
||||
export default function HeaderDisplay() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { status, data } = useQuery([KEY_CONFIG], getConfig);
|
||||
|
||||
const [version, setVersion] = useState("2.1.0");
|
||||
const [release, setRelease] = useState("");
|
||||
|
||||
// this is also in the Beta Mode
|
||||
// TODO: make this a custom hook
|
||||
useEffect(() => {
|
||||
if (status === "success") {
|
||||
// TODO also pass down the actual version
|
||||
const { update_branch: updateBranch } = data;
|
||||
|
||||
// just hard coded for now
|
||||
setVersion("v2.1");
|
||||
|
||||
if (updateBranch === "main") {
|
||||
setRelease("(stable)");
|
||||
} else {
|
||||
setRelease("(beta)");
|
||||
}
|
||||
}
|
||||
}, [status, data, setVersion, setVersion]);
|
||||
|
||||
return (
|
||||
<div className={HeaderDisplayMain}>
|
||||
<div className={HeaderTitle}>
|
||||
<h1>
|
||||
{t("title")} {version} {release}{" "}
|
||||
</h1>
|
||||
<StatusDisplay className="status-display"></StatusDisplay>
|
||||
</div>
|
||||
<div className={HeaderLinks}>
|
||||
<HelpOptions></HelpOptions>
|
||||
<SystemSettings></SystemSettings>
|
||||
</div>
|
||||
{/* <LanguageDropdown></LanguageDropdown> */}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const LanguageDropdown = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const [language, setLanguage] = useState("id");
|
||||
|
||||
const handleLangChange = (evt: any) => {
|
||||
const lang = evt.target.value;
|
||||
console.log(lang);
|
||||
setLanguage(lang);
|
||||
i18n.changeLanguage(lang);
|
||||
};
|
||||
|
||||
return (
|
||||
<select onChange={handleLangChange} value={language}>
|
||||
<option value="en">EN</option>
|
||||
<option value="es">ES</option>
|
||||
</select>
|
||||
);
|
||||
};
|
||||
|
||||
export default LanguageDropdown;
|
@ -1,57 +0,0 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { healthPing, HEALTH_PING_INTERVAL } from "../../../../api";
|
||||
|
||||
import AudioDing from "../../../molecules/audioDing";
|
||||
|
||||
import {
|
||||
StartingStatus,
|
||||
ErrorStatus,
|
||||
SuccessStatus,
|
||||
} from "./statusDisplay.css";
|
||||
|
||||
const startingMessage = "Stable Diffusion is starting...";
|
||||
const successMessage = "Stable Diffusion is ready to use!";
|
||||
const errorMessage = "Stable Diffusion is not running!";
|
||||
|
||||
export default function StatusDisplay({ className }: { className?: string }) {
|
||||
const [statusMessage, setStatusMessage] = useState(startingMessage);
|
||||
const [statusClass, setStatusClass] = useState(StartingStatus);
|
||||
|
||||
const dingRef = useRef<HTMLAudioElement>();
|
||||
|
||||
// but this will be moved to the status display when it is created
|
||||
const { status, data } = useQuery(["health"], healthPing, {
|
||||
refetchInterval: HEALTH_PING_INTERVAL,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "loading") {
|
||||
setStatusMessage(startingMessage);
|
||||
setStatusClass(StartingStatus);
|
||||
} else if (status === "error") {
|
||||
setStatusMessage(errorMessage);
|
||||
setStatusClass(ErrorStatus);
|
||||
} else if (status === "success") {
|
||||
if (data[0] === "OK") {
|
||||
setStatusMessage(successMessage);
|
||||
setStatusClass(SuccessStatus);
|
||||
// catch an auto play error
|
||||
dingRef.current?.play().catch((e) => {
|
||||
console.log('DING!')
|
||||
});
|
||||
} else {
|
||||
setStatusMessage(errorMessage);
|
||||
setStatusClass(ErrorStatus);
|
||||
}
|
||||
}
|
||||
}, [status, data, dingRef]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AudioDing ref={dingRef}></AudioDing>
|
||||
<p className={[statusClass, className].join(" ")}>{statusMessage}</p>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { style } from "@vanilla-extract/css";
|
||||
|
||||
import { vars } from "../../../../styles/theme/index.css";
|
||||
|
||||
export const StartingStatus = style({
|
||||
color: `hsl(${vars.warningHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
||||
|
||||
export const ErrorStatus = style({
|
||||
color: `hsl(${vars.errorHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
||||
|
||||
export const SuccessStatus = style({
|
||||
color: `hsl(${vars.successHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
@ -1,162 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
import React from "react";
|
||||
import { Popover } from '@headlessui/react';
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
||||
|
||||
import BetaMode from "../../../molecules/betaMode";
|
||||
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
SettingItem
|
||||
} from "../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
PopoverMain,
|
||||
PopoverButtonStyle,
|
||||
PopoverPanelMain,
|
||||
} from "../../../_recipes/popover_headless.css";
|
||||
|
||||
import {
|
||||
SettingContent
|
||||
} from "./systemSettings.css";
|
||||
|
||||
// import {
|
||||
// SwitchGroupMain,
|
||||
// SwitchMain,
|
||||
// SwitchLabel,
|
||||
// SwitchEnabled,
|
||||
// SwitchPill,
|
||||
// } from "../../../_headless/switch/index.css";
|
||||
|
||||
|
||||
export default function SystemSettings() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isUseAutoSave = useImageCreate((state) => state.isUseAutoSave());
|
||||
const diskPath = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("save_to_disk_path")
|
||||
);
|
||||
|
||||
const turbo = useImageCreate((state) => state.getValueForRequestKey("turbo"));
|
||||
const useCpu = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("use_cpu")
|
||||
);
|
||||
const useFullPrecision = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("use_full_precision")
|
||||
);
|
||||
|
||||
const isSoundEnabled = useImageCreate((state) => state.isSoundEnabled());
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
const toggleUseAutoSave = useImageCreate((state) => state.toggleUseAutoSave);
|
||||
const toggleSoundEnabled = useImageCreate(
|
||||
(state) => state.toggleSoundEnabled
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover className={PopoverMain}>
|
||||
<Popover.Button className={PopoverButtonStyle}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-gear'].join(" ")}></i>
|
||||
Settings
|
||||
</Popover.Button>
|
||||
|
||||
<Popover.Panel className={PopoverPanelMain}>
|
||||
<div className={SettingContent}>
|
||||
<h4>System Settings</h4>
|
||||
<ul>
|
||||
<li className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
checked={isUseAutoSave}
|
||||
onChange={(e) => toggleUseAutoSave()}
|
||||
type="checkbox"
|
||||
/>
|
||||
{t("storage.ast")}{" "}
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
value={diskPath}
|
||||
onChange={(e) =>
|
||||
setRequestOption("save_to_disk_path", e.target.value)
|
||||
}
|
||||
size={40}
|
||||
disabled={!isUseAutoSave}
|
||||
/>
|
||||
<span className="visually-hidden">
|
||||
Path on disk where images will be saved
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
<li className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
checked={isSoundEnabled}
|
||||
onChange={(e) => toggleSoundEnabled()}
|
||||
type="checkbox"
|
||||
/>
|
||||
{t("advanced-settings.sound")}
|
||||
</label>
|
||||
|
||||
|
||||
{/* <Switch.Group>
|
||||
<Switch.Label passive> <>{t("advanced-settings.sound")}</> </Switch.Label>
|
||||
<Switch checked={isSoundEnabled} onChange={toggleSoundEnabled} className={SwitchMain}>
|
||||
<span
|
||||
className={SwitchPill}
|
||||
/>
|
||||
</Switch>
|
||||
</Switch.Group> */}
|
||||
</li>
|
||||
|
||||
|
||||
<li className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
checked={turbo}
|
||||
onChange={(e) => setRequestOption("turbo", e.target.checked)}
|
||||
type="checkbox"
|
||||
/>
|
||||
{t("advanced-settings.turbo")} {t("advanced-settings.turbo-disc")}
|
||||
</label>
|
||||
</li>
|
||||
<li className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={useCpu}
|
||||
onChange={(e) => setRequestOption("use_cpu", e.target.checked)}
|
||||
/>
|
||||
{t("advanced-settings.cpu")} {t("advanced-settings.cpu-disc")}
|
||||
</label>
|
||||
</li>
|
||||
<li className={SettingItem}>
|
||||
<label>
|
||||
<input
|
||||
checked={useFullPrecision}
|
||||
onChange={(e) =>
|
||||
setRequestOption("use_full_precision", e.target.checked)
|
||||
}
|
||||
type="checkbox"
|
||||
/>
|
||||
{t("advanced-settings.gpu")} {t("advanced-settings.gpu-disc")}
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li className={SettingItem}>
|
||||
<BetaMode />
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
|
||||
);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user