Compare commits
2064
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96782b52cd | ||
|
|
aae00e1312 | ||
|
|
24e90f0a54 | ||
|
|
f5208a85b0 | ||
|
|
8db4b3f83b | ||
|
|
33ad04d036 | ||
|
|
4bcdb3f495 | ||
|
|
70979172b0 | ||
|
|
493b9a3975 | ||
|
|
5a21a67d46 | ||
|
|
ff72c906ba | ||
|
|
907b1f67ed | ||
|
|
72cbe7f905 | ||
|
|
deb16aa7ab | ||
|
|
d0efa44c9e | ||
|
|
d321843c02 | ||
|
|
2b44b145cb | ||
|
|
9f5606889e | ||
|
|
417f2a8b91 | ||
|
|
d3a7bf967e | ||
|
|
db145cd8ad | ||
|
|
7d614f7ac5 | ||
|
|
c7a2a3e29b | ||
|
|
3b966c03ee | ||
|
|
66d943d391 | ||
|
|
f5f876e458 | ||
|
|
27c3439120 | ||
|
|
f212d04261 | ||
|
|
06f01aa85c | ||
|
|
5f48dc08a9 | ||
|
|
e81e056758 | ||
|
|
2d95ff0830 | ||
|
|
81d921d625 | ||
|
|
e988513ed7 | ||
|
|
783d4f82d9 | ||
|
|
b5011f458f | ||
|
|
5d0e4366d2 | ||
|
|
8643dc02dd | ||
|
|
7c4dcb2817 | ||
|
|
6b64fdafcb | ||
|
+1 |
185dd47668 | ||
|
|
f165665a35 | ||
|
|
ad38749f98 | ||
|
|
7825dd64ca | ||
|
|
f6af620643 | ||
|
|
b5aeef7ebf | ||
|
|
f5a201dd94 | ||
|
|
72dab12033 | ||
|
|
ce4b4ba41d | ||
|
|
945206153d | ||
|
|
9f977d082b | ||
|
|
4a2ec0c40c | ||
|
|
70bf61a645 | ||
|
|
674f4b1095 | ||
|
|
3304070034 | ||
|
|
19ca5f08c6 | ||
|
|
5605910ac8 | ||
|
|
b1eda435a5 | ||
|
|
e88ca8430e | ||
|
|
d39db02a73 | ||
|
|
86a64ca929 | ||
|
|
5ea0f7d4c7 | ||
|
|
b3fa2fa6d2 | ||
|
|
999dc640bc | ||
|
|
9be9658ffb | ||
|
|
595d5362f6 | ||
|
|
f212fcf892 | ||
|
|
8c1c5572c0 | ||
|
|
31d151638a | ||
|
|
fb6b41630c | ||
|
|
6ab806cbde | ||
|
|
c0267f7746 | ||
|
|
a54b6dc7b9 | ||
|
|
9ec43ebe70 | ||
|
|
486cd68bf7 | ||
|
|
98c050e7e9 | ||
|
|
25fcee984b | ||
|
|
86922c4547 | ||
|
|
7bbdfd25cd | ||
|
|
b8ad22a6fb | ||
|
|
8dd955563e | ||
|
|
663ab83b08 | ||
|
|
c143929b69 | ||
|
|
1b73d248b3 | ||
|
|
cc22a92daf | ||
|
|
39f0408929 | ||
|
|
e66f46a464 | ||
|
|
9243296197 | ||
|
|
26ce83f8f1 | ||
|
|
907ef38189 | ||
|
|
a7d4001b00 | ||
|
|
e3a3379615 | ||
|
|
356a06e694 | ||
|
|
fce516a76f | ||
|
|
42ade0fbd1 | ||
|
|
ba07f5dad4 | ||
|
|
cc89e0f3f1 | ||
|
|
0e14d3f9c1 | ||
|
|
ff7975773e | ||
|
|
6716e2277d | ||
|
|
f986dc5d11 | ||
|
|
570a4096f9 | ||
|
|
c88bfbb5f0 | ||
|
|
d302795512 | ||
|
|
115acce80c | ||
|
|
a8731b0ca2 | ||
|
|
fd596bf418 | ||
|
|
ef7cfffeb6 | ||
|
|
ac9bcabd9c | ||
|
|
5bb961f16b | ||
|
|
a46677832b | ||
|
|
624abf0df4 | ||
|
|
e81a4ade97 | ||
|
|
9708685506 | ||
|
|
28b6bf8603 | ||
|
|
2713f0e610 | ||
|
|
f7d1cd2a4f | ||
|
|
3b8963fad0 | ||
|
|
060682a1ac | ||
|
|
95cd48571e | ||
|
|
3d619e6a98 | ||
|
|
edb7e5f323 | ||
|
|
0221034b60 | ||
|
|
9500384100 | ||
|
|
0b31f2eb41 | ||
|
|
b3a6393c91 | ||
|
|
5b5599128a | ||
|
|
cb0f03ca9c | ||
|
|
2e35f3608b | ||
|
|
16c5a5a3a6 | ||
|
|
2e7db502a9 | ||
|
|
d29b71ec45 | ||
|
|
9cd0af914a | ||
|
|
4a575393f0 | ||
|
|
76c93c767d | ||
|
|
e69337a1fc | ||
|
|
50734af6cd | ||
|
|
81b0922c93 | ||
|
|
d4f8fff7af | ||
|
|
bd61f5d591 | ||
|
|
016c3d779b | ||
|
|
acf26940d6 | ||
|
|
4bafae881f | ||
|
|
8311451420 | ||
|
|
4b75cb8357 | ||
|
|
bf16d360af | ||
|
|
38d95b4faf | ||
|
|
b06e7d3cf4 | ||
|
|
9e7ea82f94 | ||
|
|
d74fc8a5d5 | ||
|
|
4a43b45a99 | ||
|
|
d6a72fbfc4 | ||
|
|
396f737612 | ||
|
|
2dd8d5a119 | ||
|
|
656c5b61cc | ||
|
|
9fd0f6834a | ||
|
|
58dac27186 | ||
|
|
c8befb6843 | ||
|
|
fafd47fd90 | ||
|
|
e0990910f6 | ||
|
|
599f23c8aa | ||
|
|
a0bd011b80 | ||
|
|
157c27c20d | ||
|
|
4d0407a3b3 | ||
|
|
f73ed1213f | ||
|
|
679ffbcce7 | ||
|
|
daabe11d11 | ||
|
|
aaf125cfca | ||
|
|
161fc6bb68 | ||
|
|
1afed9f256 | ||
|
|
e8d6c15fee | ||
|
|
8686b28c28 | ||
|
|
d68251ad4b | ||
|
|
a02b4ae08f | ||
|
|
9ed1dd714b | ||
|
|
95dc6c66d9 | ||
|
|
e91c76c10c | ||
|
|
9deddbbe7c | ||
|
|
2d416d491c | ||
|
|
a19ce0458a | ||
|
|
3fca24e6fd | ||
|
|
6f956e0423 | ||
|
|
637a923e84 | ||
|
|
bb3ce9fbc6 | ||
|
|
06f2340569 | ||
|
|
510c29cc71 | ||
|
|
807aa04807 | ||
|
|
c84e2e0537 | ||
|
|
1f8d569b79 | ||
|
|
93ae24e707 | ||
|
|
910e219c0e | ||
|
|
3a4843fb46 | ||
|
|
1b3744baa2 | ||
|
|
7dd340f0b6 | ||
|
|
1d0d8d7fbe | ||
|
|
c7d8c8b104 | ||
|
|
a380d39865 | ||
|
|
34d3310eae | ||
|
|
6de8d2684a | ||
|
|
9763a43943 | ||
|
|
f328eec26d | ||
|
|
7684a54678 | ||
|
|
51f3174609 | ||
|
|
4fcd518b0a | ||
|
|
1e0d7c7e28 | ||
|
|
984da93a7b | ||
|
|
c2c7eda799 | ||
|
|
04b85630b9 | ||
|
|
ae4f3759c2 | ||
|
|
a238dcc5e6 | ||
|
|
57ba84107c | ||
|
|
ca913cafbc | ||
|
|
7032421096 | ||
|
|
06ac959496 | ||
|
|
41c15f8c96 | ||
|
|
5cad3dfbae | ||
|
|
49a20a303a | ||
|
|
90f74427d9 | ||
|
|
ba9dc6ce26 | ||
|
|
3a73994ad4 | ||
|
|
797e1f1f21 | ||
|
|
f1713647cf | ||
|
|
8704d3acb3 | ||
|
|
ce4250281f | ||
|
|
aecbc714c4 | ||
|
|
c20242cf1c | ||
|
|
04ba76aac8 | ||
|
|
d1bc65c266 | ||
|
|
60edbcd5f0 | ||
|
|
dab284f339 | ||
|
|
df76d9a50a | ||
|
|
abec2e48d4 | ||
|
|
0f2ddb452c | ||
|
|
6fa1acc461 | ||
|
|
9502639447 | ||
|
|
ef4acb1b66 | ||
|
|
8cb72d306b | ||
|
|
1ef8bf4690 | ||
|
|
22779c9dbc | ||
|
|
b52467b6d6 | ||
|
|
d33a0cd589 | ||
|
|
a04cb54d86 | ||
|
|
10785f156f | ||
|
|
4736fb8e32 | ||
|
|
531e7ec73d | ||
|
|
ff946b4f2f | ||
|
|
68f0e68343 | ||
|
|
12a3520563 | ||
|
|
e84426a4f9 | ||
|
|
8b80934f77 | ||
|
|
b6618f81f8 | ||
|
|
8140db32dd | ||
|
|
13db5f4423 | ||
|
|
0ae1e40d79 | ||
|
|
34d931573c | ||
|
|
721365578a | ||
|
|
7be02318e0 | ||
|
|
88db79188c | ||
|
|
8a0329b23d | ||
|
|
02ebe59d2f | ||
|
|
6e8e053b88 | ||
|
|
fc3056b0e0 | ||
|
|
4274a8ed68 | ||
|
|
8b16cd1b36 | ||
|
|
bd49d6bd89 | ||
|
|
61fd6f1741 | ||
|
|
05d45d9aab | ||
|
|
612eb64a83 | ||
|
|
e0a9e62d84 | ||
|
|
5db5f2251f | ||
|
|
34fd9d29c8 | ||
|
|
5148e27448 | ||
|
|
c6d8476963 | ||
|
|
608e55c01f | ||
|
|
b8963d272a | ||
|
|
beaaed6613 | ||
|
|
6bbd8c9b16 | ||
|
|
872ffa02ce | ||
|
|
1d9fe0c03d | ||
|
|
5b2d36e976 | ||
|
|
547135f7d2 | ||
|
|
15f1416f52 | ||
|
|
b2709aa816 | ||
|
|
9775d4e74d | ||
|
|
f5661af1f4 | ||
|
|
7394fdc162 | ||
|
|
a4f133eb46 | ||
|
|
53007465cd | ||
|
|
e1a748016a | ||
|
|
b933202694 | ||
|
|
611bec38b4 | ||
|
|
89c7adfbcd | ||
|
|
4de64d9a43 | ||
|
|
deedf4fc8b | ||
|
|
49cf0c8a9a | ||
|
|
83ccf4928f | ||
|
|
28b0d34bff | ||
|
|
5a166d2455 | ||
|
|
6808d270a7 | ||
|
|
9dc68611a1 | ||
|
|
e932f38160 | ||
|
|
9014835880 | ||
|
|
00328d04cd | ||
|
|
5b1850e161 | ||
|
|
60727656c9 | ||
|
|
372d021062 | ||
|
|
9c4421bfe0 | ||
|
|
5f85af76cd | ||
|
|
4c2565826f | ||
|
|
ae2d83c8aa | ||
|
|
3b0216ca7e | ||
|
|
0a0837ea02 | ||
|
|
a0aa350a08 | ||
|
|
1abfb175b5 | ||
|
|
a771695348 | ||
|
|
decfcb6c27 | ||
|
|
730913bec4 | ||
|
|
f8f037196e | ||
|
|
fe3e4edb04 | ||
|
|
364a4faa75 | ||
|
|
e2ffeab8fa | ||
|
|
331787fe43 | ||
|
|
9484a7237c | ||
|
|
04d834187b | ||
|
|
96063969ae | ||
|
|
cb1c8be870 | ||
|
|
33b2a94d90 | ||
|
|
ce3b024fea | ||
|
|
a02aa7586b | ||
|
|
5ea71da181 | ||
|
|
dda469d10e | ||
|
|
9f6e033c53 | ||
|
|
15f44adf3b | ||
|
|
e9483cb242 | ||
|
|
5243d8bedf | ||
|
|
ed731fd7a6 | ||
|
|
07f5422132 | ||
|
|
5aa1764848 | ||
|
|
4973ee555b | ||
|
|
d5107f2ef6 | ||
|
|
5b63b0b398 | ||
|
|
4bfccba4c0 | ||
|
|
5ddad8ebc2 | ||
|
|
b5921897d6 | ||
|
|
53a46b88b8 | ||
|
|
da977ccace | ||
|
|
7b9a2167ad | ||
|
|
fc16771355 | ||
|
|
3ef3fbfd0e | ||
|
|
415a0aaf75 | ||
|
|
5a4a9b570e | ||
|
|
2df60d6387 | ||
|
|
9c176013ab | ||
|
|
036d251e15 | ||
|
|
925060689a | ||
|
|
f0631d734e | ||
|
|
52b299315d | ||
|
|
0195e94aa7 | ||
|
|
75f0b2b82c | ||
|
|
f26f283c1f | ||
|
|
7c387b2aee | ||
|
|
071ecb284e | ||
|
|
03242942c2 | ||
|
|
a476927595 | ||
|
|
ec6e1704be | ||
|
|
d2f189607e | ||
|
|
c13777e68d | ||
|
|
fc577241bd | ||
|
|
bb8a0e596c | ||
|
|
2a63b703f9 | ||
|
|
bfeff78164 | ||
|
|
4826289020 | ||
|
|
0aebf37ef8 | ||
|
|
2fb63dcfb1 | ||
|
|
0adb7685f6 | ||
|
|
1cbe99a0d8 | ||
|
|
d1a09d0b95 | ||
|
|
7b00003958 | ||
|
|
4483bb147c | ||
|
|
fa83da6085 | ||
|
|
ef31c0c0da | ||
|
|
1392c16f12 | ||
|
|
d6393653e1 | ||
|
|
a75de51198 | ||
|
|
a21869ec9b | ||
|
|
f534e4ee37 | ||
|
|
9add661a5b | ||
|
|
76c885f080 | ||
|
|
f16e93bd3a | ||
|
|
05d2a96900 | ||
|
|
81948a5c29 | ||
|
|
5924154a62 | ||
|
|
354bfe58cd | ||
|
|
c5974a8575 | ||
|
|
c0275addb0 | ||
|
|
9c70c35669 | ||
|
|
c85baf7fd0 | ||
|
|
39e5778bd0 | ||
|
|
a3b77bb37f | ||
|
|
9d54c41a2b | ||
|
|
660cf0c1e4 | ||
|
|
3464fbb2e8 | ||
|
|
11020c4545 | ||
|
|
e93bf02e3a | ||
|
|
d51d6517be | ||
|
|
a629d7f048 | ||
|
|
5f6cc1281e | ||
|
|
683b0f5c48 | ||
|
|
42a80a41ca | ||
|
|
035fc69060 | ||
|
|
34baf44534 | ||
|
|
9dcb90a9cf | ||
|
|
c3448033de | ||
|
|
aee9b6a951 | ||
|
|
1af0aa3f57 | ||
|
|
35c9338220 | ||
|
|
2e8fa0f6c5 | ||
|
|
931aeda17f | ||
|
|
a037d24b0f | ||
|
|
75e5bec962 | ||
|
|
59c269c8d0 | ||
|
|
1fa556cd00 | ||
|
|
82e9ad8a20 | ||
|
|
541022cdc3 | ||
|
|
d893765b24 | ||
|
|
527521328f | ||
|
|
917b89e44f | ||
|
|
87862f3e23 | ||
|
|
10eed05d87 | ||
|
|
f5802fee31 | ||
|
|
1108b0264e | ||
|
|
cf9c8cbb4f | ||
|
|
4f060579ca | ||
|
|
1940c6e1ba | ||
|
|
f199ecf8e9 | ||
|
|
e754f6c234 | ||
|
|
d19dbbfe7e | ||
|
|
3a735ea0ce | ||
|
|
e319d19a54 | ||
|
|
3bdd551d40 | ||
|
|
4a7936a51d | ||
|
|
5f075e4936 | ||
|
|
76e00c2432 | ||
|
|
b46f3bf2c4 | ||
|
|
f7b4b782bf | ||
|
|
60c535e861 | ||
|
|
d59c522f7f | ||
|
|
9f798559cf | ||
|
|
f939e59463 | ||
|
|
50e89ad98b | ||
|
|
c0c5978028 | ||
|
|
abbeed394e | ||
|
|
f5b8c15388 | ||
|
|
f53b6b550f | ||
|
|
00e55b1874 | ||
|
|
90954dac49 | ||
|
|
6217523cc8 | ||
|
|
27ccd3dfa8 | ||
|
|
235f4f10ef | ||
|
|
d6ba3f3adf | ||
|
|
b453e2cf1a | ||
|
|
2d14e5682d | ||
|
|
945e5a2dc3 | ||
|
|
4b6a2685d0 | ||
|
|
1f58aebb2b | ||
|
|
6d70ced93a | ||
|
|
e76b6c3bde | ||
|
|
4630d175d7 | ||
|
|
27055b96e3 | ||
|
|
0ef96c0bca | ||
|
|
b2be4a7d67 | ||
|
|
a70df067bc | ||
|
|
2d92b08404 | ||
|
|
4bbc57b0dc | ||
|
|
756c14d988 | ||
|
|
b3b55210f7 | ||
|
|
58093a9438 | ||
|
|
ed33dd2127 | ||
|
|
accc53c5dd | ||
|
|
d4f9c97cca | ||
|
|
f731c1080d | ||
|
|
fd18185ef0 | ||
|
|
0efbbed5e2 | ||
|
|
bad350e49b | ||
|
|
172b93d07f | ||
|
|
ade8c162cd | ||
|
|
79e634316d | ||
|
|
e4cb8b71dd | ||
|
|
dfba6c7c91 | ||
|
|
f6eff090e7 | ||
|
|
e06a77af28 | ||
|
|
61a2c362b9 | ||
|
|
74973e73e6 | ||
|
|
cbcee037a7 | ||
|
|
de2e4a9c7f | ||
|
|
0ba0a5bcd8 | ||
|
|
70cc409402 | ||
|
|
160ca610ae | ||
|
|
2f1aa95f4c | ||
|
|
ac07ac5234 | ||
|
|
3eead128a6 | ||
|
|
4c22a73ff3 | ||
|
|
a78f58de92 | ||
|
|
fcda48903b | ||
|
|
3f9805ac56 | ||
|
|
2131fed0bb | ||
|
|
baa5d2fcac | ||
|
|
7cf9b76eb5 | ||
|
|
200648275e | ||
|
|
f4880d0519 | ||
|
|
375f992a0c | ||
|
|
a7584d62c7 | ||
|
|
74e6caf633 | ||
|
|
f1f531cbfa | ||
|
|
b5a275ad07 | ||
|
|
5051ad91ff | ||
|
|
06d6cb6d19 | ||
|
|
92116273b0 | ||
|
|
6169ff99a2 | ||
|
|
67f77d027a | ||
|
|
39e1a803a1 | ||
|
|
ba159e1a3e | ||
|
|
a60b77121a | ||
|
|
810f0104be | ||
|
|
07489fb405 | ||
|
|
82f0bdfc18 | ||
|
|
ae1c5342f2 | ||
|
|
66154b30c1 | ||
|
|
bf5d391d53 | ||
|
|
591ce0894e | ||
|
|
1c18563dfb | ||
|
|
b60e781767 | ||
|
|
ca54544b82 | ||
|
|
9c3ff71ce4 | ||
|
|
fd82ec7659 | ||
|
|
97ccb7df94 | ||
|
|
a818199b5a | ||
|
|
6fe1fa3455 | ||
|
|
aab95444a8 | ||
|
|
40f28be3b4 | ||
|
|
911d442340 | ||
|
|
d5594b03e3 | ||
|
|
23ccaacdee | ||
|
|
89f1ddf4d7 | ||
|
|
39a4297168 | ||
|
|
6cfd4637db | ||
|
|
544111846c | ||
|
|
79bdea0441 | ||
|
|
c056c4e79e | ||
|
|
19828e9070 | ||
|
|
8231c736ca | ||
|
|
85f639b1f0 | ||
|
|
c471b6d66c | ||
|
|
a363efccfb | ||
|
|
871a17a108 | ||
|
|
16a39b364c | ||
|
|
8803e11945 | ||
|
|
b1ca2cc2b6 | ||
|
|
91f79d2be0 | ||
|
|
9932fe5055 | ||
|
|
c296597427 | ||
|
|
97cb5bc12c | ||
|
|
7c596d6bf1 | ||
|
|
b68799e2d1 | ||
|
|
9a8f3d7bad | ||
|
|
a3d4db9fc1 | ||
|
|
9d0e762f36 | ||
|
|
8369330053 | ||
|
|
46a6fee81d | ||
|
|
b2c75130ce | ||
|
|
ef444f2a6f | ||
|
|
36f0871f69 | ||
|
|
5adf27d345 | ||
|
|
5e4c261332 | ||
|
|
6fb04e23ad | ||
|
|
2c850a612d | ||
|
|
e555c4d083 | ||
|
|
cb32cca6aa | ||
|
|
abf4cd71ba | ||
|
|
d66270eef0 | ||
|
|
ffb491a61f | ||
|
|
4ecba93a25 | ||
|
|
52ec1d09b8 | ||
|
|
3d2e2e2278 | ||
|
|
f9a9ece320 | ||
|
|
ffc46d6a48 | ||
|
|
ce458642af | ||
|
|
820d3ef426 | ||
|
|
145386b6a7 | ||
|
|
a708cf7f69 | ||
|
|
c70ebb6cce | ||
|
|
07ecd13554 | ||
|
|
a260b6eac4 | ||
|
|
0ab17e1ec8 | ||
|
|
d1a0cd1173 | ||
|
|
f1ff88f452 | ||
|
|
d92272ffa0 | ||
|
|
3955b973ef | ||
|
|
dfa43f3c5a | ||
|
|
259c5ef3d0 | ||
|
|
a1b59d4545 | ||
|
|
fcfa508cbc | ||
|
|
58a61051b9 | ||
|
|
a6766ef1c0 | ||
|
|
606b5ac5ab | ||
|
|
9acc463c7f | ||
|
|
c4ddd08b0a | ||
|
|
5c7dd10769 | ||
|
|
3fa86cb441 | ||
|
|
4a74ee0d72 | ||
|
|
8a8759b0d4 | ||
|
|
f259072136 | ||
|
|
3fd74292ef | ||
|
|
f37c4293df | ||
|
|
b9248553be | ||
|
|
475d434e98 | ||
|
|
05d568d1c1 | ||
|
|
51777c3f33 | ||
|
|
3767e9fae9 | ||
|
|
4bbfc8ccc5 | ||
|
|
531b8214c0 | ||
|
|
28b63bac38 | ||
|
|
5cab618bf7 | ||
|
|
fc64719bb8 | ||
|
|
3380f4d11c | ||
|
|
4bf030993a | ||
|
|
323a74eef3 | ||
|
|
bd4da4f365 | ||
|
|
f65f949a36 | ||
|
|
2864abd8c2 | ||
|
|
9bd2cb3c7e | ||
|
|
35cd277fcf | ||
|
|
ae7f7e9bd6 | ||
|
|
57b1932b5e | ||
|
|
e6818023a3 | ||
|
|
35a541f99b | ||
|
|
5fb00a947c | ||
|
|
6288f679b9 | ||
|
|
b88e63d133 | ||
|
|
a85255df5a | ||
|
|
15c02e9e91 | ||
|
|
ec35392cd1 | ||
|
|
b14b977bca | ||
|
|
54f55d44dc | ||
|
|
568dc1625e | ||
|
|
259b239e16 | ||
|
|
3033387ffc | ||
|
|
d500c29493 | ||
|
|
799d8003eb | ||
|
|
5d34af6ac5 | ||
|
|
dca5b9f197 | ||
|
|
75e075ef8e | ||
|
|
9895976128 | ||
|
|
133367ddb5 | ||
|
|
57964282ee | ||
|
|
51b07fc0c3 | ||
|
|
d8f33641a5 | ||
|
|
a7c7234589 | ||
|
|
e766759b8c | ||
|
|
f22f1971cb | ||
|
|
28a5806492 | ||
|
|
df98167706 | ||
|
|
06cc40055a | ||
|
|
66b47c08e6 | ||
|
|
40cb8db1fc | ||
|
|
2454a03c2b | ||
|
|
0a59a06121 | ||
|
|
a7191e8efb | ||
|
|
e1f4d791ae | ||
|
|
c1d28381e8 | ||
|
|
2fa8371bae | ||
|
|
a1cfdf1a5b | ||
|
|
806fcb6ed2 | ||
|
|
467b0fa988 | ||
|
|
a420d5b203 | ||
|
|
e9c7f5d664 | ||
|
|
c85f12fe2c | ||
|
|
13e5644c89 | ||
|
|
5be3aec7d4 | ||
|
|
5e25a4a00e | ||
|
|
810cf9ab2c | ||
|
|
eac029aef4 | ||
|
|
2a11de7571 | ||
|
|
12543be913 | ||
|
|
cfbf08dbf5 | ||
|
|
3649573ba1 | ||
|
|
0fdc02d5e9 | ||
|
|
0ffe8ef102 | ||
|
|
ce995812d4 | ||
|
|
cd22e1779d | ||
|
|
fbb50d8fb6 | ||
|
|
27172c2a19 | ||
|
|
f453dff438 | ||
|
|
a437a40eee | ||
|
|
70a173a16d | ||
|
|
7724fc74e5 | ||
|
|
6023c08554 | ||
|
|
2de56065af | ||
|
|
a5195920fa | ||
|
|
5676a13290 | ||
|
|
d11f0e864e | ||
|
|
df83fcc5b9 | ||
|
|
f21c756793 | ||
|
|
4b07ee2fa8 | ||
|
|
ae3a39ee65 | ||
|
|
e9f5bd4ac1 | ||
|
|
f5cf1ca08c | ||
|
|
1f4ad732fd | ||
|
|
37a1e67579 | ||
|
|
a372cbbf52 | ||
|
|
5637d37ee1 | ||
|
|
c370da2fef | ||
|
|
d168209721 | ||
|
|
ca0468b8d5 | ||
|
|
a67cf44453 | ||
|
|
039d26feeb | ||
|
|
a4bead1bde | ||
|
|
0d15024bd2 | ||
|
|
6509d726b3 | ||
|
|
a132f0f41d | ||
|
|
7c2ea3dcfd | ||
|
|
706c6d46da | ||
|
|
04915cc65a | ||
|
|
e2fb8827a7 | ||
|
|
10e7b66f38 | ||
|
|
05fda903c6 | ||
|
|
91e1eff763 | ||
|
|
2c4ffcfa7c | ||
|
|
34d63f3557 | ||
|
|
4bb47d7e01 | ||
|
|
a5613ebb10 | ||
|
|
ec80c2b9db | ||
|
|
a89418e33b | ||
|
|
0d88ff8dae | ||
|
|
4bdf9bff3a | ||
|
|
7fbb8838e7 | ||
|
|
1a2b45eebd | ||
|
|
366ea63209 | ||
|
|
6c0ad7fe1a | ||
|
|
ef9c90a43a | ||
|
|
239214ef92 | ||
|
|
65791a58e9 | ||
|
|
6e0f22323b | ||
|
|
4c8c35a25a | ||
|
|
a149f06f58 | ||
|
|
42f97f63d5 | ||
|
|
227652de2e | ||
|
|
dd205e849c | ||
|
|
b0057b130e | ||
|
|
05d994889d | ||
|
|
4b381049c3 | ||
|
|
33f3479569 | ||
|
|
6b940ed675 | ||
|
|
247be0c11f | ||
|
|
14b0e8875d | ||
|
|
bd51741b01 | ||
|
|
afd60b8a16 | ||
|
|
6e0659af4c | ||
|
|
6de1fa0878 | ||
|
|
61e00f1620 | ||
|
|
d64c043838 | ||
|
|
c8c75b38c3 | ||
|
|
2bdd0a0e8d | ||
|
|
dd3599f5b3 | ||
|
|
4131ad5016 | ||
|
|
4f74b3fafe | ||
|
|
177a487ead | ||
|
|
99a4966786 | ||
|
|
db9279a6e5 | ||
|
|
3036f43b75 | ||
|
|
f4560bd7d8 | ||
|
|
0d56127758 | ||
|
|
97b9ec5cc7 | ||
|
|
cdab3d0eff | ||
|
|
de991041c4 | ||
|
|
776c16cd49 | ||
|
|
d9f8746438 | ||
|
|
20d1c4d242 | ||
|
|
6edac37031 | ||
|
|
cea5a18a7a | ||
|
|
bf615303f1 | ||
|
|
ea043517c5 | ||
|
|
b84d9c5d55 | ||
|
|
063585f563 | ||
|
|
01304e807a | ||
|
|
d275b3fd08 | ||
|
|
66364354da | ||
|
|
48203aedf9 | ||
|
|
a6ca893ec5 | ||
|
|
d55f1163a2 | ||
|
|
80530012b8 | ||
|
|
d98a6adfb3 | ||
|
|
6c628afe5d | ||
|
|
abc99c7e69 | ||
|
|
fe25cd3bec | ||
|
|
ae3a35816e | ||
|
|
8ca4be5ac0 | ||
|
|
1c814946d5 | ||
|
|
1db59fc052 | ||
|
|
273a69258a | ||
|
|
3b0dc2195d | ||
|
|
bbb2539ace | ||
|
|
03cfe9bf62 | ||
|
|
e29a4d79ba | ||
|
|
4243bf9ba8 | ||
|
|
2eb51edfb6 | ||
|
|
715d564028 | ||
|
|
989b704efc | ||
|
|
7ae9627a79 | ||
|
|
097a1cc799 | ||
|
|
0bfaeb8521 | ||
|
|
625511d28b | ||
|
|
b6a58ee845 | ||
|
|
a349aed94c | ||
|
|
3db00534c2 | ||
|
|
82b96d1a14 | ||
|
|
b85ddd1a53 | ||
|
|
732f88ff51 | ||
|
|
c08139b812 | ||
|
|
a6a6e73b04 | ||
|
|
9971201004 | ||
|
|
e99b0f8052 | ||
|
|
7a59b2b25d | ||
|
|
b713b324f9 | ||
|
|
521e21072e | ||
|
|
f34845fd7d | ||
|
|
29ccadbd43 | ||
|
|
ffb4b395d0 | ||
|
|
19eba9526a | ||
|
|
09ed76904b | ||
|
|
22932241bd | ||
|
|
afc95d99cb | ||
|
|
5fde3c53b8 | ||
|
|
1135852f25 | ||
|
|
e892f0cb45 | ||
|
|
de56374c4d | ||
|
|
6512dbae1c | ||
|
|
3afda71349 | ||
|
|
568e5a9bb8 | ||
|
|
89e56ae279 | ||
|
|
339ac05443 | ||
|
|
9d92b8cc6d | ||
|
|
d9b3ba0ff2 | ||
|
|
4be6b11c1e | ||
|
|
6794da0738 | ||
|
|
5527170fab | ||
|
|
72cfa683cf | ||
|
|
e732eed98a | ||
|
|
5244642dee | ||
|
|
b329a44fef | ||
|
|
3a6b9f04f9 | ||
|
|
59f24df294 | ||
|
|
c93632421d | ||
|
|
97e0fd9f43 | ||
|
|
ea536c5537 | ||
|
|
970c906c97 | ||
|
|
fe738da633 | ||
|
|
5c559af936 | ||
|
|
bb80505b76 | ||
|
|
5e3da71ce4 | ||
|
|
a0cccb299e | ||
|
|
a560f6e9f6 | ||
|
|
95ae981698 | ||
|
|
e56974f4b2 | ||
|
|
fd28da2a3b | ||
|
|
257b35e4ae | ||
|
|
4398563b85 | ||
|
|
969eb67217 | ||
|
|
e23ace1bb0 | ||
|
|
0dfebbad9d | ||
|
|
f87f4bd8cc | ||
|
|
352caa85da | ||
|
|
8f61e9876f | ||
|
|
2ef333c66d | ||
|
|
c6ee44010c | ||
|
|
71d770e679 | ||
|
|
cf17b93201 | ||
|
|
08f284ce29 | ||
|
|
4336aeb0ad | ||
|
|
5fd3a45c64 | ||
|
|
77f8bfcf25 | ||
|
|
509a97e532 | ||
|
|
604683efd5 | ||
|
|
c731515b94 | ||
|
|
8d85158f91 | ||
|
|
0736f372dc | ||
|
|
fd19bb7cd5 | ||
|
|
0c2e9137a2 | ||
|
|
bf5a25a96f | ||
|
|
aa84f21fde | ||
|
|
b9de2b4b58 | ||
|
|
9754f2d1c5 | ||
|
|
f66fc06b4f | ||
|
|
79ceb56c60 | ||
|
|
a37210b22e | ||
|
|
ccf81ff7b9 | ||
|
|
a4c1a65f10 | ||
|
|
6bdea219bf | ||
|
|
02a82e1e59 | ||
|
|
d238b0b9f2 | ||
|
|
40026fbf53 | ||
|
|
4193818259 | ||
|
|
78840157ef | ||
|
|
f3d69a29b9 | ||
|
|
1ae6709b26 | ||
|
|
8cc44b3958 | ||
|
|
70e894c268 | ||
|
|
9ff3ab1a2b | ||
|
|
8167f6f232 | ||
|
|
de844e9b23 | ||
|
|
7214b71c29 | ||
|
|
be5df46803 | ||
|
|
25bd61558b | ||
|
|
41961de619 | ||
|
|
1ca3f6ef8a | ||
|
|
f97c94832a | ||
|
|
4ae7786362 | ||
|
|
d3d553ad5a | ||
|
|
4faab006e3 | ||
|
|
80621f598e | ||
|
|
eaf689fe2f | ||
|
|
211e3304f3 | ||
|
|
d4c3b70f15 | ||
|
|
7605df1bd9 | ||
|
|
f874941e4d | ||
|
|
b91ec48178 | ||
|
|
3c2f144795 | ||
|
|
437b2ab30a | ||
|
|
0271337f8e | ||
|
|
630a71c46c | ||
|
|
dcc2a5afe0 | ||
|
|
078e952f30 | ||
|
|
2d2fe4983c | ||
|
|
29ddc04f7b | ||
|
|
aac2da70cf | ||
|
|
f5cbe0c4fe | ||
|
|
ab28d0a9b3 | ||
|
|
6aaf4ed9d9 | ||
|
|
1b81a1f4a6 | ||
|
|
e838fe30de | ||
|
|
150329dd4a | ||
|
|
6d9779a497 | ||
|
|
130ece3d2e | ||
|
|
d63a794848 | ||
|
|
ba220abbbf | ||
|
|
3825575f70 | ||
|
|
8d69961130 | ||
|
|
740357d120 | ||
|
|
5638f0f24b | ||
|
|
c8a30e793a | ||
|
|
2264281e4d | ||
|
|
ce38d4ff6b | ||
|
|
59d7bce518 | ||
|
|
3c1e3cd38e | ||
|
|
a2eb0bf9fe | ||
|
|
74773ade62 | ||
|
|
3faf777db1 | ||
|
|
09e880a90d | ||
|
|
5d48ecf86a | ||
|
|
d5785e87e8 | ||
|
|
d4a43bf051 | ||
|
|
00d09aa01e | ||
|
|
9afdc55416 | ||
|
|
76c0432f96 | ||
|
|
4434796aab | ||
|
|
0faa24d5d3 | ||
|
|
2c942c8809 | ||
|
|
c15acc4ce3 | ||
|
|
b056610eaa | ||
|
|
8eb9fb1834 | ||
|
|
7ec518b41c | ||
|
|
dc15914a85 | ||
|
|
6c3b87c9b9 | ||
|
|
2fb31f5944 | ||
|
|
8be42e78de | ||
|
|
6d242ee6c3 | ||
|
|
6c910d2b5f | ||
|
|
3b22f59988 | ||
|
|
afdab0300e | ||
|
|
0caa56e618 | ||
|
|
e5dc843d6a | ||
|
|
26533c47e7 | ||
|
|
3efd1ee325 | ||
|
|
56a1367322 | ||
|
|
544aba53dc | ||
|
|
d68bbbf9a1 | ||
|
|
df3aeed291 | ||
|
|
489737274a | ||
|
|
867ba7b68f | ||
|
|
4c1fabffc3 | ||
|
|
6a52d03329 | ||
|
|
17f00e6fea | ||
|
|
c67bc33c23 | ||
|
|
bb80dcb4e4 | ||
|
|
8fff3e5389 | ||
|
|
233109d23e | ||
|
|
a6aa78e3b6 | ||
|
|
7536322e53 | ||
|
|
b690e3d149 | ||
|
|
aabf270144 | ||
|
|
61a4f15e53 | ||
|
|
de212322e2 | ||
|
|
cda18fb957 | ||
|
|
011ba5056a | ||
|
|
44c871270b | ||
|
|
9f6b0e1018 | ||
|
|
2d9293732b | ||
|
|
d4a131ad31 | ||
|
|
fa2316fb28 | ||
|
|
6e5d1fb613 | ||
|
|
e45f0f0299 | ||
|
|
62125d0284 | ||
|
|
d5ffede5ea | ||
|
|
1679a3f844 | ||
|
|
212bb33142 | ||
|
|
1d8c80c062 | ||
|
|
e8e11257d2 | ||
|
|
1611049623 | ||
|
|
7d195367a8 | ||
|
|
b4236b9a95 | ||
|
|
d2b1404907 | ||
|
|
88a4f25689 | ||
|
|
161dee89ec | ||
|
|
34af33607b | ||
|
|
5bb188a822 | ||
|
|
f11aab6c19 | ||
|
|
1f133dbcd0 | ||
|
|
60bb6f105d | ||
|
|
df4680ee09 | ||
|
|
879576b613 | ||
|
|
6aaab09601 | ||
|
|
5da42575fd | ||
|
|
7a105a1538 | ||
|
|
fe256d6a62 | ||
|
|
5f175141e1 | ||
|
|
983e2df065 | ||
|
|
7408d7bc95 | ||
|
|
1d9820a7c9 | ||
|
|
c536f7d342 | ||
|
|
6d9dfb5deb | ||
|
|
a3d469a101 | ||
|
|
16d5a70c08 | ||
|
|
b7e2d7fb8e | ||
|
|
fb5f7a336d | ||
|
|
78dc5f4bf4 | ||
|
|
45dbf5393f | ||
|
|
97ecb0a5d6 | ||
|
|
6f58e9e7bb | ||
|
|
0de19a09ad | ||
|
|
17a56189dc | ||
|
|
520f9801be | ||
|
|
03a6b0311f | ||
|
|
9fed1cde25 | ||
|
|
5c7b175e90 | ||
|
|
30b29de8ce | ||
|
|
a5f9331023 | ||
|
|
d8b9d8431e | ||
|
|
91a2ce2b3f | ||
|
|
4da1871567 | ||
|
|
e809f77461 | ||
|
|
1a922d41df | ||
|
|
050f8f3c81 | ||
|
|
5fc32c7b85 | ||
|
|
e96d23cc3f | ||
|
|
964fa69fb4 | ||
|
|
c34e2ab3e1 | ||
|
|
f1a33db800 | ||
|
|
820519b4f7 | ||
|
|
2e3b56c52f | ||
|
|
8f137cf49d | ||
|
|
34688852a4 | ||
|
|
de170ebdd2 | ||
|
|
e5ae1db49c | ||
|
|
151f28081a | ||
|
|
63035196af | ||
|
|
213a64b1ff | ||
|
|
e08d803a33 | ||
|
|
df1a939798 | ||
|
|
f259d81249 | ||
|
|
848f0db3d1 | ||
|
|
9e2d47eab5 | ||
|
|
589761bfd9 | ||
|
|
88fa103acb | ||
|
|
9849bc055c | ||
|
|
1cf75a7169 | ||
|
|
e297dff0d4 | ||
|
|
aafd7ed21f | ||
|
|
ab2c31aa8a | ||
|
|
18fde86a20 | ||
|
|
47111819e7 | ||
|
|
ddd3f7c196 | ||
|
|
1738f92ce2 | ||
|
|
074695b50c | ||
|
|
ba28bc94d3 | ||
|
|
da19a07943 | ||
|
|
95ac136720 | ||
|
|
ecced27853 | ||
|
|
e86aa6b541 | ||
|
|
91f74b44a0 | ||
|
|
35d8e28b8c | ||
|
|
26a6af4ab2 | ||
|
|
20785926e2 | ||
|
|
ecc500fc91 | ||
|
|
c22ac1e60a | ||
|
|
55d9aa2a4c | ||
|
|
1d391e68e5 | ||
|
|
0429c44d18 | ||
|
|
2c1bcaafc1 | ||
|
|
35891c74cd | ||
|
|
2ca6e67b37 | ||
|
|
66d0ee8156 | ||
|
|
6e72be54cb | ||
|
|
6138b060d7 | ||
|
|
308d661d7e | ||
|
|
4e106c2355 | ||
|
|
456160fa29 | ||
|
|
07edb998e4 | ||
|
|
b553ac58d3 | ||
|
|
2c26f43035 | ||
|
|
3e52f804a7 | ||
|
|
1b49844012 | ||
|
|
75b7583832 | ||
|
|
75d45e8907 | ||
|
|
d754eb74f7 | ||
|
|
b78bd5d6fd | ||
|
|
5d53344b75 | ||
|
|
7cd58bd534 | ||
|
|
9826bf67c2 | ||
|
|
350fe124d0 | ||
|
|
20aac83e5e | ||
|
|
9d1c822ba1 | ||
|
|
b8d46e2863 | ||
|
|
cd2f2d42a3 | ||
|
|
60252267d5 | ||
|
|
4bfab89292 | ||
|
|
1d3e8aedcd | ||
|
|
b25af641e2 | ||
|
|
75c41644c6 | ||
|
|
3e221f3b6a | ||
|
|
e7c3f8bf47 | ||
|
|
4c1dca73c4 | ||
|
|
0bbb6b91fe | ||
|
|
ee93d9b495 | ||
|
|
535abdc481 | ||
|
|
3684126250 | ||
|
|
bf8ac214a1 | ||
|
|
d3fc34c824 | ||
|
|
8769b5d1b5 | ||
|
|
59bb132dd7 | ||
|
|
8a53fa0aab | ||
|
|
71f42e405d | ||
|
|
64b89dd226 | ||
|
|
27d6b855b8 | ||
|
|
9c7b34d5e6 | ||
|
|
20c4f0dc10 | ||
|
|
7c166d85e1 | ||
|
|
093080894b | ||
|
|
76c0fa2fe2 | ||
|
|
ac3a17b178 | ||
|
|
9a2243da9f | ||
|
|
0f5aa9f8d9 | ||
|
|
673f7a82d1 | ||
|
|
c76b527b93 | ||
|
|
ded4f95537 | ||
|
|
87251878a5 | ||
|
|
3a14f363d9 | ||
|
|
84921f04cd | ||
|
|
8272386733 | ||
|
|
33988ed3fb | ||
|
|
b16475b8bd | ||
|
|
411b8e3cb6 | ||
|
|
848e26eec6 | ||
|
|
916da16523 | ||
|
|
d165c081f7 | ||
|
|
62e86f9507 | ||
|
|
992de7d66e | ||
|
|
46ab7bbcbe | ||
|
|
b04bced37f | ||
|
|
5b306f365e | ||
|
|
ce8950da43 | ||
|
|
0e1c7cd8ed | ||
|
|
fba6dd750d | ||
|
|
e73b6bc39e | ||
|
|
fa3cbbee67 | ||
|
|
029e52eb5f | ||
|
|
13914507e8 | ||
|
|
533f0213e3 | ||
|
|
13335cadc6 | ||
|
|
95d6dac055 | ||
|
|
2001d7f02a | ||
|
|
bae5b70023 | ||
|
|
8341d343d3 | ||
|
|
278a56e580 | ||
|
|
6ab44ccf0c | ||
|
|
b864791fa6 | ||
|
|
918898d6fe | ||
|
|
566e5dea57 | ||
|
|
5d1bfa18b1 | ||
|
|
800540ce7f | ||
|
|
74ee74365e | ||
|
|
75f6235111 | ||
|
|
fe415cbd77 | ||
|
|
dc69c0d3e5 | ||
|
|
40b3f39249 | ||
|
|
a9acc55735 | ||
|
|
9c07612274 | ||
|
|
3e87d88825 | ||
|
|
e280c0c5ca | ||
|
|
6614b56298 | ||
|
|
02c3894fc9 | ||
|
|
68f7dc9512 | ||
|
|
64f750a097 | ||
|
|
48bc18017e | ||
|
|
18d1bc56fd | ||
|
|
035fa3be3f | ||
|
|
f62723c274 | ||
|
|
aca59019c1 | ||
|
|
2186ea9a90 | ||
|
|
928f6e7009 | ||
|
|
1e4d07a52c | ||
|
|
64ed5fca3b | ||
|
|
4c7fc79843 | ||
|
|
153d77359f | ||
|
|
c8a2fb92d2 | ||
|
|
dcc252b371 | ||
|
|
846aadd7c6 | ||
|
|
3c604db234 | ||
|
|
cb3efb1c1d | ||
|
|
1423db35eb | ||
|
|
1fc579e907 | ||
|
|
827c4e31ee | ||
|
|
c2a1ed926e | ||
|
|
4f86c117c3 | ||
|
|
93817ba92f | ||
|
|
18153e0fcc | ||
|
|
3123f6444f | ||
|
|
cb2a7a88fc | ||
|
|
e530111283 | ||
|
|
4e97a3b3d5 | ||
|
|
332c4a1f98 | ||
|
|
8541b95d8b | ||
|
|
e4584e3f04 | ||
|
|
134c43ad9e | ||
|
|
e74b4b35b9 | ||
|
|
16e7194dfe | ||
|
|
168ec9092a | ||
|
|
914b6c757d | ||
|
|
48d10d701e | ||
|
|
6479e94c4f | ||
|
|
fb3a9f1f29 | ||
|
|
e9d7df8862 | ||
|
|
123de56f38 | ||
|
|
8627132d6a | ||
|
|
3ef9c4c626 | ||
|
|
aec03294d6 | ||
|
|
2e6e1f4060 | ||
|
|
07f1103784 | ||
|
|
ffc8f133c9 | ||
|
|
507f2a4c7c | ||
|
|
1c9e9b9367 | ||
|
|
4d81775f8d | ||
|
|
cf042931b6 | ||
|
|
f6a931599a | ||
|
|
1b17049e94 | ||
|
|
81c039d645 | ||
|
|
932b0ccf24 | ||
|
|
e245edc843 | ||
|
|
8494ed8ac3 | ||
|
|
371f14d2e4 | ||
|
|
3e5c7f62d0 | ||
|
|
1109fbfcc3 | ||
|
|
ff88f242fa | ||
|
|
bd3dd69ae1 | ||
|
|
06780c2805 | ||
|
|
e44e227af6 | ||
|
|
4ca06a9218 | ||
|
|
9e29761581 | ||
|
|
110c389d85 | ||
|
|
d856ed89ff | ||
|
|
fa747515e9 | ||
|
|
b15c9d7655 | ||
|
|
15c3ee4af2 | ||
|
|
748248deab | ||
|
|
70671ac672 | ||
|
|
f70f670ed3 | ||
|
|
4b685716d5 | ||
|
|
252c812125 | ||
|
|
69a437a1a8 | ||
|
|
b8b36b6248 | ||
|
|
28e24cb9d6 | ||
|
|
2a0609fdb8 | ||
|
|
b3233cab71 | ||
|
|
bf19f5b9c0 | ||
|
|
08a879bbb1 | ||
|
|
405a3eda60 | ||
|
|
49acfc496b | ||
|
|
a1932fa3dc | ||
|
|
87a8706299 | ||
|
|
92ec46147b | ||
|
|
cd514285d9 | ||
|
|
2bda7566b4 | ||
|
|
43488cb57b | ||
|
|
137fbb638b | ||
|
|
782bb11894 | ||
|
|
76ed8d58fa | ||
|
|
8204139df8 | ||
|
|
7926684930 | ||
|
|
73946a4ede | ||
|
|
aa88115d45 | ||
|
|
496c08b075 | ||
|
|
2388d1782f | ||
|
|
e0e1c59d41 | ||
|
|
f2cb6ce972 | ||
|
|
ed3535e9c9 | ||
|
|
62f1830197 | ||
|
|
2fb62fe8be | ||
|
|
355689ed19 | ||
|
|
75614fb13c | ||
|
|
5c4a864680 | ||
|
|
eaeff891d6 | ||
|
|
f0ab40d748 | ||
|
|
3243cbf039 | ||
|
|
eb171ecb21 | ||
|
|
e497af4c26 | ||
|
|
43b8941f7a | ||
|
|
0b16839d7f | ||
|
|
164ba46259 | ||
|
|
b174f7a023 | ||
|
|
c9ec9f14de | ||
|
|
597c071c3d | ||
|
|
f860f57363 | ||
|
|
91d05434ca | ||
|
|
5b0aba99bb | ||
|
|
87c7d1a5f4 | ||
|
|
d841d69bd4 | ||
|
|
512bf1d013 | ||
|
|
02bf5ada89 | ||
|
|
adbd58a949 | ||
|
|
a0959d2730 | ||
|
|
f455722bed | ||
|
|
735d23c9eb | ||
|
|
0fd6a23c78 | ||
|
|
fd73d8d67e | ||
|
|
347366e8d7 | ||
|
|
eb8d4abcbe | ||
|
|
86acccebb0 | ||
|
|
8f184f76fa | ||
|
|
1daabfa3e0 | ||
|
|
90b49106f0 | ||
|
|
1a5638426c | ||
|
|
8d4da009af | ||
|
|
89571d57bd | ||
|
|
d3b578fe8f | ||
|
|
d29d910ac6 | ||
|
|
5d4e06074a | ||
|
|
98522cf6e4 | ||
|
|
7cdb751606 | ||
|
|
4ffc90f963 | ||
|
|
8da6572074 | ||
|
|
ee64aad670 | ||
|
|
92cee2321f | ||
|
|
7f969b1252 | ||
|
|
a02e2e1fa1 | ||
|
|
d690e1b37a | ||
|
|
3300c2302c | ||
|
|
685470cf23 | ||
|
|
c545a959ac | ||
|
|
a7832ef40f | ||
|
|
3e941999d5 | ||
|
|
bebdfc259c | ||
|
|
d31a920eb7 | ||
|
|
ec87821bcd | ||
|
|
21df0e32c4 | ||
|
|
afaa235c75 | ||
|
|
8d97e7136f | ||
|
|
89ac422929 | ||
|
|
d8d55f032e | ||
|
|
c83d694c7a | ||
|
|
ea55650d45 | ||
|
|
ec1aee60a1 | ||
|
|
3a7a0918d3 | ||
|
|
8bf90714da | ||
|
|
d8b59925b0 | ||
|
|
d37fd6bea0 | ||
|
|
0f6263d82e | ||
|
|
e7c70945e6 | ||
|
|
095a936891 | ||
|
|
c49ce91fac | ||
|
|
dd52727055 | ||
|
|
b48068c63c | ||
|
|
c39d04e8a5 | ||
|
|
0eff8e4bc8 | ||
|
|
178551a467 | ||
|
|
720739e50a | ||
|
|
46d1537d8f | ||
|
|
63b2bb55a1 | ||
|
|
e7b41f9a4c | ||
|
|
dd0aed4614 | ||
|
|
b9b4f2bb7f | ||
|
|
3533d2a2cc | ||
|
|
26d9ef5398 | ||
|
|
06c210f5c8 | ||
|
|
a545c42047 | ||
|
|
da4b4de292 | ||
|
|
fd936e5bf3 | ||
|
|
a0f840bcf8 | ||
|
|
33d2a77e37 | ||
|
|
dc11340faf | ||
|
|
06d921d855 | ||
|
|
91b602341b | ||
|
|
ad853ca342 | ||
|
|
14fa3481b0 | ||
|
|
2b6fee0455 | ||
|
|
a48e6f82d1 | ||
|
|
1020904fe0 | ||
|
|
6aaced0c04 | ||
|
|
3646c0d0a3 | ||
|
|
44c8574f1b | ||
|
|
ea1ff65db7 | ||
|
|
85b7147927 | ||
|
|
6b54c342aa | ||
|
|
60720b04db | ||
|
|
323a593159 | ||
|
|
baef94f14a | ||
|
|
59b3cfee66 | ||
|
|
cbc85ca98f | ||
|
|
425c8cd1d3 | ||
|
|
1d7949ded6 | ||
|
|
2507170816 | ||
|
|
2c83425b42 | ||
|
|
80e00a80d5 | ||
|
|
1da281de8a | ||
|
|
98baab4d03 | ||
|
|
a3d5479878 | ||
|
|
a49dc04f5d | ||
|
|
d1c0c9739d | ||
|
|
7415b07586 | ||
|
|
441069aa76 | ||
|
|
8c5bf55b51 | ||
|
|
b6d6955b39 | ||
|
|
0d68b1a73e | ||
|
|
15b7c241ff | ||
|
|
de9c62617b | ||
|
|
a0e05115a3 | ||
|
|
023663b268 | ||
|
|
aaf58272f1 | ||
|
|
5ebaf5663d | ||
|
|
7dc3e6a08b | ||
|
|
5a5f817e59 | ||
|
|
b650320a34 | ||
|
|
424fd8e4d3 | ||
|
|
cfbf80fdfe | ||
|
|
9b8ced2803 | ||
|
|
630a1d42b8 | ||
|
|
b69ff6ca8a | ||
|
|
1a23b6178b | ||
|
|
de536d7305 | ||
|
|
6dcd33bbc5 | ||
|
|
c6df78eb81 | ||
|
|
d1babe27ec | ||
|
|
7596f62ca5 | ||
|
|
139e57f1eb | ||
|
|
e87d85b088 | ||
|
|
91b79b703c | ||
|
|
bdefa4a967 | ||
|
|
3883c509b9 | ||
|
|
b82efb6e3c | ||
|
|
a50e109043 | ||
|
|
8b5db12e1d | ||
|
|
f1f8163bb7 | ||
|
|
c0fac90b52 | ||
|
|
15717ddca0 | ||
|
|
a7ce9aaca5 | ||
|
|
d8df8e1033 | ||
|
|
440a35e491 | ||
|
|
dbbc6ed0bb | ||
|
|
86fbb383fd | ||
|
|
18f34b4f83 | ||
|
|
1c07a74bef | ||
|
|
2df93c2ceb | ||
|
|
6ca40afac0 | ||
|
|
36a8f044ae | ||
|
|
caed86d846 | ||
|
|
276e5453f1 | ||
|
|
459e36c027 | ||
|
|
0f81986684 | ||
|
|
bc54e536af | ||
|
|
acb57b3e9c | ||
|
|
725f8571bb | ||
|
|
b7c7c0e862 | ||
|
|
de0e30de57 | ||
|
|
3f671b918a | ||
|
|
b8b942cdae | ||
|
|
9492363b22 | ||
|
|
3ee144459f | ||
|
|
c0c80c0fdf | ||
|
|
0146a077e8 | ||
|
|
7c80b61666 | ||
|
|
a0fcf515cd | ||
|
|
1719ad81a4 | ||
|
|
51a9a7b75d | ||
|
|
d128f3e14e | ||
|
|
4498b89ac4 | ||
|
|
e576a58ead | ||
|
|
eb4375258e | ||
|
|
0cbc2001e2 | ||
|
|
6bf5dbabee | ||
|
|
6a89646e66 | ||
|
|
e91b0500c5 | ||
|
|
2a17361a90 | ||
|
|
1eca3a8603 | ||
|
|
86f37863a7 | ||
|
|
f3234a6b5e | ||
|
|
73a8c302e9 | ||
|
|
989f2d3001 | ||
|
|
2badcfa546 | ||
|
|
643cd87706 | ||
|
|
98c85441f8 | ||
|
|
1345f996da | ||
|
|
ff48f08241 | ||
|
|
b5f438aa0c | ||
|
|
384e14b32d | ||
|
|
a2266adb3f | ||
|
|
016e743653 | ||
|
|
00adf3631a | ||
|
|
09aef18999 | ||
|
|
1d86aac338 | ||
|
|
80173634a0 | ||
|
|
c9598b674c | ||
|
|
2a588d1e9a | ||
|
|
5a6c06c8a3 | ||
|
|
b2ef4e9619 | ||
|
|
9e9d6e45b4 | ||
|
|
6752457ad8 | ||
|
|
ddcb5cd4d3 | ||
|
|
a54b2db81b | ||
|
|
6740124364 | ||
|
|
157731e4f8 | ||
|
|
2dd1496ef4 | ||
|
|
d1e4e72693 | ||
|
|
77e8143290 | ||
|
|
7f791d4919 | ||
|
|
d7e0468776 | ||
|
|
f6c611bbba | ||
|
|
0990ac4fc1 | ||
|
|
e91f8f693b | ||
|
|
2a7dbda133 | ||
|
|
793e542312 | ||
|
|
240269eb25 | ||
|
|
c744dc8cc3 | ||
|
|
d596bdb454 | ||
|
|
bec54b4283 | ||
|
|
061b88f5b5 | ||
|
|
8704eff632 | ||
|
|
fb16f25b07 | ||
|
|
e8057a5c8a | ||
|
|
3c5edb6171 | ||
|
|
e36a191240 | ||
|
|
ecdfd65f50 | ||
|
|
4294081abb | ||
|
|
5218543c58 | ||
|
|
d8332a27e5 | ||
|
|
673658dfd2 | ||
|
|
6528d3d7da | ||
|
|
16af479b83 | ||
|
|
13187de97d | ||
|
|
32850f6770 | ||
|
|
4a7f4bde4a | ||
|
|
c518f373df | ||
|
|
0010119440 | ||
|
|
f4636fdca2 | ||
|
|
91065a6168 | ||
|
|
efa8d5c575 | ||
|
|
4108d7827a | ||
|
|
04998d0215 | ||
|
|
d0efa5d3fe | ||
|
|
c87e72e08e | ||
|
|
efb82847cb | ||
|
|
f37e267a5e | ||
|
|
69928219a3 | ||
|
|
5ccd40f530 | ||
|
|
8798340d48 | ||
|
|
e8d2959350 | ||
|
|
fdf8845a2f | ||
|
|
4073a7abc3 | ||
|
|
ffd9a34cf5 | ||
|
|
07226c6d21 | ||
|
|
b1bc7c1fc2 | ||
|
|
1b33f0cea9 | ||
|
|
8ece3b00f5 | ||
|
|
c9c58b65a6 | ||
|
|
66becbc4cc | ||
|
|
5b8612c919 | ||
|
|
430c22e06e | ||
|
|
76b62eda3a | ||
|
|
bc983162f3 | ||
|
|
4922598aee | ||
|
|
b2f8bb9990 | ||
|
|
9ee92fb9e9 | ||
|
|
f1d838de6b | ||
|
|
ec92a4cd34 | ||
|
|
b3b9788d37 | ||
|
|
67739e8e39 | ||
|
|
be3ed7d380 | ||
|
|
9b4d58cfe8 | ||
|
|
fb6a8d999c | ||
|
|
b2f6a06a1f | ||
|
|
f7da32702f | ||
|
|
219d2246fa | ||
|
|
979b5eb89c | ||
|
|
a58811b1bf | ||
|
|
be0e18d4b0 | ||
|
|
981bf1d56f | ||
|
|
fea6f0ce81 | ||
|
|
5859ac7a58 | ||
|
|
d2c2503cfa | ||
|
|
566833da6e | ||
|
|
d174602cc0 | ||
|
|
2a4caa856e | ||
|
|
46bc04f69f | ||
|
|
157962e42a | ||
|
|
16db28060c | ||
|
|
bb8fd5500d | ||
|
|
d0df105dda | ||
|
|
a061fb5421 | ||
|
|
fd17e5a4c0 | ||
|
|
cd8bc7a7a1 | ||
|
|
e22a586a41 | ||
|
|
5017c5a5f1 | ||
|
|
03cbab5267 | ||
|
|
2c22837d9f | ||
|
|
4d64df37f5 | ||
|
|
b224f1d78d | ||
|
|
52e018989d | ||
|
|
eb14193b23 | ||
|
|
001c2c88cd | ||
|
|
98ab83976e | ||
|
|
9cd5bf2992 | ||
|
|
e876712af5 | ||
|
|
9fc8d66601 | ||
|
|
12d86493bf | ||
|
|
c97cba69b9 | ||
|
|
63ed7a734b | ||
|
|
0e338ef453 | ||
|
|
d914b38f9f | ||
|
|
3ee00a4824 | ||
|
|
5198c69f6b | ||
|
|
40704c4549 | ||
|
|
83df59e5f1 | ||
|
|
246602e275 | ||
|
|
d3449609da | ||
|
|
a872058704 | ||
|
|
3033376028 | ||
|
|
712424c339 | ||
|
|
0bda636113 | ||
|
|
28092d6862 | ||
|
|
cecafb726c | ||
|
|
8418c21096 | ||
|
|
c4ace1972a | ||
|
|
862df1d2df | ||
|
|
487c1a58d6 | ||
|
|
c06c3d48d2 | ||
|
|
7d3ad5a639 | ||
|
|
03b2d02742 | ||
|
|
103ce44ba9 | ||
|
|
22219af133 | ||
|
|
7d7377ab15 | ||
|
|
af8fc53704 | ||
|
|
e80a5d82a4 | ||
|
|
2b73e745da | ||
|
|
e61a1080f7 | ||
|
|
464f336790 | ||
|
|
1dc6e085cc | ||
|
|
8594ff0c23 | ||
|
|
e58963410e | ||
|
|
1e0d118930 | ||
|
|
723e6dd13f | ||
|
|
e941af0905 | ||
|
|
24c8e29691 | ||
|
|
8911bdf966 | ||
|
|
0834759e1a | ||
|
|
15c56dfcb8 | ||
|
|
b98ad47618 | ||
|
|
4778c5f5e8 | ||
|
|
d041671dc5 | ||
|
|
bb8c0d264e | ||
|
|
c7da8c5fd3 | ||
|
|
5cab65d197 | ||
|
|
30789ff6e2 | ||
|
|
e6ece10716 | ||
|
|
ea7a255006 | ||
|
|
98df1f5312 | ||
|
|
b5bf627fb1 | ||
|
|
6104150b77 | ||
|
|
a13bae2f39 | ||
|
|
fd80e98207 | ||
|
|
f43b95f001 | ||
|
|
38802d3522 | ||
|
|
9f7813622d | ||
|
|
75d67207aa | ||
|
|
e596a8f731 | ||
|
|
5b0cc73792 | ||
|
|
2163d4465f | ||
|
|
8becf45714 | ||
|
|
2bf08787d8 | ||
|
|
853ead26ca | ||
|
|
0ccb6cb873 | ||
|
|
b8f7e4211c | ||
|
|
e46ff3de8b | ||
|
|
b581d0c44f | ||
|
|
0b613812f7 | ||
|
|
a02e08a879 | ||
|
|
4d066a762f | ||
|
|
109d7d87bd | ||
|
|
3df740702c | ||
|
|
8a30a65818 | ||
|
|
01703aff43 | ||
|
|
06bb6f7bff | ||
|
|
9d62931af9 | ||
|
|
e33738a876 | ||
|
|
f887f5dca3 | ||
|
|
257c16690a | ||
|
|
7114e88992 | ||
|
|
de7e869ca9 | ||
|
|
eaee9c9522 | ||
|
|
bee11a6d41 | ||
|
|
647e44147f | ||
|
|
4a5d46915d | ||
|
|
8ad19585cb | ||
|
|
951a33fae9 | ||
|
|
bcf174cd1e | ||
|
|
1e82909f58 | ||
|
|
33e83b8414 | ||
|
|
592c56cb20 | ||
|
|
710528c01a | ||
|
|
03cadc2604 | ||
|
|
dd73bb95a4 | ||
|
|
40e0a55378 | ||
|
|
269884d9f3 | ||
|
|
fcd548c313 | ||
|
|
140a8b6804 | ||
|
|
b5378c1296 | ||
|
|
e53d8fd4fa | ||
|
|
0dbde32ed4 | ||
|
|
1445d6ea8c | ||
|
|
5385431051 | ||
|
|
f14f4498fb | ||
|
|
d506fdb68c | ||
|
|
9c10186158 | ||
|
|
3eed51dbac | ||
|
|
1c1855f0c3 | ||
|
|
e0a277fa45 | ||
|
|
3d6c7171d2 | ||
|
|
fc2786f5e8 | ||
|
|
174dbb5e74 | ||
|
|
0fee90e4df | ||
|
|
0cced44491 | ||
|
|
f21f758591 | ||
|
|
68517c15f2 | ||
|
|
11ee142e4b | ||
|
|
51e9527d53 | ||
|
|
1e1d047e07 | ||
|
|
62f1e39e6e | ||
|
|
05756da495 | ||
|
|
fa35b2a66f | ||
|
|
268cd131dc | ||
|
|
26997ad5c3 | ||
|
|
ce1786f128 | ||
|
|
d2094e2b68 | ||
|
|
075b2df738 | ||
|
|
ec3c31a106 | ||
|
|
888057f64a | ||
|
|
3c6c4d9601 | ||
|
|
5e8bcf8faf | ||
|
|
0d6f2f93bf | ||
|
|
937b00cfcc | ||
|
|
0d4432720c | ||
|
|
0ec49643ee | ||
|
|
0d80ea4f4c | ||
|
|
d2b26124e4 | ||
|
|
343116ea24 | ||
|
|
10dc699b21 | ||
|
|
e2183c2214 | ||
|
|
4994064e6e | ||
|
|
015c5f07bc | ||
|
|
a40b9f4054 | ||
|
|
a0b6a3bed6 | ||
|
|
ee8d65977d | ||
|
|
b4ea11e55e | ||
|
|
b8d2ef1eb5 | ||
|
|
0efeffeaa3 | ||
|
|
9de5950f4d | ||
|
|
26488b793a | ||
|
|
7a86d272bb | ||
|
|
5a6c2dfcd5 | ||
|
|
4d780904d1 | ||
|
|
0a6fa65075 | ||
|
|
6440220640 | ||
|
|
4350c9a72b | ||
|
|
77feae0ab9 | ||
|
|
1261696ba2 | ||
|
|
6b35a0a527 | ||
|
|
fd33ff81c9 | ||
|
|
7e891ecb79 | ||
|
|
178b1e8bb0 | ||
|
|
12840f2428 | ||
|
|
9d50f03cb1 | ||
|
|
8c1688657a | ||
|
|
833cb99f41 | ||
|
|
bd5d84abcd | ||
|
|
d451ba9b6e | ||
|
|
14bd02a569 | ||
|
|
4beace1bb0 | ||
|
|
6996dfcd3b | ||
|
|
42c46d7d5c | ||
|
|
9b31ce83c5 | ||
|
|
cb5250527b | ||
|
|
0b160a6741 | ||
|
|
dff34a8ae2 | ||
|
|
8f780ad89e | ||
|
|
4624ef393d | ||
|
|
2ce8a890e2 | ||
|
|
90e0e9000e | ||
|
|
a6bb1c156d | ||
|
|
31db8161b5 | ||
|
|
c0d1448080 | ||
|
|
4e4f4e60b6 | ||
|
|
dcc83271af | ||
|
|
a38458c9be | ||
|
|
7934f65ae8 | ||
|
|
f0b73fd696 | ||
|
|
aea0cec061 | ||
|
|
7ac56b1a0c | ||
|
|
f5ed0b700f | ||
|
|
1ff3b83766 | ||
|
|
40eca1727e | ||
|
|
9505e68ef7 | ||
|
|
5847806a16 | ||
|
|
e427ea44aa | ||
|
|
8df8bf33a4 | ||
|
|
29d2b942e8 | ||
|
|
df5684a9f8 | ||
|
|
992cdb992a | ||
|
|
db0dc71319 | ||
|
|
2c871d1339 | ||
|
|
9673922ca1 | ||
|
|
d311870b61 | ||
|
|
8dd1ff593a | ||
|
|
0f64a769c2 | ||
|
|
a8d150db5c | ||
|
|
d7e6367ff3 | ||
|
|
7b84d8c3d5 | ||
|
|
b3f724c799 | ||
|
|
a7be6504a2 | ||
|
|
e025df0824 | ||
|
|
c3392d5386 | ||
|
|
1da5357df6 | ||
|
|
2c09e6a7c0 | ||
|
|
2a0740e135 | ||
|
|
ac65357c8a | ||
|
|
92e1847c59 | ||
|
|
0500994def | ||
|
|
07c255f7f8 | ||
|
|
da911bfeb8 | ||
|
|
578d673a4e | ||
|
|
198b3c9f1b | ||
|
|
f5c567eb90 | ||
|
|
8ca09f6384 | ||
|
|
c8e58a1e5b | ||
|
|
386dfe42d0 | ||
|
|
7445f43b1b | ||
|
|
d477874535 | ||
|
|
5b77e78662 | ||
|
|
4b0b8d4de2 | ||
|
|
da79386cc3 | ||
|
|
b7de47b6fb | ||
|
|
3434907f52 | ||
|
|
099adb3853 | ||
|
|
dd9b1c047c | ||
|
|
a4ba6d1444 | ||
|
|
6084bb15cf | ||
|
|
42b568952e | ||
|
|
ef28459b61 | ||
|
|
d3bac307bb | ||
|
|
7e488b0fa3 | ||
|
|
7d7a6191ce | ||
|
|
5c644b31ca | ||
|
|
7b4398dfee | ||
|
|
663418e943 | ||
|
|
969bec248a | ||
|
|
8f487d7d4e | ||
|
|
89ebce79b2 | ||
|
|
1ff8c908b8 | ||
|
|
34ce510fbd | ||
|
|
e966ef96e5 | ||
|
|
b05b38b269 | ||
|
|
39f29399e7 | ||
|
|
8e1f1ff2e6 | ||
|
|
680d6c20ca | ||
|
|
c886e7949e | ||
|
|
8cd4cc7d0d | ||
|
|
e0b972f6d6 | ||
|
|
25daa9f2da | ||
|
|
d0fb5c3bd5 | ||
|
|
608ab8f4ad | ||
|
|
520b12e56b | ||
|
|
e95643f198 | ||
|
|
3b1712345b | ||
|
|
5c8ffe961e | ||
|
|
7983e82b60 | ||
|
|
6effe47bcc | ||
|
|
77d35b61a9 | ||
|
|
285a97aaf8 | ||
|
|
205080a210 | ||
|
|
ad29f2477e | ||
|
|
bc998988c2 | ||
|
|
1072d1306b | ||
|
|
80b470cfd3 | ||
|
|
b8eda40937 | ||
|
|
3df2b4b7f8 | ||
|
|
6141b60294 | ||
|
|
e1cfb0cab6 | ||
|
|
9b9782ce94 | ||
|
|
5d9eb25e38 | ||
|
|
f4a518ce6b | ||
|
|
2719ae5df2 | ||
|
|
3656e6ef54 | ||
|
|
a545d7d8b1 | ||
|
|
68ee2bdcdc | ||
|
|
da654fdff5 | ||
|
|
3127f7a31b | ||
|
|
f561de200d | ||
|
|
d7f9d5a66f | ||
|
|
d85a063db8 | ||
|
|
d6bf935ceb | ||
|
|
0d6ff822e7 | ||
|
|
1c0cc8e91c | ||
|
|
c4fb7b7928 | ||
|
|
43a791db65 | ||
|
|
217311211a | ||
|
|
ca55890ad2 | ||
|
|
d6ecf5b8a9 | ||
|
|
e52edde11f | ||
|
|
2e514735ec | ||
|
|
3d32c30d2d | ||
|
|
05235f8385 | ||
|
|
cd28a75c86 | ||
|
|
34075738ea | ||
|
|
fb38573b7e | ||
|
|
8a2f45ec23 | ||
|
|
fee2eb9251 | ||
|
|
24035c4ae8 | ||
|
|
aa8215df34 | ||
|
|
eb78e3d640 | ||
|
|
f8201cd2bc | ||
|
|
f37b3ecd26 | ||
|
|
88c0b8a8f0 | ||
|
|
e6dba59ae6 | ||
|
|
a7bc6b4f36 | ||
|
|
cacc5ac803 | ||
|
|
46dc0f144b | ||
|
|
3cc5275592 | ||
|
|
a3955a1ba8 | ||
|
|
89dfaf1d5d | ||
|
|
e8bbc117e1 | ||
|
|
fc6246c5cb | ||
|
|
ce8a0cab2a | ||
|
|
b99f45874f | ||
|
|
b36b6c78a2 | ||
|
|
5232dc6485 | ||
|
|
b1d9fc6c9a | ||
|
|
0dfa378e38 | ||
|
|
80ded84f7a | ||
|
|
8394535725 | ||
|
|
adf780d25b | ||
|
|
749ae3deb3 | ||
|
|
3da0c07bcd | ||
|
|
2196b53075 | ||
|
|
a8340f37bb | ||
|
|
7b1710ee63 | ||
|
|
38b7d9724e | ||
|
|
2b1ed49e9a | ||
|
|
017cf9e464 | ||
|
|
781f0c843e | ||
|
|
e2bf474332 | ||
|
|
7e2f1c9a8b | ||
|
|
8e798dde48 | ||
|
|
c05ae6e94c | ||
|
|
ff28ea8fa8 | ||
|
|
7914e89212 | ||
|
|
558ff90e27 | ||
|
|
ee69653a83 | ||
|
|
2d7760e67c | ||
|
|
95339a8338 | ||
|
|
39b1435725 | ||
|
|
b1d3e258bd | ||
|
|
c915926e0f | ||
|
|
25203934e6 | ||
|
|
6ff7fa74e2 | ||
|
|
91305262f1 | ||
|
|
6d16b68f11 | ||
|
|
f22e4f1cc7 | ||
|
|
4b1b2878ea | ||
|
|
2851d12357 | ||
|
|
73968e4277 | ||
|
|
7a6ecd86c6 | ||
|
|
b11d5514b9 | ||
|
|
1ff2a08d19 | ||
|
|
d1efd62e7b | ||
|
|
366c95cd3c | ||
|
|
7e03f3958e | ||
|
|
e069184721 | ||
|
|
5182441cb3 | ||
|
|
0de55a8ff5 | ||
|
|
0900d7c764 | ||
|
|
8540e09ba7 | ||
|
|
6e301601f9 | ||
|
|
1bf0eab2d9 | ||
|
|
d560f656f4 | ||
|
|
0bc256aa23 | ||
|
|
ebc073a52e | ||
|
|
23503dc439 | ||
|
|
1f4985c7dd | ||
|
|
ed88d9e10d | ||
|
|
906196bac3 | ||
|
|
cb9751be04 | ||
|
|
09e03d579b | ||
|
|
9fcca2698e | ||
|
|
bba8cd9b58 | ||
|
|
c8bb30289a | ||
|
|
69f56c1eb7 | ||
|
|
adc8e23356 | ||
|
|
88005c6603 | ||
|
|
33ee4c36b4 | ||
|
|
1a142b7fe6 | ||
|
|
90373806c0 | ||
|
|
a47634bf49 | ||
|
|
e03e58323b | ||
|
|
ab1e31c0e7 | ||
|
|
aa5505d693 | ||
|
|
74f8f687cf | ||
|
|
d54500bad5 | ||
|
|
4966b4d58d | ||
|
|
b75a4667c2 | ||
|
|
14579a9320 | ||
|
|
1d92eff974 | ||
|
|
91274267e5 | ||
|
|
c49f0ede16 | ||
|
|
42a0f452b1 | ||
|
|
c24ab9831a | ||
|
|
506a68ee6a | ||
|
|
1291f792ab | ||
|
|
51cfb1903d | ||
|
|
1b1c15694a | ||
|
|
251f1941a9 | ||
|
|
625617bb20 | ||
|
|
f80f161886 | ||
|
|
4b4889d5f2 | ||
|
|
fee34ba257 | ||
|
|
c29ab25dd2 | ||
|
|
e0308a11c9 | ||
|
|
a738998c2c | ||
|
|
6be22c474d | ||
|
|
da19743ba5 |
No files matched your search
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
# Windows has stack overflows when calling from Tauri, so we increase compiler size
|
# Windows has stack overflows when calling from Tauri, so we increase compiler size
|
||||||
[target.'cfg(windows)']
|
[target.'cfg(windows)']
|
||||||
rustflags = ["-C", "link-args=/STACK:16777220"]
|
rustflags = ["-C", "link-args=/STACK:16777220"]
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
|
# Editor configuration, see http://editorconfig.org
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
|
charset = utf-8
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
max_line_length = 100
|
max_line_length = 100
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.rs]
|
||||||
|
indent_size = 4
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
name: 🎮 Modrinth App bug
|
||||||
|
description: Report an issue in the Modrinth Launcher.
|
||||||
|
labels: [bug, app]
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Please confirm the following.
|
||||||
|
options:
|
||||||
|
- label: I checked the [existing issues](https://github.com/modrinth/code/issues) for duplicate problems
|
||||||
|
required: true
|
||||||
|
- label: I have tried resolving the issue using the [support portal](https://support.modrinth.com)
|
||||||
|
required: true
|
||||||
|
- label: I have ensured my Modrinth App installation is up to date
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: What version of the Modrinth App are you using?
|
||||||
|
description: Find this in ⚙️ Settings (bottom right) -> About -> App version.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: oses
|
||||||
|
attributes:
|
||||||
|
label: What operating systems are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Windows
|
||||||
|
- MacOS
|
||||||
|
- Linux
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Describe the bug
|
||||||
|
description: A clear and concise description of what the bug is. Include screenshots if applicable.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '...'
|
||||||
|
3. Scroll down to '...'
|
||||||
|
4. See error
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: A clear and concise description of what you expected to happen.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Add any other context about the problem here.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
name: 🌐 Website bug (modrinth.com)
|
||||||
|
description: Report an issue on the Modrinth website.
|
||||||
|
labels: [bug, frontend]
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Please confirm the following.
|
||||||
|
options:
|
||||||
|
- label: I checked the [existing issues](https://github.com/modrinth/code/issues) for duplicate problems
|
||||||
|
required: true
|
||||||
|
- label: I have tried resolving the issue using the [support portal](https://support.modrinth.com)
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: browsers
|
||||||
|
attributes:
|
||||||
|
label: What browsers are you seeing the problem on?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Chrome (including Arc, Brave, Opera, Vivaldi)
|
||||||
|
- Microsoft Edge
|
||||||
|
- Firefox
|
||||||
|
- Safari
|
||||||
|
- Other (please specify)
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Describe the bug
|
||||||
|
description: A clear and concise description of what the bug is. Include screenshots if applicable.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '...'
|
||||||
|
3. Scroll down to '...'
|
||||||
|
4. See error
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: A clear and concise description of what you expected to happen.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Add any other context about the problem here.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
@@ -1,11 +1,19 @@
|
|||||||
name: Bug report
|
name: 🛠️ API issue (api.modrinth.com)
|
||||||
description: Create a report to help us improve Modrinth
|
description: Report an issue regarding the Modrinth API.
|
||||||
labels: [bug]
|
labels: [bug, api]
|
||||||
body:
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Please confirm the following.
|
||||||
|
options:
|
||||||
|
- label: I checked the [existing issues](https://github.com/modrinth/code/issues) for duplicate problems
|
||||||
|
required: true
|
||||||
|
- label: I have tried resolving the issue using the [support portal](https://support.modrinth.com)
|
||||||
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Describe the bug
|
label: Describe the bug
|
||||||
description: A clear and concise description of what the bug is.
|
description: A clear and concise description of what the bug is. Include screenshots if applicable.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: textarea
|
- type: textarea
|
||||||
@@ -25,13 +33,9 @@ body:
|
|||||||
description: A clear and concise description of what you expected to happen.
|
description: A clear and concise description of what you expected to happen.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: System information
|
|
||||||
description: Add any information about what OS you are on (like Windows or Mac), and what version of the app you are using.
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Additional context
|
label: Additional context
|
||||||
description: Add any other context about the problem here. This might include logs, screenshots, etc. The more the merrier!
|
description: Add any other context about the problem here.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
+22
-4
@@ -1,10 +1,28 @@
|
|||||||
name: Enhancement
|
name: 💡 Feature Request
|
||||||
description: Suggest an enhancement for an existing Modrinth feature
|
description: Suggest an idea
|
||||||
labels: [enhancement]
|
labels: [enhancement]
|
||||||
|
|
||||||
body:
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Please confirm the following.
|
||||||
|
options:
|
||||||
|
- label: I checked the [existing issues](https://github.com/modrinth/code/issues) for duplicate feature requests
|
||||||
|
required: true
|
||||||
|
- label: I have checked that this feature request is not on our [roadmap](https://roadmap.modrinth.com)
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: projects
|
||||||
|
attributes:
|
||||||
|
label: What parts of Modrinth is your feature request related too?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- App
|
||||||
|
- Website
|
||||||
|
- API
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Is your suggested enhancement related to a problem? Please describe.
|
label: Is your suggested feature related to a problem? Please describe.
|
||||||
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
@@ -25,4 +43,4 @@ body:
|
|||||||
label: Additional context
|
label: Additional context
|
||||||
description: Add any other context or screenshots about the suggested enhancement here.
|
description: Add any other context or screenshots about the suggested enhancement here.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Discord
|
- name: 🫶 Support Portal
|
||||||
about: Ask questions on our Discord Server.
|
about: Get support using through our portal.
|
||||||
|
url: https://support.modrinth.com
|
||||||
|
- name: 💬 Chat
|
||||||
|
about: Join our Discord server to chat about Modrinth.
|
||||||
url: https://discord.modrinth.com
|
url: https://discord.modrinth.com
|
||||||
- name: Roadmap
|
- name: 🛣️ Roadmap
|
||||||
about: View our Roadmap. Please do not open issues for items on our roadmap.
|
about: View our Roadmap. Please do not open issues for items on our roadmap.
|
||||||
url: https://roadmap.modrinth.com
|
url: https://roadmap.modrinth.com
|
||||||
- name: Discussions (Feature requests)
|
- name: 📚 Documentation
|
||||||
about: |
|
about: Useful documentation about Modrinth's API
|
||||||
Please use Issues for reporting bugs and suggesting enhancements to existing features.
|
url: https://docs.modrinth.com
|
||||||
Suggestions for new features should be made as a Discussion.
|
|
||||||
url: https://github.com/orgs/modrinth/discussions/categories/feature-requests
|
|
||||||
- name: Documentation
|
|
||||||
about: Useful documentation about Modrinth, its API, and how you can contribute.
|
|
||||||
url: https://docs.modrinth.com
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 417 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
@@ -0,0 +1,43 @@
|
|||||||
|
name: daedalus-docker-build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
paths:
|
||||||
|
- .github/workflows/daedalus-docker.yml
|
||||||
|
- 'apps/daedalus_client/**'
|
||||||
|
pull_request:
|
||||||
|
types: [ opened, synchronize ]
|
||||||
|
paths:
|
||||||
|
- .github/workflows/daedalus-docker.yml
|
||||||
|
- 'apps/daedalus_client/**'
|
||||||
|
merge_group:
|
||||||
|
types: [ checks_requested ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Fetch docker metadata
|
||||||
|
id: docker_meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/modrinth/daedalus
|
||||||
|
-
|
||||||
|
name: Login to GitHub Images
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
id: docker_build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
file: ./apps/daedalus_client/Dockerfile
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
name: Run Meta
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '*/5 * * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-docker:
|
||||||
|
if: github.repository_owner == 'modrinth'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|
||||||
|
- name: Pull Docker image from GHCR
|
||||||
|
run: docker pull ghcr.io/modrinth/daedalus:main
|
||||||
|
|
||||||
|
- name: Run Docker container
|
||||||
|
env:
|
||||||
|
BASE_URL: ${{ secrets.BASE_URL }}
|
||||||
|
S3_ACCESS_TOKEN: ${{ secrets.S3_ACCESS_TOKEN }}
|
||||||
|
S3_SECRET: ${{ secrets.S3_SECRET }}
|
||||||
|
S3_URL: ${{ secrets.S3_URL }}
|
||||||
|
S3_REGION: ${{ secrets.S3_REGION }}
|
||||||
|
S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }}
|
||||||
|
CLOUDFLARE_INTEGRATION: ${{ secrets.CLOUDFLARE_INTEGRATION }}
|
||||||
|
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
|
||||||
|
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
|
||||||
|
run: |
|
||||||
|
docker run \
|
||||||
|
--name daedalus \
|
||||||
|
-e RUST_LOG=warn,daedalus_client=trace \
|
||||||
|
-e BASE_URL=$BASE_URL \
|
||||||
|
-e S3_ACCESS_TOKEN=$S3_ACCESS_TOKEN \
|
||||||
|
-e S3_SECRET=$S3_SECRET \
|
||||||
|
-e S3_URL=$S3_URL \
|
||||||
|
-e S3_REGION=$S3_REGION \
|
||||||
|
-e S3_BUCKET_NAME=$S3_BUCKET_NAME \
|
||||||
|
-e CLOUDFLARE_INTEGRATION=$CLOUDFLARE_INTEGRATION \
|
||||||
|
-e CLOUDFLARE_TOKEN=$CLOUDFLARE_TOKEN \
|
||||||
|
-e CLOUDFLARE_ZONE_ID=$CLOUDFLARE_ZONE_ID \
|
||||||
|
ghcr.io/modrinth/daedalus:main
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
name: Clear pages cache
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- prod
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
wait:
|
||||||
|
if: github.repository_owner == 'modrinth'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
deployments: write
|
||||||
|
steps:
|
||||||
|
- name: Cloudflare Pages deployment
|
||||||
|
uses: WalshyDev/cf-pages-await@v1
|
||||||
|
with:
|
||||||
|
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||||
|
accountId: '9ddae624c98677d68d93df6e524a6061'
|
||||||
|
project: 'frontend'
|
||||||
|
commitHash: ${{ steps.push-changes.outputs.commit-hash }}
|
||||||
|
- name: Purge cache
|
||||||
|
if: github.ref == 'refs/heads/prod'
|
||||||
|
run: |
|
||||||
|
curl -X POST \
|
||||||
|
-H "Authorization: Bearer ${{ secrets.CF_API_TOKEN }}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{"hosts": ["modrinth.com", "www.modrinth.com"]}' \
|
||||||
|
https://api.cloudflare.com/client/v4/zones/e39df17b9c4ef44cbce2646346ee6d33/purge_cache
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
name: GUI Build + Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
pull_request:
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ./theseus_gui
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 18.x
|
|
||||||
- name: Install pnpm via corepack
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
corepack prepare --activate
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
id: pnpm-cache
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
||||||
- name: Setup pnpm cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install
|
|
||||||
- name: Run Lint
|
|
||||||
run: pnpm lint
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
name: docker-build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
paths:
|
||||||
|
- .github/workflows/labrinth-docker.yml
|
||||||
|
- 'apps/labrinth/**'
|
||||||
|
pull_request:
|
||||||
|
types: [ opened, synchronize ]
|
||||||
|
paths:
|
||||||
|
- .github/workflows/labrinth-docker.yml
|
||||||
|
- 'apps/labrinth/**'
|
||||||
|
merge_group:
|
||||||
|
types: [ checks_requested ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./apps/labrinth
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Fetch docker metadata
|
||||||
|
id: docker_meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/modrinth/labrinth
|
||||||
|
-
|
||||||
|
name: Login to GitHub Images
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
id: docker_build
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./apps/labrinth
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
name: 'Tauri GUI Build'
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
jobs:
|
|
||||||
test-tauri:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ./theseus_gui
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Rust setup (mac)
|
|
||||||
if: startsWith(matrix.platform, 'macos')
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
components: rustfmt, clippy
|
|
||||||
targets: aarch64-apple-darwin
|
|
||||||
|
|
||||||
- name: Rust setup
|
|
||||||
if: "!startsWith(matrix.platform, 'macos')"
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
components: rustfmt, clippy
|
|
||||||
|
|
||||||
- name: Rust cache
|
|
||||||
uses: swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: './src-tauri -> target'
|
|
||||||
|
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 18.x
|
|
||||||
- name: Install pnpm via corepack
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
corepack prepare --activate
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
id: pnpm-cache
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
||||||
- name: Setup pnpm cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
|
|
||||||
- name: install dependencies (ubuntu only)
|
|
||||||
if: startsWith(matrix.platform, 'ubuntu')
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libselinux1
|
|
||||||
|
|
||||||
- name: Install frontend dependencies
|
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: build app (macos)
|
|
||||||
uses: tauri-apps/tauri-action@v0
|
|
||||||
id: build_os_mac
|
|
||||||
if: startsWith(matrix.platform, 'macos')
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
|
||||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
|
||||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
||||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
||||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
|
||||||
with:
|
|
||||||
args: --target universal-apple-darwin
|
|
||||||
|
|
||||||
- name: build app
|
|
||||||
uses: tauri-apps/tauri-action@v0
|
|
||||||
id: build_os
|
|
||||||
if: "!startsWith(matrix.platform, 'macos')"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
|
||||||
|
|
||||||
- name: upload ${{ matrix.platform }}
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
if: startsWith(matrix.platform, 'macos')
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.platform }}
|
|
||||||
path: "${{ join(fromJSON(steps.build_os_mac.outputs.artifactPaths), '\n') }}"
|
|
||||||
|
|
||||||
- name: upload ${{ matrix.platform }}
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
if: "!startsWith(matrix.platform, 'macos')"
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.platform }}
|
|
||||||
path: "${{ join(fromJSON(steps.build_os.outputs.artifactPaths), '\n') }}"
|
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
name: 'Modrinth App build'
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
paths:
|
||||||
|
- .github/workflows/app-release.yml
|
||||||
|
- 'apps/app/**'
|
||||||
|
- 'apps/app-frontend/**'
|
||||||
|
- 'packages/app-lib/**'
|
||||||
|
- 'packages/app-macros/**'
|
||||||
|
- 'packages/assets/**'
|
||||||
|
- 'packages/ui/**'
|
||||||
|
- 'packages/utils/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform: [macos-latest, windows-latest, ubuntu-22.04]
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Rust setup (mac)
|
||||||
|
if: startsWith(matrix.platform, 'macos')
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: rustfmt, clippy
|
||||||
|
targets: aarch64-apple-darwin, x86_64-apple-darwin
|
||||||
|
|
||||||
|
- name: Rust setup
|
||||||
|
if: "!startsWith(matrix.platform, 'macos')"
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Setup rust cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
target/**
|
||||||
|
!target/*/release/bundle/*/*.dmg
|
||||||
|
!target/*/release/bundle/*/*.app.tar.gz
|
||||||
|
!target/*/release/bundle/*/*.app.tar.gz.sig
|
||||||
|
!target/release/bundle/*/*.dmg
|
||||||
|
!target/release/bundle/*/*.app.tar.gz
|
||||||
|
!target/release/bundle/*/*.app.tar.gz.sig
|
||||||
|
|
||||||
|
!target/release/bundle/*/*.AppImage
|
||||||
|
!target/release/bundle/*/*.AppImage.tar.gz
|
||||||
|
!target/release/bundle/*/*.AppImage.tar.gz.sig
|
||||||
|
!target/release/bundle/*/*.deb
|
||||||
|
!target/release/bundle/*/*.rpm
|
||||||
|
|
||||||
|
!target/release/bundle/msi/*.msi
|
||||||
|
!target/release/bundle/msi/*.msi.zip
|
||||||
|
!target/release/bundle/msi/*.msi.zip.sig
|
||||||
|
|
||||||
|
!target/release/bundle/nsis/*.exe
|
||||||
|
!target/release/bundle/nsis/*.nsis.zip
|
||||||
|
!target/release/bundle/nsis/*.nsis.zip.sig
|
||||||
|
key: ${{ runner.os }}-rust-target-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-rust-target-
|
||||||
|
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Install pnpm via corepack
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
corepack prepare --activate
|
||||||
|
|
||||||
|
- name: Get pnpm store directory
|
||||||
|
id: pnpm-cache
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Setup pnpm cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||||
|
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pnpm-store-
|
||||||
|
|
||||||
|
- name: install dependencies (ubuntu only)
|
||||||
|
if: startsWith(matrix.platform, 'ubuntu')
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev pkg-config libayatana-appindicator3-dev librsvg2-dev
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: build app (macos)
|
||||||
|
run: pnpm --filter=@modrinth/app run tauri build --target universal-apple-darwin --config "tauri-release.conf.json"
|
||||||
|
if: startsWith(matrix.platform, 'macos')
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||||
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||||
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: build app
|
||||||
|
run: pnpm --filter=@modrinth/app run tauri build --config "tauri-release.conf.json"
|
||||||
|
id: build_os
|
||||||
|
if: "!startsWith(matrix.platform, 'macos')"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: upload ${{ matrix.platform }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}
|
||||||
|
path: |
|
||||||
|
target/*/release/bundle/*/*.dmg
|
||||||
|
target/*/release/bundle/*/*.app.tar.gz
|
||||||
|
target/*/release/bundle/*/*.app.tar.gz.sig
|
||||||
|
target/release/bundle/*/*.dmg
|
||||||
|
target/release/bundle/*/*.app.tar.gz
|
||||||
|
target/release/bundle/*/*.app.tar.gz.sig
|
||||||
|
|
||||||
|
target/release/bundle/*/*.AppImage
|
||||||
|
target/release/bundle/*/*.AppImage.tar.gz
|
||||||
|
target/release/bundle/*/*.AppImage.tar.gz.sig
|
||||||
|
target/release/bundle/*/*.deb
|
||||||
|
target/release/bundle/*/*.rpm
|
||||||
|
|
||||||
|
target/release/bundle/msi/*.msi
|
||||||
|
target/release/bundle/msi/*.msi.zip
|
||||||
|
target/release/bundle/msi/*.msi.zip.sig
|
||||||
|
|
||||||
|
target/release/bundle/nsis/*.exe
|
||||||
|
target/release/bundle/nsis/*.nsis.zip
|
||||||
|
target/release/bundle/nsis/*.nsis.zip.sig
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize]
|
||||||
|
merge_group:
|
||||||
|
types: [ checks_requested ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build, Test, and Lint
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
|
||||||
|
- name: Cache turbo build setup
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: .turbo
|
||||||
|
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-turbo-
|
||||||
|
|
||||||
|
- name: Install build dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
||||||
|
|
||||||
|
- name: Setup Node.JS environment
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Install pnpm via corepack
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
corepack prepare --activate
|
||||||
|
|
||||||
|
- name: Get pnpm store directory
|
||||||
|
id: pnpm-cache
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
name: Setup pnpm cache
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||||
|
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pnpm-store-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: pnpm build
|
||||||
|
env:
|
||||||
|
SQLX_OFFLINE: true
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: pnpm lint
|
||||||
|
env:
|
||||||
|
SQLX_OFFLINE: true
|
||||||
|
|
||||||
|
- name: Start docker compose
|
||||||
|
run: docker compose up -d
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: pnpm test
|
||||||
|
env:
|
||||||
|
SQLX_OFFLINE: true
|
||||||
|
DATABASE_URL: postgresql://labrinth:labrinth@localhost/postgres
|
||||||
+53
-105
@@ -1,115 +1,63 @@
|
|||||||
/target
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
node_modules/
|
|
||||||
.svelte-kit/
|
|
||||||
theseus_gui/build/
|
|
||||||
theseus_gui/generated/
|
|
||||||
WixTools
|
|
||||||
.direnv/
|
|
||||||
.DS_Store
|
|
||||||
.pnpm-debug.log
|
|
||||||
|
|
||||||
minecraft
|
# compiled output
|
||||||
config
|
dist
|
||||||
|
tmp
|
||||||
|
/out-tsc
|
||||||
|
|
||||||
[#]*[#]
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
# TEMPORARY: ignore my test instance and metadata
|
# IDEs and editors
|
||||||
theseus_cli/foo
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
### Intellij+all ###
|
# IDE - VSCode
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# AWS User-specific
|
|
||||||
.idea/**/aws.xml
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# SonarLint plugin
|
|
||||||
.idea/sonarlint/
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
### Intellij+all Patch ###
|
|
||||||
# Ignore everything but code style settings and run configurations
|
|
||||||
# that are supposed to be shared within teams.
|
|
||||||
|
|
||||||
.idea/*
|
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
!.idea/codeStyles
|
# misc
|
||||||
!.idea/runConfigurations
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# System Files
|
||||||
**/*.rs.bk
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
# Nuxt dev/build outputs
|
||||||
*.pdb
|
.output
|
||||||
|
.data
|
||||||
|
.nuxt
|
||||||
|
.nitro
|
||||||
|
.cache
|
||||||
|
|
||||||
theseus.iml
|
# frontend generated files
|
||||||
|
apps/frontend/src/generated
|
||||||
|
|
||||||
|
.turbo
|
||||||
|
target
|
||||||
|
generated
|
||||||
|
.env
|
||||||
|
|
||||||
|
# app testing dir
|
||||||
|
app-playground-data/*
|
||||||
|
|
||||||
|
# soley because i need the PORT to be 3002 due to WSL stuff
|
||||||
|
.env
|
||||||
|
apps/frontend/.env
|
||||||
|
|
||||||
|
.astro
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
Generated
+15
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/daedalus_client_new/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/apps/daedalus_client/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/packages/daedalus/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="PROJECT_FILES" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+26
@@ -0,0 +1,26 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="KotlinJavaRuntime" type="repository">
|
||||||
|
<properties maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0" />
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0-javadoc.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0-javadoc.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0-javadoc.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-javadoc.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0-sources.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0-sources.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0-sources.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/daedalus.iml" filepath="$PROJECT_DIR$/.idea/daedalus.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["esbenp.prettier-vscode", "Vue.volar", "rust-lang.rust-analyzer"]
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"prettier.endOfLine": "lf",
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact"
|
||||||
|
],
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": "explicit"
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-7
@@ -1,13 +1,13 @@
|
|||||||
# Copying
|
# Copying Guidelines
|
||||||
|
|
||||||
The source code of the theseus repository is licensed under the GNU General Public License, Version 3 only, which is provided in the file [LICENSE](./LICENSE). However, some files listed below are licensed under a different license.
|
All packages in this repository are licensed under their respective licenses. For more information, refer to the LICENSE file in each package.
|
||||||
|
|
||||||
## Modrinth logo
|
For detailed information, consult each package's COPYING.md file, if available.
|
||||||
|
|
||||||
Any files depicting the Modrinth branding, including the wrench-in-labyrinth logo, the landing image, and variations thereof, are licensed as follows:
|
## Modrinth Branding
|
||||||
|
|
||||||
> All rights reserved. © 2020-2023 Rinth, Inc.
|
The use of Modrinth branding elements, including but not limited to the wrench-in-labyrinth logo, the landing image, and any variations thereof, is strictly prohibited without explicit written permission from Rinth, Inc. This includes trademarks, logos, or other branding elements.
|
||||||
|
|
||||||
This includes, but may not be limited to, the following files:
|
All rights reserved. © 2020-2024 Rinth, Inc.
|
||||||
|
|
||||||
- theseus_gui/src-tauri/icons/*
|
If you fork this repository, you must remove all Modrinth branding assets from your fork.
|
||||||
Generated
+6009
-1584
File diff suppressed because it is too large.
Load diff
+13
-16
@@ -1,23 +1,14 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
|
resolver = '2'
|
||||||
members = [
|
members = [
|
||||||
"theseus",
|
'./packages/app-lib',
|
||||||
"theseus_playground",
|
'./apps/app-playground',
|
||||||
"theseus_gui/src-tauri",
|
'./apps/app',
|
||||||
"theseus_macros"
|
'./apps/labrinth',
|
||||||
|
'./apps/daedalus_client',
|
||||||
|
'./packages/daedalus',
|
||||||
]
|
]
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
opt-level = 0
|
|
||||||
debug = true
|
|
||||||
debug-assertions = true
|
|
||||||
overflow-checks = true
|
|
||||||
lto = false
|
|
||||||
panic = 'unwind'
|
|
||||||
incremental = true
|
|
||||||
codegen-units = 256
|
|
||||||
rpath = false
|
|
||||||
|
|
||||||
# Optimize for speed and reduce size on release builds
|
# Optimize for speed and reduce size on release builds
|
||||||
[profile.release]
|
[profile.release]
|
||||||
panic = "abort" # Strip expensive panic clean-up logic
|
panic = "abort" # Strip expensive panic clean-up logic
|
||||||
@@ -25,3 +16,9 @@ codegen-units = 1 # Compile crates one after another so the compiler can optimiz
|
|||||||
lto = true # Enables link to optimizations
|
lto = true # Enables link to optimizations
|
||||||
opt-level = "s" # Optimize for binary size
|
opt-level = "s" # Optimize for binary size
|
||||||
strip = true # Remove debug symbols
|
strip = true # Remove debug symbols
|
||||||
|
|
||||||
|
[profile.dev.package.sqlx-macros]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
wry = { git = "https://github.com/modrinth/wry", rev = "27fb16b" }
|
||||||
@@ -1,9 +1,39 @@
|
|||||||
# theseus
|
# 
|
||||||
A game launcher which can be used as a CLI, GUI, and a library for creating and playing modrinth projects
|
|
||||||
|
|
||||||
Theseus aims to provide three components:
|

|
||||||
- A library (theseus)
|

|
||||||
- A CLI (theseus-cli)
|

|
||||||
- A GUI (theseus-gui)
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
Feel free to contribute!
|
## Modrinth Monorepo
|
||||||
|
|
||||||
|
Welcome to the Modrinth Monorepo, the primary codebase for the Modrinth web interface and app. It contains  lines of code and has  contributors!
|
||||||
|
|
||||||
|
If you're not a developer and you've stumbled upon this repository, you can access the web interface on the [Modrinth website](https://modrinth.com) and download the latest release of the app [here](https://modrinth.com/app).
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
This repository contains two primary packages. For detailed development information, please refer to their respective READMEs:
|
||||||
|
|
||||||
|
- [Web Interface](apps/frontend/README.md)
|
||||||
|
- [Desktop App](apps/app/README.md)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
We welcome contributions! Before submitting any contributions, please read our [contributing guidelines](https://docs.modrinth.com/contributing/getting-started/).
|
||||||
|
|
||||||
|
If you plan to fork this repository for your own purposes, please review our [copying guidelines](COPYING.md).
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
If you discover a security vulnerability within our codebase, please follow our [responsible disclosure guidelines](https://modrinth.com/legal/security).
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you need help with the Modrinth web interface or app, please visit our [support page](https://support.modrinth.com). For general inquiries, you can also join our [Discord server](https://discord.modrinth.com).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
All packages in this repository are licensed under their respective licenses. Refer to the LICENSE file in each package for more information.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
**/dist
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Copying
|
||||||
|
|
||||||
|
The source code of the theseus repository is licensed under the GNU General Public License, Version 3 only, which is provided in the file [LICENSE](./LICENSE). However, some files listed below are licensed under a different license.
|
||||||
|
|
||||||
|
## Modrinth logo
|
||||||
|
|
||||||
|
The use of Modrinth branding elements, including but not limited to the wrench-in-labyrinth logo, the landing image, and any variations thereof, is strictly prohibited without explicit written permission from Rinth, Inc. This includes trademarks, logos, or other branding elements.
|
||||||
|
|
||||||
|
> All rights reserved. © 2020-2023 Rinth, Inc.
|
||||||
|
|
||||||
|
This includes, but may not be limited to, the following files:
|
||||||
|
|
||||||
|
- theseus_gui/src-tauri/icons/\*
|
||||||
File renamed without changes.
@@ -0,0 +1,22 @@
|
|||||||
|
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
|
||||||
|
import { fixupPluginRules } from '@eslint/compat'
|
||||||
|
import turboPlugin from 'eslint-plugin-turbo'
|
||||||
|
|
||||||
|
export default createConfigForNuxt().append([
|
||||||
|
{
|
||||||
|
name: 'turbo',
|
||||||
|
plugins: {
|
||||||
|
turbo: fixupPluginRules(turboPlugin),
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'turbo/no-undeclared-env-vars': 'error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'modrinth',
|
||||||
|
rules: {
|
||||||
|
'vue/html-self-closing': 'off',
|
||||||
|
'vue/multi-word-component-names': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en" class="dark-mode">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Modrinth App</title>
|
<title>Modrinth App</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"name": "@modrinth/app-frontend",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.8.9",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
|
"tsc:check": "vue-tsc --noEmit",
|
||||||
|
"lint": "eslint . && prettier --check .",
|
||||||
|
"fix": "eslint . --fix && prettier --write ."
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@modrinth/assets": "workspace:*",
|
||||||
|
"@modrinth/ui": "workspace:*",
|
||||||
|
"@modrinth/utils": "workspace:*",
|
||||||
|
"@sentry/vue": "^8.27.0",
|
||||||
|
"@tauri-apps/api": "^2.0.0-rc.3",
|
||||||
|
"@tauri-apps/plugin-dialog": "^2.0.0-rc.0",
|
||||||
|
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
||||||
|
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
||||||
|
"@tauri-apps/plugin-updater": "^2.0.0-rc.0",
|
||||||
|
"@tauri-apps/plugin-window-state": "^2.0.0-rc.0",
|
||||||
|
"@vintl/vintl": "^4.4.1",
|
||||||
|
"dayjs": "^1.11.10",
|
||||||
|
"floating-vue": "^5.2.2",
|
||||||
|
"ofetch": "^1.3.4",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
|
"posthog-js": "^1.158.2",
|
||||||
|
"vite-svg-loader": "^5.1.0",
|
||||||
|
"vue": "^3.4.21",
|
||||||
|
"vue-multiselect": "3.0.0",
|
||||||
|
"vue-router": "4.3.0",
|
||||||
|
"vue-virtual-scroller": "v2.0.0-beta.8"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/compat": "^1.1.1",
|
||||||
|
"@nuxt/eslint-config": "^0.5.6",
|
||||||
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
|
"autoprefixer": "^10.4.19",
|
||||||
|
"eslint": "^9.9.1",
|
||||||
|
"eslint-config-custom": "workspace:*",
|
||||||
|
"eslint-plugin-turbo": "^2.1.1",
|
||||||
|
"postcss": "^8.4.39",
|
||||||
|
"prettier": "^3.2.5",
|
||||||
|
"sass": "^1.74.1",
|
||||||
|
"tailwindcss": "^3.4.4",
|
||||||
|
"tsconfig": "workspace:*",
|
||||||
|
"typescript": "^5.5.4",
|
||||||
|
"vite": "^5.2.8",
|
||||||
|
"vue-tsc": "^2.1.6"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@9.4.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, onMounted } from 'vue'
|
||||||
import { RouterView, RouterLink, useRouter, useRoute } from 'vue-router'
|
import { RouterView, RouterLink, useRouter, useRoute } from 'vue-router'
|
||||||
import {
|
import {
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
@@ -7,12 +7,10 @@ import {
|
|||||||
LibraryIcon,
|
LibraryIcon,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
FileIcon,
|
|
||||||
Button,
|
|
||||||
Notifications,
|
|
||||||
XIcon,
|
XIcon,
|
||||||
Card,
|
DownloadIcon,
|
||||||
} from 'omorphia'
|
} from '@modrinth/assets'
|
||||||
|
import { Button, Notifications } from '@modrinth/ui'
|
||||||
import { useLoading, useTheming } from '@/store/state'
|
import { useLoading, useTheming } from '@/store/state'
|
||||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||||
@@ -23,173 +21,171 @@ import SplashScreen from '@/components/ui/SplashScreen.vue'
|
|||||||
import ErrorModal from '@/components/ui/ErrorModal.vue'
|
import ErrorModal from '@/components/ui/ErrorModal.vue'
|
||||||
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator'
|
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator'
|
||||||
import { handleError, useNotifications } from '@/store/notifications.js'
|
import { handleError, useNotifications } from '@/store/notifications.js'
|
||||||
import { offline_listener, command_listener, warning_listener } from '@/helpers/events.js'
|
import { command_listener, warning_listener } from '@/helpers/events.js'
|
||||||
import { MinimizeIcon, MaximizeIcon, ChatIcon } from '@/assets/icons'
|
import { MinimizeIcon, MaximizeIcon } from '@/assets/icons'
|
||||||
import { type } from '@tauri-apps/api/os'
|
import { type } from '@tauri-apps/plugin-os'
|
||||||
import { appWindow } from '@tauri-apps/api/window'
|
import { isDev, getOS, restartApp } from '@/helpers/utils.js'
|
||||||
import { isDev, getOS, isOffline, showLauncherLogsFolder } from '@/helpers/utils.js'
|
import { initAnalytics, debugAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
||||||
import {
|
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||||
mixpanel_track,
|
|
||||||
mixpanel_init,
|
|
||||||
mixpanel_opt_out_tracking,
|
|
||||||
mixpanel_is_loaded,
|
|
||||||
} from '@/helpers/mixpanel'
|
|
||||||
import { saveWindowState, StateFlags } from 'tauri-plugin-window-state-api'
|
|
||||||
import { getVersion } from '@tauri-apps/api/app'
|
import { getVersion } from '@tauri-apps/api/app'
|
||||||
import { window as TauriWindow } from '@tauri-apps/api'
|
|
||||||
import { TauriEvent } from '@tauri-apps/api/event'
|
|
||||||
import { await_sync, check_safe_loading_bars_complete } from './helpers/state'
|
|
||||||
import { confirm } from '@tauri-apps/api/dialog'
|
|
||||||
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
||||||
import OnboardingScreen from '@/components/ui/tutorial/OnboardingScreen.vue'
|
|
||||||
import { install_from_file } from './helpers/pack'
|
import { install_from_file } from './helpers/pack'
|
||||||
import { useError } from '@/store/error.js'
|
import { useError } from '@/store/error.js'
|
||||||
|
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||||
|
import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue'
|
||||||
|
import IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue'
|
||||||
|
import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue'
|
||||||
|
import { useInstall } from '@/store/install.js'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import { open } from '@tauri-apps/plugin-shell'
|
||||||
|
import { get_opening_command, initialize_state } from '@/helpers/state'
|
||||||
|
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||||
|
import { renderString } from '@modrinth/utils'
|
||||||
|
import { useFetch } from '@/helpers/fetch.js'
|
||||||
|
import { check } from '@tauri-apps/plugin-updater'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
const themeStore = useTheming()
|
||||||
const urlModal = ref(null)
|
|
||||||
const isLoading = ref(true)
|
|
||||||
|
|
||||||
const offline = ref(false)
|
const urlModal = ref(null)
|
||||||
|
|
||||||
|
const offline = ref(!navigator.onLine)
|
||||||
|
window.addEventListener('offline', () => {
|
||||||
|
offline.value = true
|
||||||
|
})
|
||||||
|
window.addEventListener('online', () => {
|
||||||
|
offline.value = false
|
||||||
|
})
|
||||||
|
|
||||||
const showOnboarding = ref(false)
|
const showOnboarding = ref(false)
|
||||||
const nativeDecorations = ref(false)
|
const nativeDecorations = ref(false)
|
||||||
|
|
||||||
const onboardingVideo = ref()
|
|
||||||
|
|
||||||
const failureText = ref(null)
|
|
||||||
const os = ref('')
|
const os = ref('')
|
||||||
|
|
||||||
defineExpose({
|
const stateInitialized = ref(false)
|
||||||
initialize: async () => {
|
|
||||||
isLoading.value = false
|
|
||||||
const {
|
|
||||||
native_decorations,
|
|
||||||
theme,
|
|
||||||
opt_out_analytics,
|
|
||||||
collapsed_navigation,
|
|
||||||
advanced_rendering,
|
|
||||||
fully_onboarded,
|
|
||||||
} = await get()
|
|
||||||
// video should play if the user is not on linux, and has not onboarded
|
|
||||||
os.value = await getOS()
|
|
||||||
const dev = await isDev()
|
|
||||||
const version = await getVersion()
|
|
||||||
showOnboarding.value = !fully_onboarded
|
|
||||||
|
|
||||||
nativeDecorations.value = native_decorations
|
const criticalErrorMessage = ref()
|
||||||
if (os.value !== 'MacOS') appWindow.setDecorations(native_decorations)
|
|
||||||
|
|
||||||
themeStore.setThemeState(theme)
|
onMounted(async () => {
|
||||||
themeStore.collapsedNavigation = collapsed_navigation
|
await useCheckDisableMouseover()
|
||||||
themeStore.advancedRendering = advanced_rendering
|
|
||||||
|
|
||||||
mixpanel_init('014c7d6a336d0efaefe3aca91063748d', { debug: dev, persistence: 'localStorage' })
|
|
||||||
if (opt_out_analytics) {
|
|
||||||
mixpanel_opt_out_tracking()
|
|
||||||
}
|
|
||||||
mixpanel_track('Launched', { version, dev, fully_onboarded })
|
|
||||||
|
|
||||||
if (!dev) document.addEventListener('contextmenu', (event) => event.preventDefault())
|
|
||||||
|
|
||||||
if ((await type()) === 'Darwin') {
|
|
||||||
document.getElementsByTagName('html')[0].classList.add('mac')
|
|
||||||
} else {
|
|
||||||
document.getElementsByTagName('html')[0].classList.add('windows')
|
|
||||||
}
|
|
||||||
|
|
||||||
offline.value = await isOffline()
|
|
||||||
await offline_listener((b) => {
|
|
||||||
offline.value = b
|
|
||||||
})
|
|
||||||
|
|
||||||
await warning_listener((e) =>
|
|
||||||
notificationsWrapper.value.addNotification({
|
|
||||||
title: 'Warning',
|
|
||||||
text: e.message,
|
|
||||||
type: 'warn',
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
if (showOnboarding.value) {
|
|
||||||
onboardingVideo.value.play()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
failure: async (e) => {
|
|
||||||
isLoading.value = false
|
|
||||||
failureText.value = e
|
|
||||||
os.value = await getOS()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const confirmClose = async () => {
|
async function setupApp() {
|
||||||
const confirmed = await confirm(
|
stateInitialized.value = true
|
||||||
'An action is currently in progress. Are you sure you want to exit?',
|
const {
|
||||||
{
|
native_decorations,
|
||||||
title: 'Modrinth',
|
theme,
|
||||||
type: 'warning',
|
telemetry,
|
||||||
},
|
collapsed_navigation,
|
||||||
|
advanced_rendering,
|
||||||
|
onboarded,
|
||||||
|
default_page,
|
||||||
|
} = await get()
|
||||||
|
|
||||||
|
if (default_page && default_page !== 'Home') {
|
||||||
|
await router.push({ name: default_page })
|
||||||
|
}
|
||||||
|
|
||||||
|
os.value = await getOS()
|
||||||
|
const dev = await isDev()
|
||||||
|
const version = await getVersion()
|
||||||
|
showOnboarding.value = !onboarded
|
||||||
|
|
||||||
|
nativeDecorations.value = native_decorations
|
||||||
|
if (os.value !== 'MacOS') await getCurrentWindow().setDecorations(native_decorations)
|
||||||
|
|
||||||
|
themeStore.setThemeState(theme)
|
||||||
|
themeStore.collapsedNavigation = collapsed_navigation
|
||||||
|
themeStore.advancedRendering = advanced_rendering
|
||||||
|
|
||||||
|
initAnalytics()
|
||||||
|
if (!telemetry) {
|
||||||
|
optOutAnalytics()
|
||||||
|
}
|
||||||
|
if (dev) debugAnalytics()
|
||||||
|
trackEvent('Launched', { version, dev, onboarded })
|
||||||
|
|
||||||
|
if (!dev) document.addEventListener('contextmenu', (event) => event.preventDefault())
|
||||||
|
|
||||||
|
const osType = await type()
|
||||||
|
if (osType === 'macos') {
|
||||||
|
document.getElementsByTagName('html')[0].classList.add('mac')
|
||||||
|
} else {
|
||||||
|
document.getElementsByTagName('html')[0].classList.add('windows')
|
||||||
|
}
|
||||||
|
|
||||||
|
await warning_listener((e) =>
|
||||||
|
notificationsWrapper.value.addNotification({
|
||||||
|
title: 'Warning',
|
||||||
|
text: e.message,
|
||||||
|
type: 'warn',
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
return confirmed
|
|
||||||
|
useFetch(
|
||||||
|
`https://api.modrinth.com/appCriticalAnnouncement.json?version=${version}`,
|
||||||
|
'criticalAnnouncements',
|
||||||
|
true,
|
||||||
|
).then((res) => {
|
||||||
|
if (res && res.header && res.body) {
|
||||||
|
criticalErrorMessage.value = res
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
get_opening_command().then(handleCommand)
|
||||||
|
checkUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stateFailed = ref(false)
|
||||||
|
initialize_state()
|
||||||
|
.then(() => {
|
||||||
|
setupApp().catch((err) => {
|
||||||
|
stateFailed.value = true
|
||||||
|
console.error(err)
|
||||||
|
error.showError(err, null, false, 'state_init')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
stateFailed.value = true
|
||||||
|
console.error('Failed to initialize app', err)
|
||||||
|
error.showError(err, null, false, 'state_init')
|
||||||
|
})
|
||||||
|
|
||||||
const handleClose = async () => {
|
const handleClose = async () => {
|
||||||
if (failureText.value != null) {
|
await saveWindowState(StateFlags.ALL)
|
||||||
await TauriWindow.getCurrent().close()
|
await getCurrentWindow().close()
|
||||||
return
|
|
||||||
}
|
|
||||||
// State should respond immeiately if it's safe to close
|
|
||||||
// If not, code is deadlocked or worse, so wait 2 seconds and then ask the user to confirm closing
|
|
||||||
// (Exception: if the user is changing config directory, which takes control of the state, and it's taking a significant amount of time for some reason)
|
|
||||||
const isSafe = await Promise.race([
|
|
||||||
check_safe_loading_bars_complete(),
|
|
||||||
new Promise((r) => setTimeout(r, 2000)),
|
|
||||||
])
|
|
||||||
if (!isSafe) {
|
|
||||||
const response = await confirmClose()
|
|
||||||
if (!response) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await await_sync()
|
|
||||||
await TauriWindow.getCurrent().close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const openSupport = async () => {
|
|
||||||
window.__TAURI_INVOKE__('tauri', {
|
|
||||||
__tauriModule: 'Shell',
|
|
||||||
message: {
|
|
||||||
cmd: 'open',
|
|
||||||
path: 'https://discord.gg/modrinth',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
TauriWindow.getCurrent().listen(TauriEvent.WINDOW_CLOSE_REQUESTED, async () => {
|
|
||||||
await handleClose()
|
|
||||||
})
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
router.afterEach((to, from, failure) => {
|
router.afterEach((to, from, failure) => {
|
||||||
if (mixpanel_is_loaded()) {
|
trackEvent('PageView', { path: to.path, fromPath: from.path, failed: failure })
|
||||||
mixpanel_track('PageView', { path: to.path, fromPath: from.path, failed: failure })
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const isOnBrowse = computed(() => route.path.startsWith('/browse'))
|
const isOnBrowse = computed(() => route.path.startsWith('/browse'))
|
||||||
|
|
||||||
const loading = useLoading()
|
const loading = useLoading()
|
||||||
|
loading.setEnabled(false)
|
||||||
|
|
||||||
const notifications = useNotifications()
|
const notifications = useNotifications()
|
||||||
const notificationsWrapper = ref()
|
const notificationsWrapper = ref()
|
||||||
|
|
||||||
watch(notificationsWrapper, () => {
|
|
||||||
notifications.setNotifs(notificationsWrapper.value)
|
|
||||||
})
|
|
||||||
|
|
||||||
const error = useError()
|
const error = useError()
|
||||||
const errorModal = ref()
|
const errorModal = ref()
|
||||||
|
|
||||||
watch(errorModal, () => {
|
const install = useInstall()
|
||||||
|
const modInstallModal = ref()
|
||||||
|
const installConfirmModal = ref()
|
||||||
|
const incompatibilityWarningModal = ref()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
invoke('show_window')
|
||||||
|
|
||||||
|
notifications.setNotifs(notificationsWrapper.value)
|
||||||
|
|
||||||
error.setErrorModal(errorModal.value)
|
error.setErrorModal(errorModal.value)
|
||||||
|
|
||||||
|
install.setIncompatibilityWarningModal(incompatibilityWarningModal)
|
||||||
|
install.setInstallConfirmModal(installConfirmModal)
|
||||||
|
install.setModInstallModal(modInstallModal)
|
||||||
})
|
})
|
||||||
|
|
||||||
document.querySelector('body').addEventListener('click', function (e) {
|
document.querySelector('body').addEventListener('click', function (e) {
|
||||||
@@ -201,15 +197,10 @@ document.querySelector('body').addEventListener('click', function (e) {
|
|||||||
['http://', 'https://', 'mailto:', 'tel:'].some((v) => target.href.startsWith(v)) &&
|
['http://', 'https://', 'mailto:', 'tel:'].some((v) => target.href.startsWith(v)) &&
|
||||||
!target.classList.contains('router-link-active') &&
|
!target.classList.contains('router-link-active') &&
|
||||||
!target.href.startsWith('http://localhost') &&
|
!target.href.startsWith('http://localhost') &&
|
||||||
!target.href.startsWith('https://tauri.localhost')
|
!target.href.startsWith('https://tauri.localhost') &&
|
||||||
|
!target.href.startsWith('http://tauri.localhost')
|
||||||
) {
|
) {
|
||||||
window.__TAURI_INVOKE__('tauri', {
|
open(target.href)
|
||||||
__tauriModule: 'Shell',
|
|
||||||
message: {
|
|
||||||
cmd: 'open',
|
|
||||||
path: target.href,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
break
|
break
|
||||||
@@ -234,12 +225,15 @@ document.querySelector('body').addEventListener('auxclick', function (e) {
|
|||||||
|
|
||||||
const accounts = ref(null)
|
const accounts = ref(null)
|
||||||
|
|
||||||
command_listener(async (e) => {
|
command_listener(handleCommand)
|
||||||
|
async function handleCommand(e) {
|
||||||
|
if (!e) return
|
||||||
|
|
||||||
if (e.event === 'RunMRPack') {
|
if (e.event === 'RunMRPack') {
|
||||||
// RunMRPack should directly install a local mrpack given a path
|
// RunMRPack should directly install a local mrpack given a path
|
||||||
if (e.path.endsWith('.mrpack')) {
|
if (e.path.endsWith('.mrpack')) {
|
||||||
await install_from_file(e.path).catch(handleError)
|
await install_from_file(e.path).catch(handleError)
|
||||||
mixpanel_track('InstanceCreate', {
|
trackEvent('InstanceCreate', {
|
||||||
source: 'CreationModalFileDrop',
|
source: 'CreationModalFileDrop',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -247,53 +241,26 @@ command_listener(async (e) => {
|
|||||||
// Other commands are URL-based (deep linking)
|
// Other commands are URL-based (deep linking)
|
||||||
urlModal.value.show(e)
|
urlModal.value.show(e)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const updateAvailable = ref(false)
|
||||||
|
async function checkUpdates() {
|
||||||
|
const update = await check()
|
||||||
|
console.log(update)
|
||||||
|
updateAvailable.value = !!update
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
checkUpdates()
|
||||||
|
},
|
||||||
|
5 * 1000 * 60,
|
||||||
|
)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="failureText" class="failure dark-mode">
|
<SplashScreen v-if="!stateFailed" ref="splashScreen" data-tauri-drag-region />
|
||||||
<div class="appbar-failure dark-mode">
|
<div v-if="stateInitialized" class="app-container">
|
||||||
<Button v-if="os != 'MacOS'" icon-only @click="TauriWindow.getCurrent().close()">
|
|
||||||
<XIcon />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div class="error-view dark-mode">
|
|
||||||
<Card class="error-text">
|
|
||||||
<div class="label">
|
|
||||||
<h3>
|
|
||||||
<span class="label__title size-card-header">Failed to initialize</span>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="error-div">
|
|
||||||
Modrinth App failed to load correctly. This may be because of a corrupted file, or because
|
|
||||||
the app is missing crucial files.
|
|
||||||
</div>
|
|
||||||
<div class="error-div">You may be able to fix it one of the following ways:</div>
|
|
||||||
<ul class="error-div">
|
|
||||||
<li>Ennsuring you are connected to the internet, then try restarting the app.</li>
|
|
||||||
<li>Redownloading the app.</li>
|
|
||||||
</ul>
|
|
||||||
<div class="error-div">
|
|
||||||
If it still does not work, you can seek support using the link below. You should provide
|
|
||||||
the following error, as well as any recent launcher logs in the folder below.
|
|
||||||
</div>
|
|
||||||
<div class="error-div">The following error was provided:</div>
|
|
||||||
|
|
||||||
<Card class="error-message">
|
|
||||||
{{ failureText.message }}
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<div class="button-row push-right">
|
|
||||||
<Button @click="showLauncherLogsFolder"><FileIcon />Open launcher logs</Button>
|
|
||||||
|
|
||||||
<Button @click="openSupport"><ChatIcon />Get support</Button>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<SplashScreen v-else-if="isLoading" app-loading />
|
|
||||||
<OnboardingScreen v-else-if="showOnboarding" :finish="() => (showOnboarding = false)" />
|
|
||||||
<div v-else class="container">
|
|
||||||
<div class="nav-container">
|
<div class="nav-container">
|
||||||
<div class="nav-section">
|
<div class="nav-section">
|
||||||
<suspense>
|
<suspense>
|
||||||
@@ -322,6 +289,14 @@ command_listener(async (e) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings pages-list">
|
<div class="settings pages-list">
|
||||||
|
<button
|
||||||
|
v-if="updateAvailable"
|
||||||
|
v-tooltip="'Install update'"
|
||||||
|
class="btn btn-outline btn-primary icon-only collapsed-button"
|
||||||
|
@click="restartApp()"
|
||||||
|
>
|
||||||
|
<DownloadIcon />
|
||||||
|
</button>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="'Create profile'"
|
v-tooltip="'Create profile'"
|
||||||
class="sleek-primary collapsed-button"
|
class="sleek-primary collapsed-button"
|
||||||
@@ -337,6 +312,10 @@ command_listener(async (e) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="view">
|
<div class="view">
|
||||||
|
<div v-if="criticalErrorMessage" class="critical-error-banner" data-tauri-drag-region>
|
||||||
|
<h1>{{ criticalErrorMessage.header }}</h1>
|
||||||
|
<div class="markdown-body" v-html="renderString(criticalErrorMessage.body ?? '')"></div>
|
||||||
|
</div>
|
||||||
<div class="appbar-row">
|
<div class="appbar-row">
|
||||||
<div data-tauri-drag-region class="appbar">
|
<div data-tauri-drag-region class="appbar">
|
||||||
<section class="navigation-controls">
|
<section class="navigation-controls">
|
||||||
@@ -349,22 +328,17 @@ command_listener(async (e) => {
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<section v-if="!nativeDecorations" class="window-controls">
|
<section v-if="!nativeDecorations" class="window-controls">
|
||||||
<Button class="titlebar-button" icon-only @click="() => appWindow.minimize()">
|
<Button class="titlebar-button" icon-only @click="() => getCurrentWindow().minimize()">
|
||||||
<MinimizeIcon />
|
<MinimizeIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button class="titlebar-button" icon-only @click="() => appWindow.toggleMaximize()">
|
<Button
|
||||||
|
class="titlebar-button"
|
||||||
|
icon-only
|
||||||
|
@click="() => getCurrentWindow().toggleMaximize()"
|
||||||
|
>
|
||||||
<MaximizeIcon />
|
<MaximizeIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button class="titlebar-button close" icon-only @click="handleClose">
|
||||||
class="titlebar-button close"
|
|
||||||
icon-only
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
saveWindowState(StateFlags.ALL)
|
|
||||||
handleClose()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
@@ -387,6 +361,9 @@ command_listener(async (e) => {
|
|||||||
<URLConfirmModal ref="urlModal" />
|
<URLConfirmModal ref="urlModal" />
|
||||||
<Notifications ref="notificationsWrapper" />
|
<Notifications ref="notificationsWrapper" />
|
||||||
<ErrorModal ref="errorModal" />
|
<ErrorModal ref="errorModal" />
|
||||||
|
<ModInstallModal ref="modInstallModal" />
|
||||||
|
<IncompatibilityWarningModal ref="incompatibilityWarningModal" />
|
||||||
|
<InstallConfirmModal ref="installConfirmModal" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -438,7 +415,7 @@ command_listener(async (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.app-container {
|
||||||
--appbar-height: 3.25rem;
|
--appbar-height: 3.25rem;
|
||||||
--sidebar-width: 4.5rem;
|
--sidebar-width: 4.5rem;
|
||||||
|
|
||||||
@@ -451,6 +428,16 @@ command_listener(async (e) => {
|
|||||||
width: calc(100% - var(--sidebar-width));
|
width: calc(100% - var(--sidebar-width));
|
||||||
background-color: var(--color-raised-bg);
|
background-color: var(--color-raised-bg);
|
||||||
|
|
||||||
|
.critical-error-banner {
|
||||||
|
margin-top: -1.25rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: rgba(203, 34, 69, 0.1);
|
||||||
|
border-left: 2px solid var(--color-red);
|
||||||
|
border-bottom: 2px solid var(--color-red);
|
||||||
|
border-right: 2px solid var(--color-red);
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.appbar {
|
.appbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -476,53 +463,6 @@ command_listener(async (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.failure {
|
|
||||||
height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
|
|
||||||
.appbar-failure {
|
|
||||||
display: flex; /* Change to flex to align items horizontally */
|
|
||||||
justify-content: flex-end; /* Align items to the right */
|
|
||||||
height: 3.25rem;
|
|
||||||
//no select
|
|
||||||
user-select: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-view {
|
|
||||||
display: flex; /* Change to flex to align items horizontally */
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
|
|
||||||
color: var(--color-base);
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: var(--color-raised-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-text {
|
|
||||||
display: flex;
|
|
||||||
max-width: 60%;
|
|
||||||
gap: 0.25rem;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.error-div {
|
|
||||||
// spaced out
|
|
||||||
margin: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-message {
|
|
||||||
margin: 0.5rem;
|
|
||||||
background-color: var(--color-button-bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -586,55 +526,6 @@ command_listener(async (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
width: 70%;
|
|
||||||
margin: 0.4rem;
|
|
||||||
|
|
||||||
p:nth-child(1) {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
color: var(--color-base);
|
|
||||||
margin: 0.8rem 0;
|
|
||||||
font-size: 0.7rem;
|
|
||||||
line-height: 0.8125rem;
|
|
||||||
font-weight: 500;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-section {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 4.375rem;
|
|
||||||
|
|
||||||
section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-start;
|
|
||||||
text-align: left;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
margin-bottom: 0.3rem;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.25rem;
|
|
||||||
color: var(--color-contrast);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: 400;
|
|
||||||
color: var(--color-secondary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-section {
|
.nav-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -645,14 +536,6 @@ command_listener(async (e) => {
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video {
|
|
||||||
margin-top: 2.25rem;
|
|
||||||
width: 100vw;
|
|
||||||
height: calc(100vh - 2.25rem);
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-row {
|
.button-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -664,3 +547,33 @@ command_listener(async (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<style>
|
||||||
|
.mac {
|
||||||
|
.nav-container {
|
||||||
|
padding-top: calc(var(--gap-md) + 1.75rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-card,
|
||||||
|
.card-section {
|
||||||
|
top: calc(var(--gap-md) + 1.75rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.windows {
|
||||||
|
.fake-appbar {
|
||||||
|
height: 2.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-controls {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-card {
|
||||||
|
right: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-card {
|
||||||
|
right: 8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File renamed without changes.
File renamed without changes.
Vendored
File renamed without changes.
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
File renamed without changes.
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
Vendored
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
|
After Width: | Height: | Size: 937 KiB |
+9
-32
@@ -1,3 +1,7 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
font-family: var(--font-standard);
|
font-family: var(--font-standard);
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
@@ -69,44 +73,15 @@ input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mac {
|
|
||||||
.nav-container {
|
|
||||||
padding-top: calc(var(--gap-md) + 1.75rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.account-card,
|
|
||||||
.card-section {
|
|
||||||
top: calc(var(--gap-md) + 1.75rem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.windows {
|
|
||||||
.fake-appbar {
|
|
||||||
height: 2.5rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-controls {
|
|
||||||
display: flex !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-card {
|
|
||||||
right: 8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-card {
|
|
||||||
right: 8rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
scrollbar-width: auto;
|
scrollbar-width: auto;
|
||||||
scrollbar-color: var(--color-button-bg) var(--color-bg);
|
scrollbar-color: var(--color-scrollbar) var(--color-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chrome, Edge, and Safari */
|
/* Chrome, Edge, and Safari */
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
width: var(--gap-md);
|
width: var(--gap-md);
|
||||||
border: 3px solid var(--color-bg);
|
border: 3px solid var(--color-scrollbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar-track {
|
*::-webkit-scrollbar-track {
|
||||||
@@ -115,7 +90,7 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar-thumb {
|
*::-webkit-scrollbar-thumb {
|
||||||
background-color: var(--color-button-bg);
|
background-color: var(--color-scrollbar);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
border: 3px solid var(--color-bg);
|
border: 3px solid var(--color-bg);
|
||||||
}
|
}
|
||||||
@@ -135,3 +110,5 @@ img {
|
|||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@import '@modrinth/assets/omorphia.scss';
|
||||||
File renamed without changes.
+21
-26
@@ -9,19 +9,16 @@ import {
|
|||||||
TrashIcon,
|
TrashIcon,
|
||||||
StopCircleIcon,
|
StopCircleIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
Card,
|
|
||||||
DropdownSelect,
|
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
Button,
|
} from '@modrinth/assets'
|
||||||
formatCategoryHeader,
|
import { Button, Card, DropdownSelect } from '@modrinth/ui'
|
||||||
ModalConfirm,
|
import { formatCategoryHeader } from '@modrinth/utils'
|
||||||
} from 'omorphia'
|
|
||||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { duplicate, remove } from '@/helpers/profile.js'
|
import { duplicate, remove } from '@/helpers/profile.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
|
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
instances: {
|
instances: {
|
||||||
@@ -38,7 +35,6 @@ const props = defineProps({
|
|||||||
const instanceOptions = ref(null)
|
const instanceOptions = ref(null)
|
||||||
const instanceComponents = ref(null)
|
const instanceComponents = ref(null)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
const currentDeleteInstance = ref(null)
|
const currentDeleteInstance = ref(null)
|
||||||
const confirmModal = ref(null)
|
const confirmModal = ref(null)
|
||||||
|
|
||||||
@@ -130,46 +126,46 @@ const sortBy = ref('Name')
|
|||||||
|
|
||||||
const filteredResults = computed(() => {
|
const filteredResults = computed(() => {
|
||||||
let instances = props.instances.filter((instance) => {
|
let instances = props.instances.filter((instance) => {
|
||||||
return instance.metadata.name.toLowerCase().includes(search.value.toLowerCase())
|
return instance.name.toLowerCase().includes(search.value.toLowerCase())
|
||||||
})
|
})
|
||||||
|
|
||||||
if (sortBy.value === 'Name') {
|
if (sortBy.value === 'Name') {
|
||||||
instances.sort((a, b) => {
|
instances.sort((a, b) => {
|
||||||
return a.metadata.name.localeCompare(b.metadata.name)
|
return a.name.localeCompare(b.name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortBy.value === 'Game version') {
|
if (sortBy.value === 'Game version') {
|
||||||
instances.sort((a, b) => {
|
instances.sort((a, b) => {
|
||||||
return a.metadata.game_version.localeCompare(b.metadata.game_version)
|
return a.game_version.localeCompare(b.game_version)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortBy.value === 'Last played') {
|
if (sortBy.value === 'Last played') {
|
||||||
instances.sort((a, b) => {
|
instances.sort((a, b) => {
|
||||||
return dayjs(b.metadata.last_played ?? 0).diff(dayjs(a.metadata.last_played ?? 0))
|
return dayjs(b.last_played ?? 0).diff(dayjs(a.last_played ?? 0))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortBy.value === 'Date created') {
|
if (sortBy.value === 'Date created') {
|
||||||
instances.sort((a, b) => {
|
instances.sort((a, b) => {
|
||||||
return dayjs(b.metadata.date_created).diff(dayjs(a.metadata.date_created))
|
return dayjs(b.date_created).diff(dayjs(a.date_created))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortBy.value === 'Date modified') {
|
if (sortBy.value === 'Date modified') {
|
||||||
instances.sort((a, b) => {
|
instances.sort((a, b) => {
|
||||||
return dayjs(b.metadata.date_modified).diff(dayjs(a.metadata.date_modified))
|
return dayjs(b.date_modified).diff(dayjs(a.date_modified))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filters.value === 'Custom instances') {
|
if (filters.value === 'Custom instances') {
|
||||||
instances = instances.filter((instance) => {
|
instances = instances.filter((instance) => {
|
||||||
return !instance.metadata?.linked_data
|
return !instance.linked_data
|
||||||
})
|
})
|
||||||
} else if (filters.value === 'Downloaded modpacks') {
|
} else if (filters.value === 'Downloaded modpacks') {
|
||||||
instances = instances.filter((instance) => {
|
instances = instances.filter((instance) => {
|
||||||
return instance.metadata?.linked_data
|
return instance.linked_data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +173,7 @@ const filteredResults = computed(() => {
|
|||||||
|
|
||||||
if (group.value === 'Loader') {
|
if (group.value === 'Loader') {
|
||||||
instances.forEach((instance) => {
|
instances.forEach((instance) => {
|
||||||
const loader = formatCategoryHeader(instance.metadata.loader)
|
const loader = formatCategoryHeader(instance.loader)
|
||||||
if (!instanceMap.has(loader)) {
|
if (!instanceMap.has(loader)) {
|
||||||
instanceMap.set(loader, [])
|
instanceMap.set(loader, [])
|
||||||
}
|
}
|
||||||
@@ -186,19 +182,19 @@ const filteredResults = computed(() => {
|
|||||||
})
|
})
|
||||||
} else if (group.value === 'Game version') {
|
} else if (group.value === 'Game version') {
|
||||||
instances.forEach((instance) => {
|
instances.forEach((instance) => {
|
||||||
if (!instanceMap.has(instance.metadata.game_version)) {
|
if (!instanceMap.has(instance.game_version)) {
|
||||||
instanceMap.set(instance.metadata.game_version, [])
|
instanceMap.set(instance.game_version, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceMap.get(instance.metadata.game_version).push(instance)
|
instanceMap.get(instance.game_version).push(instance)
|
||||||
})
|
})
|
||||||
} else if (group.value === 'Category') {
|
} else if (group.value === 'Category') {
|
||||||
instances.forEach((instance) => {
|
instances.forEach((instance) => {
|
||||||
if (instance.metadata.groups.length === 0) {
|
if (instance.groups.length === 0) {
|
||||||
instance.metadata.groups.push('None')
|
instance.groups.push('None')
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const category of instance.metadata.groups) {
|
for (const category of instance.groups) {
|
||||||
if (!instanceMap.has(category)) {
|
if (!instanceMap.has(category)) {
|
||||||
instanceMap.set(category, [])
|
instanceMap.set(category, [])
|
||||||
}
|
}
|
||||||
@@ -233,20 +229,19 @@ const filteredResults = computed(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<ModalConfirm
|
<ConfirmModalWrapper
|
||||||
ref="confirmModal"
|
ref="confirmModal"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
:has-to-type="false"
|
:has-to-type="false"
|
||||||
proceed-label="Delete"
|
proceed-label="Delete"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
@proceed="deleteProfile"
|
@proceed="deleteProfile"
|
||||||
/>
|
/>
|
||||||
<Card class="header">
|
<Card class="header">
|
||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
||||||
<Button @click="() => (search = '')">
|
<Button class="r-btn" @click="() => (search = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
+37
-65
@@ -11,28 +11,20 @@ import {
|
|||||||
ExternalIcon,
|
ExternalIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
ModalConfirm,
|
} from '@modrinth/assets'
|
||||||
} from 'omorphia'
|
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||||
import Instance from '@/components/ui/Instance.vue'
|
import Instance from '@/components/ui/Instance.vue'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||||
import ProjectCard from '@/components/ui/ProjectCard.vue'
|
import ProjectCard from '@/components/ui/ProjectCard.vue'
|
||||||
import InstallConfirmModal from '@/components/ui/InstallConfirmModal.vue'
|
import { get_by_profile_path } from '@/helpers/process.js'
|
||||||
import ModInstallModal from '@/components/ui/ModInstallModal.vue'
|
|
||||||
import {
|
|
||||||
get_all_running_profile_paths,
|
|
||||||
get_uuids_by_profile_path,
|
|
||||||
kill_by_uuid,
|
|
||||||
} from '@/helpers/process.js'
|
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { duplicate, remove, run } from '@/helpers/profile.js'
|
import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||||
import { useFetch } from '@/helpers/fetch.js'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { install as pack_install } from '@/helpers/pack.js'
|
|
||||||
import { useTheming } from '@/store/state.js'
|
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
|
||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
|
import { install as installVersion } from '@/store/install.js'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@@ -58,11 +50,8 @@ const modsRow = ref(null)
|
|||||||
const instanceOptions = ref(null)
|
const instanceOptions = ref(null)
|
||||||
const instanceComponents = ref(null)
|
const instanceComponents = ref(null)
|
||||||
const rows = ref(null)
|
const rows = ref(null)
|
||||||
const confirmModal = ref(null)
|
|
||||||
const deleteConfirmModal = ref(null)
|
const deleteConfirmModal = ref(null)
|
||||||
const modInstallModal = ref(null)
|
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
const currentDeleteInstance = ref(null)
|
const currentDeleteInstance = ref(null)
|
||||||
|
|
||||||
async function deleteProfile() {
|
async function deleteProfile() {
|
||||||
@@ -90,23 +79,24 @@ const handleInstanceRightClick = async (event, passedInstance) => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const running = await get_all_running_profile_paths().catch(handleError)
|
const runningProcesses = await get_by_profile_path(passedInstance.path).catch(handleError)
|
||||||
|
|
||||||
const options = running.includes(passedInstance.path)
|
const options =
|
||||||
? [
|
runningProcesses.length > 0
|
||||||
{
|
? [
|
||||||
name: 'stop',
|
{
|
||||||
color: 'danger',
|
name: 'stop',
|
||||||
},
|
color: 'danger',
|
||||||
...baseOptions,
|
},
|
||||||
]
|
...baseOptions,
|
||||||
: [
|
]
|
||||||
{
|
: [
|
||||||
name: 'play',
|
{
|
||||||
color: 'primary',
|
name: 'play',
|
||||||
},
|
color: 'primary',
|
||||||
...baseOptions,
|
},
|
||||||
]
|
...baseOptions,
|
||||||
|
]
|
||||||
|
|
||||||
instanceOptions.value.showMenu(event, passedInstance, options)
|
instanceOptions.value.showMenu(event, passedInstance, options)
|
||||||
}
|
}
|
||||||
@@ -130,24 +120,24 @@ const handleProjectClick = (event, passedInstance) => {
|
|||||||
const handleOptionsClick = async (args) => {
|
const handleOptionsClick = async (args) => {
|
||||||
switch (args.option) {
|
switch (args.option) {
|
||||||
case 'play':
|
case 'play':
|
||||||
await run(args.item.path).catch(handleSevereError)
|
await run(args.item.path).catch((err) =>
|
||||||
mixpanel_track('InstanceStart', {
|
handleSevereError(err, { profilePath: args.item.path }),
|
||||||
loader: args.item.metadata.loader,
|
)
|
||||||
game_version: args.item.metadata.game_version,
|
trackEvent('InstanceStart', {
|
||||||
|
loader: args.item.loader,
|
||||||
|
game_version: args.item.game_version,
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 'stop':
|
case 'stop':
|
||||||
for (const u of await get_uuids_by_profile_path(args.item.path).catch(handleError)) {
|
await kill(args.item.path).catch(handleError)
|
||||||
await kill_by_uuid(u).catch(handleError)
|
trackEvent('InstanceStop', {
|
||||||
}
|
loader: args.item.loader,
|
||||||
mixpanel_track('InstanceStop', {
|
game_version: args.item.game_version,
|
||||||
loader: args.item.metadata.loader,
|
|
||||||
game_version: args.item.metadata.game_version,
|
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 'add_content':
|
case 'add_content':
|
||||||
await router.push({
|
await router.push({
|
||||||
path: `/browse/${args.item.metadata.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
path: `/browse/${args.item.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||||
query: { i: args.item.path },
|
query: { i: args.item.path },
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
@@ -170,21 +160,8 @@ const handleOptionsClick = async (args) => {
|
|||||||
await navigator.clipboard.writeText(args.item.path)
|
await navigator.clipboard.writeText(args.item.path)
|
||||||
break
|
break
|
||||||
case 'install': {
|
case 'install': {
|
||||||
const versions = await useFetch(
|
await installVersion(args.item.project_id, null, null, 'ProjectCardContextMenu')
|
||||||
`https://api.modrinth.com/v2/project/${args.item.project_id}/version`,
|
|
||||||
'project versions',
|
|
||||||
)
|
|
||||||
|
|
||||||
if (args.item.project_type === 'modpack') {
|
|
||||||
await pack_install(
|
|
||||||
args.item.project_id,
|
|
||||||
versions[0].id,
|
|
||||||
args.item.title,
|
|
||||||
args.item.icon_url,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
modInstallModal.value.show(args.item.project_id, versions)
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'open_link':
|
case 'open_link':
|
||||||
@@ -228,13 +205,12 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ModalConfirm
|
<ConfirmModalWrapper
|
||||||
ref="deleteConfirmModal"
|
ref="deleteConfirmModal"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
:has-to-type="false"
|
:has-to-type="false"
|
||||||
proceed-label="Delete"
|
proceed-label="Delete"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
@proceed="deleteProfile"
|
@proceed="deleteProfile"
|
||||||
/>
|
/>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -243,7 +219,7 @@ onUnmounted(() => {
|
|||||||
<router-link :to="row.route">{{ row.label }}</router-link>
|
<router-link :to="row.route">{{ row.label }}</router-link>
|
||||||
<ChevronRightIcon />
|
<ChevronRightIcon />
|
||||||
</div>
|
</div>
|
||||||
<section v-if="row.instances[0].metadata" ref="modsRow" class="instances">
|
<section v-if="row.instance" ref="modsRow" class="instances">
|
||||||
<Instance
|
<Instance
|
||||||
v-for="instance in row.instances.slice(0, maxInstancesPerRow)"
|
v-for="instance in row.instances.slice(0, maxInstancesPerRow)"
|
||||||
:key="(instance?.project_id || instance?.id) + instance.install_stage"
|
:key="(instance?.project_id || instance?.id) + instance.install_stage"
|
||||||
@@ -258,8 +234,6 @@ onUnmounted(() => {
|
|||||||
ref="instanceComponents"
|
ref="instanceComponents"
|
||||||
class="item"
|
class="item"
|
||||||
:project="project"
|
:project="project"
|
||||||
:confirm-modal="confirmModal"
|
|
||||||
:mod-install-modal="modInstallModal"
|
|
||||||
@contextmenu.prevent.stop="(event) => handleProjectClick(event, project)"
|
@contextmenu.prevent.stop="(event) => handleProjectClick(event, project)"
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
@@ -278,8 +252,6 @@ onUnmounted(() => {
|
|||||||
<template #open_link> <GlobeIcon /> Open in Modrinth <ExternalIcon /> </template>
|
<template #open_link> <GlobeIcon /> Open in Modrinth <ExternalIcon /> </template>
|
||||||
<template #copy_link> <ClipboardCopyIcon /> Copy link </template>
|
<template #copy_link> <ClipboardCopyIcon /> Copy link </template>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
<InstallConfirmModal ref="confirmModal" />
|
|
||||||
<ModInstallModal ref="modInstallModal" />
|
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.content {
|
.content {
|
||||||
+6
-4
@@ -40,10 +40,12 @@ export default defineComponent({
|
|||||||
const loading = useLoading()
|
const loading = useLoading()
|
||||||
|
|
||||||
watch(loading, (newValue) => {
|
watch(loading, (newValue) => {
|
||||||
if (newValue.loading) {
|
if (newValue.barEnabled) {
|
||||||
indicator.start()
|
if (newValue.loading) {
|
||||||
} else {
|
indicator.start()
|
||||||
indicator.finish()
|
} else {
|
||||||
|
indicator.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
+23
-8
@@ -5,7 +5,7 @@
|
|||||||
v-tooltip.right="'Minecraft accounts'"
|
v-tooltip.right="'Minecraft accounts'"
|
||||||
class="button-base avatar-button"
|
class="button-base avatar-button"
|
||||||
:class="{ expanded: mode === 'expanded' }"
|
:class="{ expanded: mode === 'expanded' }"
|
||||||
@click="showCard = !showCard"
|
@click="toggleMenu"
|
||||||
>
|
>
|
||||||
<Avatar
|
<Avatar
|
||||||
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
||||||
@@ -59,7 +59,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Avatar, Button, Card, PlusIcon, TrashIcon, LogInIcon } from 'omorphia'
|
import { PlusIcon, TrashIcon, LogInIcon } from '@modrinth/assets'
|
||||||
|
import { Avatar, Button, Card } from '@modrinth/ui'
|
||||||
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue'
|
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue'
|
||||||
import {
|
import {
|
||||||
users,
|
users,
|
||||||
@@ -69,9 +70,10 @@ import {
|
|||||||
get_default_user,
|
get_default_user,
|
||||||
} from '@/helpers/auth'
|
} from '@/helpers/auth'
|
||||||
import { handleError } from '@/store/state.js'
|
import { handleError } from '@/store/state.js'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { process_listener } from '@/helpers/events'
|
import { process_listener } from '@/helpers/events'
|
||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
mode: {
|
mode: {
|
||||||
@@ -117,7 +119,7 @@ async function login() {
|
|||||||
await refreshValues()
|
await refreshValues()
|
||||||
}
|
}
|
||||||
|
|
||||||
mixpanel_track('AccountLogIn')
|
trackEvent('AccountLogIn')
|
||||||
}
|
}
|
||||||
|
|
||||||
const logout = async (id) => {
|
const logout = async (id) => {
|
||||||
@@ -129,12 +131,12 @@ const logout = async (id) => {
|
|||||||
} else {
|
} else {
|
||||||
emit('change')
|
emit('change')
|
||||||
}
|
}
|
||||||
mixpanel_track('AccountLogOut')
|
trackEvent('AccountLogOut')
|
||||||
}
|
}
|
||||||
|
|
||||||
let showCard = ref(false)
|
const showCard = ref(false)
|
||||||
let card = ref(null)
|
const card = ref(null)
|
||||||
let button = ref(null)
|
const button = ref(null)
|
||||||
const handleClickOutside = (event) => {
|
const handleClickOutside = (event) => {
|
||||||
const elements = document.elementsFromPoint(event.clientX, event.clientY)
|
const elements = document.elementsFromPoint(event.clientX, event.clientY)
|
||||||
if (
|
if (
|
||||||
@@ -143,7 +145,20 @@ const handleClickOutside = (event) => {
|
|||||||
!elements.includes(card.value.$el) &&
|
!elements.includes(card.value.$el) &&
|
||||||
!button.value.contains(event.target)
|
!button.value.contains(event.target)
|
||||||
) {
|
) {
|
||||||
|
toggleMenu(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMenu(override = true) {
|
||||||
|
if (showCard.value || !override) {
|
||||||
|
if (showCard.value) {
|
||||||
|
show_ads_window()
|
||||||
|
}
|
||||||
|
|
||||||
showCard.value = false
|
showCard.value = false
|
||||||
|
} else {
|
||||||
|
hide_ads_window()
|
||||||
|
showCard.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { DropdownIcon, FolderOpenIcon, SearchIcon } from '@modrinth/assets'
|
||||||
|
import { Button, OverflowMenu } from '@modrinth/ui'
|
||||||
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
|
import { add_project_from_path } from '@/helpers/profile.js'
|
||||||
|
import { handleError } from '@/store/notifications.js'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
instance: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const handleAddContentFromFile = async () => {
|
||||||
|
const newProject = await open({ multiple: true })
|
||||||
|
if (!newProject) return
|
||||||
|
|
||||||
|
for (const project of newProject) {
|
||||||
|
await add_project_from_path(props.instance.path, project.path ?? project).catch(handleError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearchContent = async () => {
|
||||||
|
await router.push({
|
||||||
|
path: `/browse/${props.instance.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||||
|
query: { i: props.instance.path },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="joined-buttons">
|
||||||
|
<Button color="primary" @click="handleSearchContent"><SearchIcon /> Add content </Button>
|
||||||
|
|
||||||
|
<OverflowMenu
|
||||||
|
:options="[
|
||||||
|
{
|
||||||
|
id: 'search',
|
||||||
|
action: handleSearchContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'from_file',
|
||||||
|
action: handleAddContentFromFile,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
class="btn btn-primary btn-dropdown-animation icon-only"
|
||||||
|
>
|
||||||
|
<DropdownIcon />
|
||||||
|
<template #search>
|
||||||
|
<SearchIcon />
|
||||||
|
<span class="no-wrap"> Search </span>
|
||||||
|
</template>
|
||||||
|
<template #from_file>
|
||||||
|
<FolderOpenIcon />
|
||||||
|
<span class="no-wrap"> Add from file </span>
|
||||||
|
</template>
|
||||||
|
</OverflowMenu>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
+2
-1
@@ -31,7 +31,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ChevronRightIcon, Button, ChevronLeftIcon } from 'omorphia'
|
import { ChevronRightIcon, ChevronLeftIcon } from '@modrinth/assets'
|
||||||
|
import { Button } from '@modrinth/ui'
|
||||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
+7
-2
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
|
||||||
const emit = defineEmits(['menu-closed', 'option-clicked'])
|
const emit = defineEmits(['menu-closed', 'option-clicked'])
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ const shown = ref(false)
|
|||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
showMenu: (event, passedItem, passedOptions) => {
|
showMenu: (event, passedItem, passedOptions) => {
|
||||||
|
hide_ads_window()
|
||||||
item.value = passedItem
|
item.value = passedItem
|
||||||
options.value = passedOptions
|
options.value = passedOptions
|
||||||
|
|
||||||
@@ -60,15 +62,18 @@ defineExpose({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const isLinkedData = (item) => {
|
const isLinkedData = (item) => {
|
||||||
if (item.instance != undefined && item.instance.metadata.linked_data) {
|
if (item.instance != undefined && item.instance.linked_data) {
|
||||||
return true
|
return true
|
||||||
} else if (item.metadata != undefined && item.metadata.linked_data) {
|
} else if (item != undefined && item.linked_data) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideContextMenu = () => {
|
const hideContextMenu = () => {
|
||||||
|
if (shown.value) {
|
||||||
|
show_ads_window()
|
||||||
|
}
|
||||||
shown.value = false
|
shown.value = false
|
||||||
emit('menu-closed')
|
emit('menu-closed')
|
||||||
}
|
}
|
||||||
+153
-44
@@ -1,14 +1,18 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Modal, XIcon, IssuesIcon, LogInIcon } from 'omorphia'
|
import { XIcon, HammerIcon, LogInIcon, UpdatedIcon } from '@modrinth/assets'
|
||||||
import { ChatIcon } from '@/assets/icons'
|
import { ChatIcon } from '@/assets/icons'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import mixpanel from 'mixpanel-browser'
|
|
||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
|
import { cancel_directory_change } from '@/helpers/settings.js'
|
||||||
|
import { install } from '@/helpers/profile.js'
|
||||||
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const errorModal = ref()
|
const errorModal = ref()
|
||||||
const error = ref()
|
const error = ref()
|
||||||
|
const closable = ref(true)
|
||||||
|
|
||||||
const title = ref('An error occurred')
|
const title = ref('An error occurred')
|
||||||
const errorType = ref('unknown')
|
const errorType = ref('unknown')
|
||||||
@@ -16,14 +20,19 @@ const supportLink = ref('https://support.modrinth.com')
|
|||||||
const metadata = ref({})
|
const metadata = ref({})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
async show(errorVal) {
|
async show(errorVal, context, canClose = true, source = null) {
|
||||||
|
closable.value = canClose
|
||||||
|
|
||||||
if (errorVal.message && errorVal.message.includes('Minecraft authentication error:')) {
|
if (errorVal.message && errorVal.message.includes('Minecraft authentication error:')) {
|
||||||
title.value = 'Unable to sign in to Minecraft'
|
title.value = 'Unable to sign in to Minecraft'
|
||||||
errorType.value = 'minecraft_auth'
|
errorType.value = 'minecraft_auth'
|
||||||
supportLink.value =
|
supportLink.value =
|
||||||
'https://support.modrinth.com/en/articles/9038231-minecraft-sign-in-issues'
|
'https://support.modrinth.com/en/articles/9038231-minecraft-sign-in-issues'
|
||||||
|
|
||||||
if (errorVal.message.includes('existing connection was forcibly closed')) {
|
if (
|
||||||
|
errorVal.message.includes('existing connection was forcibly closed') ||
|
||||||
|
errorVal.message.includes('error sending request for url')
|
||||||
|
) {
|
||||||
metadata.value.network = true
|
metadata.value.network = true
|
||||||
}
|
}
|
||||||
if (errorVal.message.includes('because the target machine actively refused it')) {
|
if (errorVal.message.includes('because the target machine actively refused it')) {
|
||||||
@@ -33,6 +42,27 @@ defineExpose({
|
|||||||
title.value = 'Sign in to Minecraft'
|
title.value = 'Sign in to Minecraft'
|
||||||
errorType.value = 'minecraft_sign_in'
|
errorType.value = 'minecraft_sign_in'
|
||||||
supportLink.value = 'https://support.modrinth.com'
|
supportLink.value = 'https://support.modrinth.com'
|
||||||
|
} else if (errorVal.message && errorVal.message.includes('Move directory error:')) {
|
||||||
|
title.value = 'Could not change app directory'
|
||||||
|
errorType.value = 'directory_move'
|
||||||
|
supportLink.value = 'https://support.modrinth.com'
|
||||||
|
|
||||||
|
if (errorVal.message.includes('directory is not writeable')) {
|
||||||
|
metadata.value.readOnly = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorVal.message.includes('Not enough space')) {
|
||||||
|
metadata.value.notEnoughSpace = true
|
||||||
|
}
|
||||||
|
} else if (errorVal.message && errorVal.message.includes('No loader version selected for')) {
|
||||||
|
title.value = 'No loader selected'
|
||||||
|
errorType.value = 'no_loader_version'
|
||||||
|
supportLink.value = 'https://support.modrinth.com'
|
||||||
|
metadata.value.profilePath = context.profilePath
|
||||||
|
} else if (source === 'state_init') {
|
||||||
|
title.value = 'Error initializing Modrinth App'
|
||||||
|
errorType.value = 'state_init'
|
||||||
|
supportLink.value = 'https://support.modrinth.com'
|
||||||
} else {
|
} else {
|
||||||
title.value = 'An error occurred'
|
title.value = 'An error occurred'
|
||||||
errorType.value = 'unknown'
|
errorType.value = 'unknown'
|
||||||
@@ -55,7 +85,7 @@ async function loginMinecraft() {
|
|||||||
await set_default_user(loggedIn.id).catch(handleError)
|
await set_default_user(loggedIn.id).catch(handleError)
|
||||||
}
|
}
|
||||||
|
|
||||||
await mixpanel.track('AccountLogIn')
|
await trackEvent('AccountLogIn', { source: 'ErrorModal' })
|
||||||
loadingMinecraft.value = false
|
loadingMinecraft.value = false
|
||||||
errorModal.value.hide()
|
errorModal.value.hide()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -63,17 +93,38 @@ async function loginMinecraft() {
|
|||||||
handleSevereError(err)
|
handleSevereError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function cancelDirectoryChange() {
|
||||||
|
try {
|
||||||
|
await cancel_directory_change()
|
||||||
|
window.location.reload()
|
||||||
|
} catch (err) {
|
||||||
|
handleError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function retryDirectoryChange() {
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadingRepair = ref(false)
|
||||||
|
async function repairInstance() {
|
||||||
|
loadingRepair.value = true
|
||||||
|
try {
|
||||||
|
await install(metadata.value.profilePath, false)
|
||||||
|
errorModal.value.hide()
|
||||||
|
} catch (err) {
|
||||||
|
handleSevereError(err)
|
||||||
|
}
|
||||||
|
loadingRepair.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="errorModal" :header="title">
|
<ModalWrapper ref="errorModal" :header="title" :closable="closable">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="markdown-body">
|
<div class="markdown-body">
|
||||||
<template v-if="errorType === 'minecraft_auth'">
|
<template v-if="errorType === 'minecraft_auth'">
|
||||||
<p>
|
|
||||||
Signing into Microsoft account is a complex task for the launchers, and there are a lot
|
|
||||||
of things can go wrong.
|
|
||||||
</p>
|
|
||||||
<template v-if="metadata.network">
|
<template v-if="metadata.network">
|
||||||
<h3>Network issues</h3>
|
<h3>Network issues</h3>
|
||||||
<p>
|
<p>
|
||||||
@@ -103,49 +154,62 @@ async function loginMinecraft() {
|
|||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<h3>Make sure you are signing into the right Microsoft account</h3>
|
<h3>Try another Microsoft account</h3>
|
||||||
<p>
|
<p>
|
||||||
More often than not, this error is caused by you signing into an incorrect Microsoft
|
Double check you've signed in with the right account. You may own Minecraft on a
|
||||||
account which isn't linked to Minecraft. Double check and try again!
|
different Microsoft account.
|
||||||
</p>
|
</p>
|
||||||
<h3>Try signing in and launching through the official launcher first</h3>
|
<div class="cta-button">
|
||||||
|
<button class="btn btn-primary" :disabled="loadingMinecraft" @click="loginMinecraft">
|
||||||
|
<LogInIcon /> Try another account
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<h3>Using PC Game Pass, coming from Bedrock, or just bought the game?</h3>
|
||||||
<p>
|
<p>
|
||||||
If you just bought Minecraft, are coming from the Bedrock Edition world and have never
|
Try signing in with the
|
||||||
played Java before, or just subscribed to PC Game Pass, you would need to start the
|
<a href="https://www.minecraft.net/en-us/download">official Minecraft Launcher</a>
|
||||||
game at least once using the
|
first. Once you're done, come back here and sign in!
|
||||||
<a href="https://www.minecraft.net/en-us/download">official Minecraft Launcher</a>.
|
|
||||||
Once you're done, come back here and sign in!
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<div class="cta-button">
|
<div class="cta-button">
|
||||||
<button class="btn btn-primary" :disabled="loadingMinecraft" @click="loginMinecraft">
|
<button class="btn btn-primary" :disabled="loadingMinecraft" @click="loginMinecraft">
|
||||||
<LogInIcon /> Sign in to Minecraft
|
<LogInIcon /> Try signing in again
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="errorType === 'directory_move'">
|
||||||
|
<template v-if="metadata.readOnly">
|
||||||
|
<h3>Change directory permissions</h3>
|
||||||
|
<p>
|
||||||
|
It looks like the Modrinth App is unable to write to the directory you selected.
|
||||||
|
Please adjust the permissions of the directory and try again or cancel the directory
|
||||||
|
change.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="metadata.notEnoughSpace">
|
||||||
|
<h3>Not enough space</h3>
|
||||||
|
<p>
|
||||||
|
It looks like there is not enough space on the disk containing the dirctory you
|
||||||
|
selected Please free up some space and try again or cancel the directory change.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<p>
|
||||||
|
The Modrinth App is unable to migrate to the new directory you selected. Please
|
||||||
|
contact support for help or cancel the directory change.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="cta-button">
|
||||||
|
<button class="btn" @click="retryDirectoryChange">
|
||||||
|
<UpdatedIcon /> Retry directory change
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger" @click="cancelDirectoryChange">
|
||||||
|
<XIcon /> Cancel directory change
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
|
||||||
<p>
|
|
||||||
If nothing is working and you need help, visit
|
|
||||||
<a :href="supportLink">our support page</a>
|
|
||||||
and start a chat using the widget in the bottom right and we will be more than happy to
|
|
||||||
assist!
|
|
||||||
</p>
|
|
||||||
<details>
|
|
||||||
<summary>Debug info</summary>
|
|
||||||
{{ error.message ?? error }}
|
|
||||||
</details>
|
|
||||||
</template>
|
</template>
|
||||||
<div v-else-if="errorType === 'minecraft_sign_in'">
|
<div v-else-if="errorType === 'minecraft_sign_in'">
|
||||||
<div class="warning-banner">
|
|
||||||
<div class="warning-banner__title">
|
|
||||||
<IssuesIcon />
|
|
||||||
<span>Installed the app before April 23rd, 2024?</span>
|
|
||||||
</div>
|
|
||||||
<div class="warning-banner__description">
|
|
||||||
Modrinth has updated our sign-in workflow to allow for better stability, security, and
|
|
||||||
performance. You must sign in again so your credentials can be upgraded to this new
|
|
||||||
flow.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p>
|
<p>
|
||||||
To play this instance, you must sign in through Microsoft below. If you don't have a
|
To play this instance, you must sign in through Microsoft below. If you don't have a
|
||||||
Minecraft account, you can purchase the game on the
|
Minecraft account, you can purchase the game on the
|
||||||
@@ -159,16 +223,56 @@ async function loginMinecraft() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<template v-else-if="errorType === 'state_init'">
|
||||||
|
<p>
|
||||||
|
Modrinth App failed to load correctly. This may be because of a corrupted file, or
|
||||||
|
because the app is missing crucial files.
|
||||||
|
</p>
|
||||||
|
<p>You may be able to fix it through one of the following ways:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Ensuring you are connected to the internet, then try restarting the app.</li>
|
||||||
|
<li>Redownloading the app.</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="errorType === 'no_loader_version'">
|
||||||
|
<p>The Modrinth App failed to find the loader version for this instance.</p>
|
||||||
|
<p>To resolve this, you need to repair the instance. Click the button below to do so.</p>
|
||||||
|
<div class="cta-button">
|
||||||
|
<button class="btn btn-primary" :disabled="loadingRepair" @click="repairInstance">
|
||||||
|
<HammerIcon /> Repair instance
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ error.message ?? error }}
|
{{ error.message ?? error }}
|
||||||
</template>
|
</template>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
errorType === 'directory_move' ||
|
||||||
|
errorType === 'minecraft_auth' ||
|
||||||
|
errorType === 'state_init' ||
|
||||||
|
errorType === 'no_loader_version'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<hr />
|
||||||
|
<p>
|
||||||
|
If nothing is working and you need help, visit
|
||||||
|
<a :href="supportLink">our support page</a>
|
||||||
|
and start a chat using the widget in the bottom right and we will be more than happy to
|
||||||
|
assist! Make sure to provide the following debug information to the agent:
|
||||||
|
</p>
|
||||||
|
<details>
|
||||||
|
<summary>Debug information</summary>
|
||||||
|
{{ error.message ?? error }}
|
||||||
|
</details>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group push-right">
|
<div class="input-group push-right">
|
||||||
<a :href="supportLink" class="btn" @click="errorModal.hide()"><ChatIcon /> Get support</a>
|
<a :href="supportLink" class="btn" @click="errorModal.hide()"><ChatIcon /> Get support</a>
|
||||||
<button class="btn" @click="errorModal.hide()"><XIcon /> Close</button>
|
<button v-if="closable" class="btn" @click="errorModal.hide()"><XIcon /> Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -188,6 +292,7 @@ async function loginMinecraft() {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.warning-banner {
|
.warning-banner {
|
||||||
@@ -220,4 +325,8 @@ async function loginMinecraft() {
|
|||||||
gap: var(--gap-md);
|
gap: var(--gap-md);
|
||||||
padding: var(--gap-lg);
|
padding: var(--gap-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.markdown-body {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
+11
-12
@@ -1,11 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Checkbox, Modal, XIcon, PlusIcon } from 'omorphia'
|
import { XIcon, PlusIcon } from '@modrinth/assets'
|
||||||
|
import { Button, Checkbox } from '@modrinth/ui'
|
||||||
import { PackageIcon, VersionIcon } from '@/assets/icons'
|
import { PackageIcon, VersionIcon } from '@/assets/icons'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
||||||
import { open } from '@tauri-apps/api/dialog'
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { useTheming } from '@/store/theme'
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
instance: {
|
instance: {
|
||||||
@@ -22,15 +23,13 @@ defineExpose({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const exportModal = ref(null)
|
const exportModal = ref(null)
|
||||||
const nameInput = ref(props.instance.metadata.name)
|
const nameInput = ref(props.instance.name)
|
||||||
const exportDescription = ref('')
|
const exportDescription = ref('')
|
||||||
const versionInput = ref('1.0.0')
|
const versionInput = ref('1.0.0')
|
||||||
const files = ref([])
|
const files = ref([])
|
||||||
const folders = ref([])
|
const folders = ref([])
|
||||||
const showingFiles = ref(false)
|
const showingFiles = ref(false)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const initFiles = async () => {
|
const initFiles = async () => {
|
||||||
const newFolders = new Map()
|
const newFolders = new Map()
|
||||||
const sep = '/'
|
const sep = '/'
|
||||||
@@ -49,9 +48,9 @@ const initFiles = async () => {
|
|||||||
disabled:
|
disabled:
|
||||||
folder === 'profile.json' ||
|
folder === 'profile.json' ||
|
||||||
folder.startsWith('modrinth_logs') ||
|
folder.startsWith('modrinth_logs') ||
|
||||||
folder.startsWith('.fabric') ||
|
folder.startsWith('.fabric'),
|
||||||
folder.includes('.DS_Store'),
|
|
||||||
}))
|
}))
|
||||||
|
.filter((pathData) => !pathData.path.includes('.DS_Store'))
|
||||||
.forEach((pathData) => {
|
.forEach((pathData) => {
|
||||||
const parent = pathData.path.split(sep).slice(0, -1).join(sep)
|
const parent = pathData.path.split(sep).slice(0, -1).join(sep)
|
||||||
if (parent !== '') {
|
if (parent !== '') {
|
||||||
@@ -105,14 +104,14 @@ const exportPack = async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="exportModal" header="Export modpack" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="exportModal" header="Export modpack">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="labeled_input">
|
<div class="labeled_input">
|
||||||
<p>Modpack Name</p>
|
<p>Modpack Name</p>
|
||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<PackageIcon />
|
<PackageIcon />
|
||||||
<input v-model="nameInput" type="text" placeholder="Modpack name" class="input" />
|
<input v-model="nameInput" type="text" placeholder="Modpack name" class="input" />
|
||||||
<Button @click="nameInput = ''">
|
<Button class="r-btn" @click="nameInput = ''">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,7 +121,7 @@ const exportPack = async () => {
|
|||||||
<div class="iconified-input">
|
<div class="iconified-input">
|
||||||
<VersionIcon />
|
<VersionIcon />
|
||||||
<input v-model="versionInput" type="text" placeholder="1.0.0" class="input" />
|
<input v-model="versionInput" type="text" placeholder="1.0.0" class="input" />
|
||||||
<Button @click="versionInput = ''">
|
<Button class="r-btn" @click="versionInput = ''">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -207,7 +206,7 @@ const exportPack = async () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onUnmounted, ref, computed } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { StopCircleIcon, PlayIcon } from '@modrinth/assets'
|
||||||
|
import { Card, Avatar, AnimatedLogo } from '@modrinth/ui'
|
||||||
|
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||||
|
import { kill, run } from '@/helpers/profile'
|
||||||
|
import { get_by_profile_path } from '@/helpers/process'
|
||||||
|
import { process_listener } from '@/helpers/events'
|
||||||
|
import { handleError } from '@/store/state.js'
|
||||||
|
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||||
|
import { handleSevereError } from '@/store/error.js'
|
||||||
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
instance: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const playing = ref(false)
|
||||||
|
|
||||||
|
const modLoading = computed(() => props.instance.install_stage !== 'installed')
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const seeInstance = async () => {
|
||||||
|
await router.push(`/instance/${encodeURIComponent(props.instance.path)}/`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkProcess = async () => {
|
||||||
|
const runningProcesses = await get_by_profile_path(props.instance.path).catch(handleError)
|
||||||
|
|
||||||
|
playing.value = runningProcesses.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const play = async (e, context) => {
|
||||||
|
e?.stopPropagation()
|
||||||
|
modLoading.value = true
|
||||||
|
await run(props.instance.path).catch((err) =>
|
||||||
|
handleSevereError(err, { profilePath: props.instance.path }),
|
||||||
|
)
|
||||||
|
modLoading.value = false
|
||||||
|
|
||||||
|
trackEvent('InstancePlay', {
|
||||||
|
loader: props.instance.loader,
|
||||||
|
game_version: props.instance.game_version,
|
||||||
|
source: context,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const stop = async (e, context) => {
|
||||||
|
e?.stopPropagation()
|
||||||
|
playing.value = false
|
||||||
|
|
||||||
|
await kill(props.instance.path).catch(handleError)
|
||||||
|
|
||||||
|
trackEvent('InstanceStop', {
|
||||||
|
loader: props.instance.loader,
|
||||||
|
game_version: props.instance.game_version,
|
||||||
|
source: context,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const openFolder = async () => {
|
||||||
|
await showProfileInFolder(props.instance.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addContent = async () => {
|
||||||
|
await router.push({
|
||||||
|
path: `/browse/${props.instance.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||||
|
query: { i: props.instance.path },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
play,
|
||||||
|
stop,
|
||||||
|
seeInstance,
|
||||||
|
openFolder,
|
||||||
|
addContent,
|
||||||
|
instance: props.instance,
|
||||||
|
})
|
||||||
|
|
||||||
|
const unlisten = await process_listener((e) => {
|
||||||
|
if (e.event === 'finished' && e.profile_path_id === props.instance.path) playing.value = false
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => unlisten())
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="instance">
|
||||||
|
<Card class="instance-card-item button-base" @click="seeInstance" @mouseenter="checkProcess">
|
||||||
|
<Avatar
|
||||||
|
size="lg"
|
||||||
|
:src="props.instance.icon_path ? convertFileSrc(props.instance.icon_path) : null"
|
||||||
|
alt="Mod card"
|
||||||
|
class="mod-image"
|
||||||
|
/>
|
||||||
|
<div class="project-info">
|
||||||
|
<p class="title">{{ props.instance.name }}</p>
|
||||||
|
<p
|
||||||
|
v-if="
|
||||||
|
props.instance.install_stage === 'installing' ||
|
||||||
|
props.instance.install_stage === 'not_installed' ||
|
||||||
|
props.instance.install_stage === 'pack_installing'
|
||||||
|
"
|
||||||
|
class="description"
|
||||||
|
>
|
||||||
|
Installing...
|
||||||
|
</p>
|
||||||
|
<p v-else class="description">
|
||||||
|
{{ props.instance.loader }}
|
||||||
|
{{ props.instance.game_version }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<div
|
||||||
|
v-if="playing === true"
|
||||||
|
class="stop cta button-base"
|
||||||
|
@click="(e) => stop(e, 'InstanceCard')"
|
||||||
|
@mousehover="checkProcess"
|
||||||
|
>
|
||||||
|
<StopCircleIcon />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="modLoading === true && playing === false" class="cta loading-cta">
|
||||||
|
<AnimatedLogo class="loading-indicator" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="install cta button-base" @click="(e) => play(e, 'InstanceCard')">
|
||||||
|
<PlayIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.loading-indicator {
|
||||||
|
width: 2.5rem !important;
|
||||||
|
height: 2.5rem !important;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 2.5rem !important;
|
||||||
|
height: 2.5rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.instance {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.cta {
|
||||||
|
opacity: 1;
|
||||||
|
bottom: calc(var(--gap-md) + 4.25rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
z-index: 1;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
right: calc(var(--gap-md) * 2);
|
||||||
|
bottom: 3.25rem;
|
||||||
|
opacity: 0;
|
||||||
|
transition:
|
||||||
|
0.2s ease-in-out bottom,
|
||||||
|
0.2s ease-in-out opacity,
|
||||||
|
0.1s ease-in-out filter !important;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: var(--shadow-floating);
|
||||||
|
|
||||||
|
svg {
|
||||||
|
color: var(--color-accent-contrast);
|
||||||
|
width: 1.5rem !important;
|
||||||
|
height: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.install {
|
||||||
|
background: var(--color-brand);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stop {
|
||||||
|
background: var(--color-red);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.loading-cta {
|
||||||
|
background: hsl(220, 11%, 10%) !important;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.instance-card-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: var(--gap-md);
|
||||||
|
transition: 0.1s ease-in-out all !important; /* overrides Omorphia defaults */
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
.mod-image {
|
||||||
|
--size: 100%;
|
||||||
|
|
||||||
|
width: 100% !important;
|
||||||
|
height: auto !important;
|
||||||
|
max-width: unset !important;
|
||||||
|
max-height: unset !important;
|
||||||
|
aspect-ratio: 1 / 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-info {
|
||||||
|
margin-top: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: var(--color-contrast);
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 110%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--color-base);
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.775rem;
|
||||||
|
line-height: 125%;
|
||||||
|
margin: 0.25rem 0 0;
|
||||||
|
text-transform: capitalize;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+30
-38
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal ref="modal" header="Create instance" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="modal" header="Create instance">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<Chips v-model="creationType" :items="['custom', 'from file', 'import from launcher']" />
|
<Chips v-model="creationType" :items="['custom', 'from file', 'import from launcher']" />
|
||||||
</div>
|
</div>
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
placeholder="Path to launcher"
|
placeholder="Path to launcher"
|
||||||
@change="setPath"
|
@change="setPath"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (selectedLauncherPath = '')">
|
<Button class="r-btn" @click="() => (selectedLauncherPath = '')">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -193,42 +193,31 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Button,
|
|
||||||
Chips,
|
|
||||||
Modal,
|
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
UploadIcon,
|
UploadIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
CodeIcon,
|
CodeIcon,
|
||||||
Checkbox,
|
|
||||||
FolderOpenIcon,
|
FolderOpenIcon,
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
FolderSearchIcon,
|
FolderSearchIcon,
|
||||||
UpdatedIcon,
|
UpdatedIcon,
|
||||||
} from 'omorphia'
|
} from '@modrinth/assets'
|
||||||
|
import { Avatar, Button, Chips, Checkbox } from '@modrinth/ui'
|
||||||
import { computed, onUnmounted, ref, shallowRef } from 'vue'
|
import { computed, onUnmounted, ref, shallowRef } from 'vue'
|
||||||
import { get_loaders } from '@/helpers/tags'
|
import { get_loaders } from '@/helpers/tags'
|
||||||
import { create } from '@/helpers/profile'
|
import { create } from '@/helpers/profile'
|
||||||
import { open } from '@tauri-apps/api/dialog'
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
import { tauri } from '@tauri-apps/api'
|
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||||
import {
|
import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
|
||||||
get_game_versions,
|
|
||||||
get_fabric_versions,
|
|
||||||
get_forge_versions,
|
|
||||||
get_quilt_versions,
|
|
||||||
get_neoforge_versions,
|
|
||||||
} from '@/helpers/metadata'
|
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import Multiselect from 'vue-multiselect'
|
import Multiselect from 'vue-multiselect'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { useTheming } from '@/store/state.js'
|
|
||||||
import { listen } from '@tauri-apps/api/event'
|
|
||||||
import { install_from_file } from '@/helpers/pack.js'
|
import { install_from_file } from '@/helpers/pack.js'
|
||||||
import {
|
import {
|
||||||
get_default_launcher_path,
|
get_default_launcher_path,
|
||||||
@@ -236,8 +225,7 @@ import {
|
|||||||
import_instance,
|
import_instance,
|
||||||
} from '@/helpers/import.js'
|
} from '@/helpers/import.js'
|
||||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||||
|
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const profile_name = ref('')
|
const profile_name = ref('')
|
||||||
const game_version = ref('')
|
const game_version = ref('')
|
||||||
@@ -267,20 +255,22 @@ defineExpose({
|
|||||||
isShowing.value = true
|
isShowing.value = true
|
||||||
modal.value.show()
|
modal.value.show()
|
||||||
|
|
||||||
unlistener.value = await listen('tauri://file-drop', async (event) => {
|
unlistener.value = await getCurrentWebview().onDragDropEvent(async (event) => {
|
||||||
// Only if modal is showing
|
// Only if modal is showing
|
||||||
if (!isShowing.value) return
|
if (!isShowing.value) return
|
||||||
|
if (event.payload.type !== 'drop') return
|
||||||
if (creationType.value !== 'from file') return
|
if (creationType.value !== 'from file') return
|
||||||
hide()
|
hide()
|
||||||
if (event.payload && event.payload.length > 0 && event.payload[0].endsWith('.mrpack')) {
|
const { paths } = event.payload
|
||||||
await install_from_file(event.payload[0]).catch(handleError)
|
if (paths && paths.length > 0 && paths[0].endsWith('.mrpack')) {
|
||||||
mixpanel_track('InstanceCreate', {
|
await install_from_file(paths[0]).catch(handleError)
|
||||||
|
trackEvent('InstanceCreate', {
|
||||||
source: 'CreationModalFileDrop',
|
source: 'CreationModalFileDrop',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
mixpanel_track('InstanceCreateStart', { source: 'CreationModal' })
|
trackEvent('InstanceCreateStart', { source: 'CreationModal' })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -308,10 +298,10 @@ const [
|
|||||||
all_game_versions,
|
all_game_versions,
|
||||||
loaders,
|
loaders,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
get_fabric_versions().then(shallowRef).catch(handleError),
|
get_loader_versions('fabric').then(shallowRef).catch(handleError),
|
||||||
get_forge_versions().then(shallowRef).catch(handleError),
|
get_loader_versions('forge').then(shallowRef).catch(handleError),
|
||||||
get_quilt_versions().then(shallowRef).catch(handleError),
|
get_loader_versions('quilt').then(shallowRef).catch(handleError),
|
||||||
get_neoforge_versions().then(shallowRef).catch(handleError),
|
get_loader_versions('neo').then(shallowRef).catch(handleError),
|
||||||
get_game_versions().then(shallowRef).catch(handleError),
|
get_game_versions().then(shallowRef).catch(handleError),
|
||||||
get_loaders()
|
get_loaders()
|
||||||
.then((value) =>
|
.then((value) =>
|
||||||
@@ -370,7 +360,7 @@ const create_instance = async () => {
|
|||||||
icon.value,
|
icon.value,
|
||||||
).catch(handleError)
|
).catch(handleError)
|
||||||
|
|
||||||
mixpanel_track('InstanceCreate', {
|
trackEvent('InstanceCreate', {
|
||||||
profile_name: profile_name.value,
|
profile_name: profile_name.value,
|
||||||
game_version: game_version.value,
|
game_version: game_version.value,
|
||||||
loader: loader.value,
|
loader: loader.value,
|
||||||
@@ -381,7 +371,7 @@ const create_instance = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const upload_icon = async () => {
|
const upload_icon = async () => {
|
||||||
icon.value = await open({
|
const res = await open({
|
||||||
multiple: false,
|
multiple: false,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
@@ -391,8 +381,10 @@ const upload_icon = async () => {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
icon.value = res.path ?? res
|
||||||
|
|
||||||
if (!icon.value) return
|
if (!icon.value) return
|
||||||
display_icon.value = tauri.convertFileSrc(icon.value)
|
display_icon.value = convertFileSrc(icon.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const reset_icon = () => {
|
const reset_icon = () => {
|
||||||
@@ -427,9 +419,9 @@ const openFile = async () => {
|
|||||||
const newProject = await open({ multiple: false })
|
const newProject = await open({ multiple: false })
|
||||||
if (!newProject) return
|
if (!newProject) return
|
||||||
hide()
|
hide()
|
||||||
await install_from_file(newProject).catch(handleError)
|
await install_from_file(newProject.path ?? newProject).catch(handleError)
|
||||||
|
|
||||||
mixpanel_track('InstanceCreate', {
|
trackEvent('InstanceCreate', {
|
||||||
source: 'CreationModalFileOpen',
|
source: 'CreationModalFileOpen',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -472,7 +464,7 @@ const promises = profileOptions.value.map(async (option) => {
|
|||||||
option.name,
|
option.name,
|
||||||
instances.map((name) => ({ name, selected: false })),
|
instances.map((name) => ({ name, selected: false })),
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Allow failure silently
|
// Allow failure silently
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
+7
-11
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal ref="detectJavaModal" header="Select java version" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="detectJavaModal" header="Select java version">
|
||||||
<div class="auto-detect-modal">
|
<div class="auto-detect-modal">
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="table-row table-head">
|
<div class="table-row table-head">
|
||||||
@@ -32,17 +32,16 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Modal, PlusIcon, CheckIcon, Button, XIcon } from 'omorphia'
|
import { PlusIcon, CheckIcon, XIcon } from '@modrinth/assets'
|
||||||
|
import { Button } from '@modrinth/ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { find_filtered_jres } from '@/helpers/jre.js'
|
import { find_filtered_jres } from '@/helpers/jre.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { useTheming } from '@/store/theme.js'
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const chosenInstallOptions = ref([])
|
const chosenInstallOptions = ref([])
|
||||||
const detectJavaModal = ref(null)
|
const detectJavaModal = ref(null)
|
||||||
@@ -52,9 +51,6 @@ defineExpose({
|
|||||||
show: async (version, currentSelectedJava) => {
|
show: async (version, currentSelectedJava) => {
|
||||||
chosenInstallOptions.value = await find_filtered_jres(version).catch(handleError)
|
chosenInstallOptions.value = await find_filtered_jres(version).catch(handleError)
|
||||||
|
|
||||||
console.log(chosenInstallOptions.value)
|
|
||||||
console.log(version)
|
|
||||||
|
|
||||||
currentSelected.value = currentSelectedJava
|
currentSelected.value = currentSelectedJava
|
||||||
if (!currentSelected.value) {
|
if (!currentSelected.value) {
|
||||||
currentSelected.value = { path: '', version: '' }
|
currentSelected.value = { path: '', version: '' }
|
||||||
@@ -69,7 +65,7 @@ const emit = defineEmits(['submit'])
|
|||||||
function setJavaInstall(javaInstall) {
|
function setJavaInstall(javaInstall) {
|
||||||
emit('submit', javaInstall)
|
emit('submit', javaInstall)
|
||||||
detectJavaModal.value.hide()
|
detectJavaModal.value.hide()
|
||||||
mixpanel_track('JavaAutoDetect', {
|
trackEvent('JavaAutoDetect', {
|
||||||
path: javaInstall.path,
|
path: javaInstall.path,
|
||||||
version: javaInstall.version,
|
version: javaInstall.version,
|
||||||
})
|
})
|
||||||
+15
-13
@@ -53,20 +53,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
PlayIcon,
|
PlayIcon,
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
FolderSearchIcon,
|
FolderSearchIcon,
|
||||||
DownloadIcon,
|
DownloadIcon,
|
||||||
} from 'omorphia'
|
} from '@modrinth/assets'
|
||||||
|
import { Button } from '@modrinth/ui'
|
||||||
import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/helpers/jre.js'
|
import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/helpers/jre.js'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { open } from '@tauri-apps/api/dialog'
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
|
||||||
import { handleError } from '@/store/state.js'
|
import { handleError } from '@/store/state.js'
|
||||||
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
version: {
|
version: {
|
||||||
@@ -113,7 +113,7 @@ async function testJava() {
|
|||||||
)
|
)
|
||||||
testingJava.value = false
|
testingJava.value = false
|
||||||
|
|
||||||
mixpanel_track('JavaTest', {
|
trackEvent('JavaTest', {
|
||||||
path: props.modelValue ? props.modelValue.path : '',
|
path: props.modelValue ? props.modelValue.path : '',
|
||||||
success: testingJavaSuccess.value,
|
success: testingJavaSuccess.value,
|
||||||
})
|
})
|
||||||
@@ -124,20 +124,19 @@ async function testJava() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleJavaFileInput() {
|
async function handleJavaFileInput() {
|
||||||
let filePath = await open()
|
const filePath = await open()
|
||||||
|
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
let result = await get_jre(filePath)
|
let result = await get_jre(filePath.path ?? filePath)
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = {
|
result = {
|
||||||
path: filePath,
|
path: filePath.path ?? filePath,
|
||||||
version: props.version.toString(),
|
version: props.version.toString(),
|
||||||
architecture: 'x86',
|
architecture: 'x86',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixpanel_track('JavaManualSelect', {
|
trackEvent('JavaManualSelect', {
|
||||||
path: filePath,
|
|
||||||
version: props.version,
|
version: props.version,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -150,7 +149,7 @@ async function autoDetect() {
|
|||||||
if (!props.compact) {
|
if (!props.compact) {
|
||||||
detectJavaModal.value.show(props.version, props.modelValue)
|
detectJavaModal.value.show(props.version, props.modelValue)
|
||||||
} else {
|
} else {
|
||||||
let versions = await find_filtered_jres(props.version).catch(handleError)
|
const versions = await find_filtered_jres(props.version).catch(handleError)
|
||||||
if (versions.length > 0) {
|
if (versions.length > 0) {
|
||||||
emit('update:modelValue', versions[0])
|
emit('update:modelValue', versions[0])
|
||||||
}
|
}
|
||||||
@@ -162,7 +161,6 @@ async function reinstallJava() {
|
|||||||
const path = await auto_install_java(props.version).catch(handleError)
|
const path = await auto_install_java(props.version).catch(handleError)
|
||||||
let result = await get_jre(path)
|
let result = await get_jre(path)
|
||||||
|
|
||||||
console.log('java result ' + result)
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = {
|
result = {
|
||||||
path: path,
|
path: path,
|
||||||
@@ -171,7 +169,7 @@ async function reinstallJava() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixpanel_track('JavaReInstall', {
|
trackEvent('JavaReInstall', {
|
||||||
path: path,
|
path: path,
|
||||||
version: props.version,
|
version: props.version,
|
||||||
})
|
})
|
||||||
@@ -205,6 +203,10 @@ async function reinstallJava() {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.test-success {
|
.test-success {
|
||||||
+7
-9
@@ -1,10 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Modal, CheckIcon, Badge } from 'omorphia'
|
import { CheckIcon } from '@modrinth/assets'
|
||||||
|
import { Button, Badge } from '@modrinth/ui'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useTheming } from '@/store/theme'
|
|
||||||
import { update_managed_modrinth_version } from '@/helpers/profile'
|
import { update_managed_modrinth_version } from '@/helpers/profile'
|
||||||
import { releaseColor } from '@/helpers/utils'
|
import { releaseColor } from '@/helpers/utils'
|
||||||
import { SwapIcon } from '@/assets/icons/index.js'
|
import { SwapIcon } from '@/assets/icons/index.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
versions: {
|
versions: {
|
||||||
@@ -28,12 +29,10 @@ const filteredVersions = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const modpackVersionModal = ref(null)
|
const modpackVersionModal = ref(null)
|
||||||
const installedVersion = computed(() => props.instance?.metadata?.linked_data?.version_id)
|
const installedVersion = computed(() => props.instance?.linked_data?.version_id)
|
||||||
const installing = computed(() => props.instance.install_stage !== 'installed')
|
const installing = computed(() => props.instance.install_stage !== 'installed')
|
||||||
const inProgress = ref(false)
|
const inProgress = ref(false)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const switchVersion = async (versionId) => {
|
const switchVersion = async (versionId) => {
|
||||||
inProgress.value = true
|
inProgress.value = true
|
||||||
await update_managed_modrinth_version(props.instance.path, versionId)
|
await update_managed_modrinth_version(props.instance.path, versionId)
|
||||||
@@ -42,14 +41,13 @@ const switchVersion = async (versionId) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<ModalWrapper
|
||||||
ref="modpackVersionModal"
|
ref="modpackVersionModal"
|
||||||
class="modpack-version-modal"
|
class="modpack-version-modal"
|
||||||
header="Change modpack version"
|
header="Change modpack version"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
>
|
>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<Card v-if="instance.metadata.linked_data" class="mod-card">
|
<Card v-if="instance.linked_data" class="mod-card">
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="table-row with-columns table-head">
|
<div class="table-row with-columns table-head">
|
||||||
<div class="table-cell table-text download-cell" />
|
<div class="table-cell table-text download-cell" />
|
||||||
@@ -110,7 +108,7 @@ const switchVersion = async (versionId) => {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
File renamed without changes.
+13
-59
@@ -1,22 +1,13 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { Card, Avatar, Button } from '@modrinth/ui'
|
||||||
Card,
|
import { DownloadIcon, HeartIcon, CalendarIcon } from '@modrinth/assets'
|
||||||
Avatar,
|
import { formatNumber, formatCategory } from '@modrinth/utils'
|
||||||
Button,
|
|
||||||
formatNumber,
|
|
||||||
formatCategory,
|
|
||||||
DownloadIcon,
|
|
||||||
HeartIcon,
|
|
||||||
CalendarIcon,
|
|
||||||
} from 'omorphia'
|
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useFetch } from '@/helpers/fetch.js'
|
import { install as installVersion } from '@/store/install.js'
|
||||||
import { list } from '@/helpers/profile.js'
|
|
||||||
import { handleError } from '@/store/notifications.js'
|
|
||||||
import { install as pack_install } from '@/helpers/pack.js'
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -29,18 +20,6 @@ const props = defineProps({
|
|||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
confirmModal: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
modInstallModal: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const toColor = computed(() => {
|
const toColor = computed(() => {
|
||||||
@@ -72,40 +51,15 @@ const toTransparent = computed(() => {
|
|||||||
const install = async (e) => {
|
const install = async (e) => {
|
||||||
e?.stopPropagation()
|
e?.stopPropagation()
|
||||||
installing.value = true
|
installing.value = true
|
||||||
const versions = await useFetch(
|
await installVersion(
|
||||||
`https://api.modrinth.com/v2/project/${props.project.project_id}/version`,
|
props.project.project_id,
|
||||||
'project versions',
|
null,
|
||||||
)
|
props.instance ? props.instance.path : null,
|
||||||
|
'ProjectCard',
|
||||||
if (props.project.project_type === 'modpack') {
|
() => {
|
||||||
const packs = Object.values(await list(true).catch(handleError))
|
|
||||||
|
|
||||||
if (
|
|
||||||
packs.length === 0 ||
|
|
||||||
!packs
|
|
||||||
.map((value) => value.metadata)
|
|
||||||
.find((pack) => pack.linked_data?.project_id === props.project.project_id)
|
|
||||||
) {
|
|
||||||
installing.value = true
|
|
||||||
await pack_install(
|
|
||||||
props.project.project_id,
|
|
||||||
versions[0].id,
|
|
||||||
props.project.title,
|
|
||||||
props.project.icon_url,
|
|
||||||
).catch(handleError)
|
|
||||||
installing.value = false
|
installing.value = false
|
||||||
} else
|
},
|
||||||
props.confirmModal.show(
|
)
|
||||||
props.project.project_id,
|
|
||||||
versions[0].id,
|
|
||||||
props.project.title,
|
|
||||||
props.project.icon_url,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
props.modInstallModal.show(props.project.project_id, versions)
|
|
||||||
}
|
|
||||||
|
|
||||||
installing.value = false
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { get as getCreds } from '@/helpers/mr_auth.js'
|
||||||
|
import { handleError } from '@/store/notifications.js'
|
||||||
|
import { get_user } from '@/helpers/cache.js'
|
||||||
|
import { ChevronRightIcon } from '@modrinth/assets'
|
||||||
|
import { init_ads_window, open_ads_link, record_ads_click } from '@/helpers/ads.js'
|
||||||
|
import { listen } from '@tauri-apps/api/event'
|
||||||
|
|
||||||
|
const showAd = ref(true)
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
scroll() {
|
||||||
|
updateAdPosition()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const creds = await getCreds().catch(handleError)
|
||||||
|
if (creds && creds.user_id) {
|
||||||
|
const user = await get_user(creds.user_id).catch(handleError)
|
||||||
|
|
||||||
|
const MIDAS_BITFLAG = 1 << 0
|
||||||
|
if (user && (user.badges & MIDAS_BITFLAG) === MIDAS_BITFLAG) {
|
||||||
|
showAd.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const adsWrapper = ref(null)
|
||||||
|
let resizeObserver
|
||||||
|
let scrollHandler
|
||||||
|
let intersectionObserver
|
||||||
|
let mutationObserver
|
||||||
|
onMounted(() => {
|
||||||
|
if (showAd.value) {
|
||||||
|
updateAdPosition(true)
|
||||||
|
|
||||||
|
resizeObserver = new ResizeObserver(() => updateAdPosition())
|
||||||
|
resizeObserver.observe(adsWrapper.value)
|
||||||
|
|
||||||
|
intersectionObserver = new IntersectionObserver(() => updateAdPosition())
|
||||||
|
intersectionObserver.observe(adsWrapper.value)
|
||||||
|
|
||||||
|
mutationObserver = new MutationObserver(() => updateAdPosition())
|
||||||
|
mutationObserver.observe(adsWrapper.value, { attributes: true, childList: true, subtree: true })
|
||||||
|
|
||||||
|
// Add scroll event listener
|
||||||
|
scrollHandler = () => {
|
||||||
|
requestAnimationFrame(() => updateAdPosition())
|
||||||
|
}
|
||||||
|
window.addEventListener('scroll', scrollHandler, { passive: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function updateAdPosition(overrideShown = false) {
|
||||||
|
if (adsWrapper.value) {
|
||||||
|
const rect = adsWrapper.value.getBoundingClientRect()
|
||||||
|
|
||||||
|
let y = rect.top + window.scrollY
|
||||||
|
let height = rect.bottom - rect.top
|
||||||
|
|
||||||
|
// Prevent ad from overlaying the app bar
|
||||||
|
if (y <= 52) {
|
||||||
|
y = 52
|
||||||
|
height = rect.bottom - 52
|
||||||
|
|
||||||
|
if (height < 0) {
|
||||||
|
height = 0
|
||||||
|
y = -1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_ads_window(rect.left + window.scrollX, y, rect.right - rect.left, height, overrideShown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openPlusLink() {
|
||||||
|
await record_ads_click()
|
||||||
|
await open_ads_link('https://modrinth.com/plus', 'https://modrinth.com')
|
||||||
|
}
|
||||||
|
|
||||||
|
const unlisten = await listen('ads-scroll', (event) => {
|
||||||
|
if (adsWrapper.value) {
|
||||||
|
adsWrapper.value.parentNode.scrollTop += event.payload.scroll
|
||||||
|
updateAdPosition()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (resizeObserver) {
|
||||||
|
resizeObserver.disconnect()
|
||||||
|
}
|
||||||
|
if (intersectionObserver) {
|
||||||
|
intersectionObserver.disconnect()
|
||||||
|
}
|
||||||
|
if (mutationObserver) {
|
||||||
|
mutationObserver.disconnect()
|
||||||
|
}
|
||||||
|
if (scrollHandler) {
|
||||||
|
window.removeEventListener('scroll', scrollHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
unlisten()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="showAd"
|
||||||
|
ref="adsWrapper"
|
||||||
|
class="ad-parent relative mb-3 flex w-full justify-center rounded-2xl bg-bg-raised cursor-pointer"
|
||||||
|
>
|
||||||
|
<div class="flex max-h-[250px] min-h-[250px] min-w-[300px] max-w-[300px] flex-col gap-4 p-6">
|
||||||
|
<p class="m-0 text-2xl font-bold text-contrast">75% of ad revenue goes to creators</p>
|
||||||
|
<button
|
||||||
|
class="mt-auto items-center gap-1 text-purple hover:underline bg-transparent border-none text-left cursor-pointer outline-none"
|
||||||
|
@click="openPlusLink"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Support creators and Modrinth ad-free with
|
||||||
|
<span class="font-bold">Modrinth+</span>
|
||||||
|
</span>
|
||||||
|
<ChevronRightIcon class="relative top-[3px] h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
+60
-57
@@ -15,15 +15,15 @@
|
|||||||
</Button>
|
</Button>
|
||||||
<div v-if="offline" class="status">
|
<div v-if="offline" class="status">
|
||||||
<span class="circle stopped" />
|
<span class="circle stopped" />
|
||||||
<div class="running-text clickable" @click="refreshInternet()">
|
<div class="running-text">
|
||||||
<span> Offline </span>
|
<span> Offline </span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectedProfile" class="status">
|
<div v-if="selectedProcess" class="status">
|
||||||
<span class="circle running" />
|
<span class="circle running" />
|
||||||
<div ref="profileButton" class="running-text">
|
<div ref="profileButton" class="running-text">
|
||||||
<router-link :to="`/instance/${encodeURIComponent(selectedProfile.path)}`">
|
<router-link :to="`/instance/${encodeURIComponent(selectedProcess.profile.path)}`">
|
||||||
{{ selectedProfile.metadata.name }}
|
{{ selectedProcess.profile.name }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<div
|
<div
|
||||||
v-if="currentProcesses.length > 1"
|
v-if="currentProcesses.length > 1"
|
||||||
@@ -34,7 +34,12 @@
|
|||||||
<DropdownIcon />
|
<DropdownIcon />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button v-tooltip="'Stop instance'" icon-only class="icon-button stop" @click="stop()">
|
<Button
|
||||||
|
v-tooltip="'Stop instance'"
|
||||||
|
icon-only
|
||||||
|
class="icon-button stop"
|
||||||
|
@click="stop(selectedProcess)"
|
||||||
|
>
|
||||||
<StopCircleIcon />
|
<StopCircleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-tooltip="'View logs'" icon-only class="icon-button" @click="goToTerminal()">
|
<Button v-tooltip="'View logs'" icon-only class="icon-button" @click="goToTerminal()">
|
||||||
@@ -75,17 +80,17 @@
|
|||||||
class="profile-card"
|
class="profile-card"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
v-for="profile in currentProcesses"
|
v-for="process in currentProcesses"
|
||||||
:key="profile.id"
|
:key="process.uuid"
|
||||||
class="profile-button"
|
class="profile-button"
|
||||||
@click="selectProfile(profile)"
|
@click="selectProcess(process)"
|
||||||
>
|
>
|
||||||
<div class="text"><span class="circle running" /> {{ profile.metadata.name }}</div>
|
<div class="text"><span class="circle running" /> {{ process.profile.name }}</div>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="'Stop instance'"
|
v-tooltip="'Stop instance'"
|
||||||
icon-only
|
icon-only
|
||||||
class="icon-button stop"
|
class="icon-button stop"
|
||||||
@click.stop="stop(profile.path)"
|
@click.stop="stop(process)"
|
||||||
>
|
>
|
||||||
<StopCircleIcon />
|
<StopCircleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -93,7 +98,7 @@
|
|||||||
v-tooltip="'View logs'"
|
v-tooltip="'View logs'"
|
||||||
icon-only
|
icon-only
|
||||||
class="icon-button"
|
class="icon-button"
|
||||||
@click.stop="goToTerminal(profile.path)"
|
@click.stop="goToTerminal(process.profile.path)"
|
||||||
>
|
>
|
||||||
<TerminalSquareIcon />
|
<TerminalSquareIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -103,28 +108,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { DownloadIcon, StopCircleIcon, TerminalSquareIcon, DropdownIcon } from '@modrinth/assets'
|
||||||
Button,
|
import { Button, Card } from '@modrinth/ui'
|
||||||
DownloadIcon,
|
|
||||||
Card,
|
|
||||||
StopCircleIcon,
|
|
||||||
TerminalSquareIcon,
|
|
||||||
DropdownIcon,
|
|
||||||
} from 'omorphia'
|
|
||||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||||
import {
|
import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/process'
|
||||||
get_all_running_profiles as getRunningProfiles,
|
import { loading_listener, process_listener } from '@/helpers/events'
|
||||||
kill_by_uuid as killProfile,
|
|
||||||
get_uuids_by_profile_path as getProfileProcesses,
|
|
||||||
} from '@/helpers/process'
|
|
||||||
import { loading_listener, process_listener, offline_listener } from '@/helpers/events'
|
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { progress_bars_list } from '@/helpers/state.js'
|
import { progress_bars_list } from '@/helpers/state.js'
|
||||||
import { refreshOffline, isOffline } from '@/helpers/utils.js'
|
|
||||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
|
||||||
import { ChatIcon } from '@/assets/icons'
|
import { ChatIcon } from '@/assets/icons'
|
||||||
|
import { get_many } from '@/helpers/profile.js'
|
||||||
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const card = ref(null)
|
const card = ref(null)
|
||||||
@@ -135,38 +130,43 @@ const showCard = ref(false)
|
|||||||
|
|
||||||
const showProfiles = ref(false)
|
const showProfiles = ref(false)
|
||||||
|
|
||||||
const currentProcesses = ref(await getRunningProfiles().catch(handleError))
|
const currentProcesses = ref([])
|
||||||
const selectedProfile = ref(currentProcesses.value[0])
|
const selectedProcess = ref()
|
||||||
|
|
||||||
const offline = ref(await isOffline().catch(handleError))
|
const refresh = async () => {
|
||||||
const refreshInternet = async () => {
|
const processes = await getRunningProcesses().catch(handleError)
|
||||||
offline.value = await refreshOffline().catch(handleError)
|
const profiles = await get_many(processes.map((x) => x.profile_path)).catch(handleError)
|
||||||
|
|
||||||
|
currentProcesses.value = processes.map((x) => ({
|
||||||
|
profile: profiles.find((prof) => x.profile_path === prof.path),
|
||||||
|
...x,
|
||||||
|
}))
|
||||||
|
if (!selectedProcess.value || !currentProcesses.value.includes(selectedProcess.value)) {
|
||||||
|
selectedProcess.value = currentProcesses.value[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await refresh()
|
||||||
|
|
||||||
|
const offline = ref(!navigator.onLine)
|
||||||
|
window.addEventListener('offline', () => {
|
||||||
|
offline.value = true
|
||||||
|
})
|
||||||
|
window.addEventListener('online', () => {
|
||||||
|
offline.value = false
|
||||||
|
})
|
||||||
|
|
||||||
const unlistenProcess = await process_listener(async () => {
|
const unlistenProcess = await process_listener(async () => {
|
||||||
await refresh()
|
await refresh()
|
||||||
})
|
})
|
||||||
|
|
||||||
const unlistenRefresh = await offline_listener(async (b) => {
|
const stop = async (process) => {
|
||||||
offline.value = b
|
|
||||||
await refresh()
|
|
||||||
})
|
|
||||||
|
|
||||||
const refresh = async () => {
|
|
||||||
currentProcesses.value = await getRunningProfiles().catch(handleError)
|
|
||||||
if (!currentProcesses.value.includes(selectedProfile.value)) {
|
|
||||||
selectedProfile.value = currentProcesses.value[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const stop = async (path) => {
|
|
||||||
try {
|
try {
|
||||||
const processes = await getProfileProcesses(path ?? selectedProfile.value.path)
|
await killProcess(process.uuid).catch(handleError)
|
||||||
await killProfile(processes[0])
|
|
||||||
|
|
||||||
mixpanel_track('InstanceStop', {
|
trackEvent('InstanceStop', {
|
||||||
loader: currentProcesses.value[0].metadata.loader,
|
loader: process.profile.loader,
|
||||||
game_version: currentProcesses.value[0].metadata.game_version,
|
game_version: process.profile.game_version,
|
||||||
source: 'AppBar',
|
source: 'AppBar',
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -176,7 +176,7 @@ const stop = async (path) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const goToTerminal = (path) => {
|
const goToTerminal = (path) => {
|
||||||
router.push(`/instance/${encodeURIComponent(path ?? selectedProfile.value.path)}/logs`)
|
router.push(`/instance/${encodeURIComponent(path ?? selectedProcess.value.profile.path)}/logs`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentLoadingBars = ref([])
|
const currentLoadingBars = ref([])
|
||||||
@@ -188,8 +188,8 @@ const refreshInfo = async () => {
|
|||||||
if (x.bar_type.type === 'java_download') {
|
if (x.bar_type.type === 'java_download') {
|
||||||
x.title = 'Downloading Java ' + x.bar_type.version
|
x.title = 'Downloading Java ' + x.bar_type.version
|
||||||
}
|
}
|
||||||
if (x.bar_type.profile_name) {
|
if (x.bar_type.profile_path) {
|
||||||
x.title = x.bar_type.profile_name
|
x.title = x.bar_type.profile_path
|
||||||
}
|
}
|
||||||
if (x.bar_type.pack_name) {
|
if (x.bar_type.pack_name) {
|
||||||
x.title = x.bar_type.pack_name
|
x.title = x.bar_type.pack_name
|
||||||
@@ -221,8 +221,8 @@ const unlistenLoading = await loading_listener(async () => {
|
|||||||
await refreshInfo()
|
await refreshInfo()
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectProfile = (profile) => {
|
const selectProcess = (process) => {
|
||||||
selectedProfile.value = profile
|
selectedProcess.value = process
|
||||||
showProfiles.value = false
|
showProfiles.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +273,6 @@ onBeforeUnmount(() => {
|
|||||||
window.removeEventListener('click', handleClickOutsideProfile)
|
window.removeEventListener('click', handleClickOutsideProfile)
|
||||||
unlistenProcess()
|
unlistenProcess()
|
||||||
unlistenLoading()
|
unlistenLoading()
|
||||||
unlistenRefresh()
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -341,8 +340,12 @@ onBeforeUnmount(() => {
|
|||||||
width: 1.25rem !important;
|
width: 1.25rem !important;
|
||||||
height: 1.25rem !important;
|
height: 1.25rem !important;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
min-width: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
&.stop {
|
&.stop {
|
||||||
--text-color: var(--color-red) !important;
|
color: var(--color-red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+15
-117
@@ -63,29 +63,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { DownloadIcon, HeartIcon, CalendarIcon, CheckIcon, StarIcon } from '@modrinth/assets'
|
||||||
Avatar,
|
import { Avatar, Card, Categories, EnvironmentIndicator, Button } from '@modrinth/ui'
|
||||||
Card,
|
import { formatNumber, formatCategory } from '@modrinth/utils'
|
||||||
Categories,
|
|
||||||
EnvironmentIndicator,
|
|
||||||
Button,
|
|
||||||
DownloadIcon,
|
|
||||||
formatNumber,
|
|
||||||
formatCategory,
|
|
||||||
HeartIcon,
|
|
||||||
CalendarIcon,
|
|
||||||
CheckIcon,
|
|
||||||
StarIcon,
|
|
||||||
} from 'omorphia'
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { add_project_from_version as installMod, list } from '@/helpers/profile.js'
|
import { install as installVersion } from '@/store/install.js'
|
||||||
import { install as packInstall } from '@/helpers/pack.js'
|
|
||||||
import { installVersionDependencies } from '@/helpers/utils.js'
|
|
||||||
import { useFetch } from '@/helpers/fetch.js'
|
|
||||||
import { handleError } from '@/store/notifications.js'
|
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -105,18 +89,6 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
confirmModal: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
modInstallModal: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
incompatibilityWarningModal: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
featured: {
|
featured: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
@@ -134,93 +106,19 @@ const installed = ref(props.installed)
|
|||||||
|
|
||||||
async function install() {
|
async function install() {
|
||||||
installing.value = true
|
installing.value = true
|
||||||
const versions = await useFetch(
|
await installVersion(
|
||||||
`https://api.modrinth.com/v2/project/${props.project.project_id}/version`,
|
props.project.project_id,
|
||||||
'project versions',
|
null,
|
||||||
)
|
props.instance ? props.instance.path : null,
|
||||||
let queuedVersionData
|
'SearchCard',
|
||||||
|
(version) => {
|
||||||
if (!props.instance) {
|
|
||||||
queuedVersionData = versions[0]
|
|
||||||
} else {
|
|
||||||
queuedVersionData = versions.find(
|
|
||||||
(v) =>
|
|
||||||
v.game_versions.includes(props.instance.metadata.game_version) &&
|
|
||||||
(props.project.project_type !== 'mod' ||
|
|
||||||
v.loaders.includes(props.instance.metadata.loader)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.project.project_type === 'modpack') {
|
|
||||||
const packs = Object.values(await list().catch(handleError))
|
|
||||||
if (
|
|
||||||
packs.length === 0 ||
|
|
||||||
!packs
|
|
||||||
.map((value) => value.metadata)
|
|
||||||
.find((pack) => pack.linked_data?.project_id === props.project.project_id)
|
|
||||||
) {
|
|
||||||
await packInstall(
|
|
||||||
props.project.project_id,
|
|
||||||
queuedVersionData.id,
|
|
||||||
props.project.title,
|
|
||||||
props.project.icon_url,
|
|
||||||
).catch(handleError)
|
|
||||||
|
|
||||||
mixpanel_track('PackInstall', {
|
|
||||||
id: props.project.project_id,
|
|
||||||
version_id: queuedVersionData.id,
|
|
||||||
title: props.project.title,
|
|
||||||
source: 'SearchCard',
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
props.confirmModal.show(
|
|
||||||
props.project.project_id,
|
|
||||||
queuedVersionData.id,
|
|
||||||
props.project.title,
|
|
||||||
props.project.icon_url,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (props.instance) {
|
|
||||||
if (!queuedVersionData) {
|
|
||||||
props.incompatibilityWarningModal.show(
|
|
||||||
props.instance,
|
|
||||||
props.project.title,
|
|
||||||
versions,
|
|
||||||
() => (installed.value = true),
|
|
||||||
props.project.project_id,
|
|
||||||
props.project.project_type,
|
|
||||||
)
|
|
||||||
installing.value = false
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
await installMod(props.instance.path, queuedVersionData.id).catch(handleError)
|
|
||||||
await installVersionDependencies(props.instance, queuedVersionData)
|
|
||||||
|
|
||||||
mixpanel_track('ProjectInstall', {
|
|
||||||
loader: props.instance.metadata.loader,
|
|
||||||
game_version: props.instance.metadata.game_version,
|
|
||||||
id: props.project.project_id,
|
|
||||||
project_type: props.project.project_type,
|
|
||||||
version_id: queuedVersionData.id,
|
|
||||||
title: props.project.title,
|
|
||||||
source: 'SearchCard',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
props.modInstallModal.show(
|
|
||||||
props.project.project_id,
|
|
||||||
versions,
|
|
||||||
props.project.title,
|
|
||||||
props.project.project_type,
|
|
||||||
)
|
|
||||||
installing.value = false
|
installing.value = false
|
||||||
return
|
|
||||||
}
|
|
||||||
if (props.instance) installed.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
installing.value = false
|
if (props.instance && version) {
|
||||||
|
installed.value = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="!hidden" class="splash-screen dark" :class="{ 'fade-out': doneLoading }">
|
||||||
|
<div v-if="os !== 'MacOS'" class="app-buttons">
|
||||||
|
<button class="btn icon-only transparent" icon-only @click="() => getCurrent().minimize()">
|
||||||
|
<MinimizeIcon />
|
||||||
|
</button>
|
||||||
|
<button class="btn icon-only transparent" @click="() => getCurrent().toggleMaximize()">
|
||||||
|
<MaximizeIcon />
|
||||||
|
</button>
|
||||||
|
<button class="btn icon-only transparent" @click="handleClose">
|
||||||
|
<XIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="app-logo-wrapper" data-tauri-drag-region>
|
||||||
|
<svg
|
||||||
|
class="app-logo"
|
||||||
|
viewBox="0 0 1215 175"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 2"
|
||||||
|
color="var(--color-contrast)"
|
||||||
|
>
|
||||||
|
<g transform="matrix(1,0,0,1,-3395.45,-1175)">
|
||||||
|
<g transform="matrix(0.632704,0,0,0.161619,3395.45,1175)">
|
||||||
|
<rect
|
||||||
|
id="modrinth-app-logo"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1920"
|
||||||
|
height="1080"
|
||||||
|
style="fill: none"
|
||||||
|
/>
|
||||||
|
<g id="modrinth-app-logo1">
|
||||||
|
<g transform="matrix(1.26353,0,0,3.23025,-514.757,-837.171)">
|
||||||
|
<g transform="matrix(1.25087,0,0,1.91545,-240.84,-608.008)">
|
||||||
|
<g transform="matrix(0.273005,0,0,0.273005,523.782,459.389)">
|
||||||
|
<path
|
||||||
|
d="M1053.02,205.51C1088.61,205.51 1117.29,215.61 1138,236.32C1158.72,257.57 1169.34,288.37 1169.34,329.8L1169.34,492.33L1102.94,492.33L1102.94,338.3C1102.94,313.34 1097.64,294.75 1086.48,282C1075.33,269.78 1059.93,263.4 1039.21,263.4C1016.91,263.4 998.84,270.85 985.56,285.19C972.29,300.06 965.38,321.3 965.38,348.39L965.38,492.33L898.98,492.33L898.98,338.3C898.98,313.34 893.68,294.75 882.52,282C871.37,269.78 855.96,263.4 835.25,263.4C812.41,263.4 794.88,270.85 781.6,285.19C768.33,299.53 761.42,320.77 761.42,348.39L761.42,492.33L695.02,492.33L695.02,208.7L758.23,208.7L758.23,244.82C768.86,232.07 782.13,222.52 798.07,215.61C814,208.71 831.53,205.51 851.18,205.51C872.43,205.51 891.55,209.23 908.02,217.2C924.48,225.7 937.23,237.38 946.79,252.79C958.48,237.91 973.35,226.23 991.94,217.73C1010.53,209.76 1030.71,205.51 1053.02,205.51ZM1382.86,496.05C1354.18,496.05 1328.16,489.68 1305.32,477.46C1282.84,465.588 1264.22,447.523 1251.67,425.41C1238.39,403.63 1232.02,378.67 1232.02,350.51C1232.02,322.37 1238.39,297.41 1251.67,275.63C1264.39,253.783 1282.98,235.93 1305.32,224.1C1328.16,211.89 1354.18,205.51 1382.86,205.51C1412.08,205.51 1438.1,211.89 1460.94,224.11C1483.78,236.32 1501.84,253.85 1515.12,275.63C1527.87,297.4 1534.24,322.37 1534.24,350.52C1534.24,378.67 1527.87,403.63 1515.12,425.41C1501.84,447.71 1483.78,465.24 1460.94,477.46C1438.1,489.68 1412.08,496.06 1382.86,496.06L1382.86,496.05ZM1382.86,439.22C1407.3,439.22 1427.48,431.25 1443.41,414.79C1459.35,398.32 1467.31,377.07 1467.31,350.52C1467.31,323.96 1459.35,302.72 1443.41,286.25C1427.48,269.78 1407.3,261.82 1382.86,261.82C1358.43,261.82 1338.25,269.78 1322.84,286.25C1306.91,302.71 1298.94,323.96 1298.94,350.52C1298.94,377.07 1306.91,398.32 1322.84,414.79C1338.24,431.25 1358.44,439.22 1382.86,439.22ZM1874.18,98.22L1874.18,492.33L1810.44,492.33L1810.44,455.68C1799.56,468.819 1785.73,479.196 1770.07,485.96C1753.61,492.86 1736.07,496.06 1716.42,496.06C1689.34,496.06 1664.9,490.21 1643.12,477.99C1621.35,465.78 1603.82,448.78 1591.6,426.47C1579.39,404.69 1573.01,379.2 1573.01,350.52C1573.01,321.84 1579.39,296.34 1591.61,274.56C1603.82,252.79 1621.35,235.79 1643.13,223.57C1664.9,211.36 1689.33,205.51 1716.43,205.51C1735.02,205.51 1752.54,208.71 1767.95,215.07C1783.28,221.396 1796.92,231.222 1807.78,243.76L1807.78,98.22L1874.18,98.22ZM1724.39,439.22C1740.33,439.22 1754.67,435.5 1767.42,428.06C1780.16,421.16 1790.25,410.54 1797.69,397.26C1805.13,383.98 1808.84,368.05 1808.84,350.52C1808.84,332.99 1805.13,317.06 1797.69,303.78C1790.25,290.5 1780.16,279.88 1767.42,272.44C1754.67,265.54 1740.32,261.82 1724.39,261.82C1708.46,261.82 1694.12,265.53 1681.37,272.44C1668.62,279.87 1658.53,290.5 1651.09,303.78C1643.66,317.06 1639.94,332.98 1639.94,350.52C1639.94,368.05 1643.66,383.98 1651.09,397.26C1658.53,410.54 1668.62,421.16 1681.37,428.06C1694.12,435.5 1708.46,439.22 1724.39,439.22ZM2022.9,250.13C2042.02,220.39 2075.48,205.51 2123.82,205.51L2123.82,268.72C2118.75,267.715 2113.59,267.18 2108.42,267.12C2082.39,267.12 2062.2,274.56 2047.86,289.44C2033.52,304.84 2026.08,326.62 2026.08,354.77L2026.08,492.33L1959.69,492.33L1959.69,208.7L2022.89,208.7L2022.89,250.13L2022.9,250.13ZM2178.52,208.7L2244.92,208.7L2244.92,492.33L2178.52,492.33L2178.52,208.7ZM2211.99,161.96C2199.77,161.96 2189.68,158.24 2181.71,150.28C2173.8,143.08 2169.35,132.817 2169.5,122.12C2169.5,110.97 2173.75,101.41 2181.71,93.44C2189.68,86.01 2199.77,82.29 2211.99,82.29C2224.2,82.29 2234.29,86.01 2242.26,92.91C2250.23,100.35 2254.48,109.38 2254.48,120.53C2254.48,132.22 2250.76,141.78 2242.79,149.74C2234.83,157.71 2224.2,161.96 2211.99,161.96ZM2491.37,205.51C2526.96,205.51 2555.64,216.14 2577.42,236.85C2599.2,257.57 2609.82,288.9 2609.82,329.8L2609.82,492.33L2543.42,492.33L2543.42,338.3C2543.42,313.34 2537.58,294.75 2525.9,282C2514.21,269.78 2497.75,263.4 2475.97,263.4C2451.54,263.4 2432.42,270.85 2418.07,285.19C2403.73,300.06 2396.83,321.3 2396.83,348.92L2396.83,492.33L2330.43,492.33L2330.43,208.7L2393.64,208.7L2393.64,245.35C2404.8,232.07 2418.61,222.51 2435.07,215.61C2451.54,208.71 2470.66,205.51 2491.37,205.51ZM2863.18,476.93C2854.87,483.572 2845.29,488.451 2835.03,491.27C2823.44,494.492 2811.46,496.101 2799.43,496.05C2768.1,496.05 2744.2,488.08 2727.2,471.62C2710.2,455.15 2701.7,431.78 2701.7,400.45L2701.7,263.94L2654.97,263.94L2654.97,210.83L2701.71,210.83L2701.71,146.03L2768.11,146.03L2768.11,210.83L2844.06,210.83L2844.06,263.94L2768.1,263.94L2768.1,398.85C2768.1,412.66 2771.29,423.28 2778.2,430.19C2785.1,437.63 2794.66,441.34 2807.4,441.34C2822.28,441.34 2834.5,437.63 2844.59,429.66L2863.18,476.93ZM3077.23,205.51C3112.82,205.51 3141.5,216.14 3163.28,236.85C3185.05,257.57 3195.68,288.9 3195.68,329.8L3195.68,492.33L3129.28,492.33L3129.28,338.3C3129.28,313.34 3123.44,294.75 3111.75,282C3100.07,269.78 3083.6,263.4 3061.83,263.4C3037.39,263.4 3018.27,270.85 3003.93,285.19C2989.59,300.06 2982.69,321.3 2982.69,348.92L2982.69,492.33L2916.29,492.33L2916.29,98.23L2982.69,98.23L2982.69,241.Line truncated
|
||||||
|
style="fill: currentColor; fill-rule: nonzero"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(0.273005,0,0,0.273005,523.782,459.389)">
|
||||||
|
<path
|
||||||
|
d="M29,424.4L217.2,311.45L200.05,265.97L253.8,210.76L321.73,196.12L341.4,220.33L310.08,252.05L282.78,260.65L263.26,280.7L272.82,307.3L292.22,327.9L319.58,320.62L339.05,299.24L381.56,285.77L394.23,314.27L350.36,368.05L276.86,391.32L243.89,354.62L55.06,467.94C46.1,456.41 35.67,440.08 29,424.4ZM572.03,194.15L422.53,234.47C430.77,256.39 433.48,269.27 435.76,283.47L584.99,243.21C582.61,227.27 578.34,211.04 572.03,194.15Z"
|
||||||
|
style="fill: var(--color-brand)"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M51.28,316.13C61.87,441.13 166.82,539.43 294.55,539.43C391.06,539.43 474.57,483.31 514.18,401.97L562.79,418.8C516.01,520.14 413.44,590.55 294.55,590.55C138.6,590.55 10.71,469.38 0,316.13L51.28,316.13ZM0.78,265.24C15.86,116.36 141.73,0 294.56,0C457.53,0 589.84,132.31 589.84,295.28C589.84,321.42 586.44,346.77 580.04,370.91L531.56,354.13C536.324,334.876 538.725,315.114 538.71,295.28C538.71,160.53 429.31,51.13 294.56,51.13C169.98,51.13 67.07,144.63 52.24,265.24L0.78,265.24Z"
|
||||||
|
style="fill: var(--color-brand)"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M293.77,153.17C215.28,153.24 151.57,217 151.57,295.51C151.57,374.07 215.36,437.85 293.92,437.85C297.9,437.85 301.85,437.69 305.75,437.36L319.97,487.12C311.335,488.282 302.632,488.864 293.92,488.86C187.2,488.86 100.56,402.22 100.56,295.51C100.56,188.79 187.2,102.16 293.92,102.16C296.56,102.16 299.2,102.21 301.82,102.32L293.77,153.17ZM351.97,111.04C430.36,135.71 487.27,209.02 487.27,295.51C487.27,375.58 438.5,444.34 369.07,473.69L354.9,424.14C402.98,401.29 436.26,352.25 436.26,295.51C436.26,234.52 397.82,182.44 343.87,162.19L351.97,111.04Z"
|
||||||
|
style="fill: var(--color-brand)"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(1.25498,0,0,1.92174,1126.78,-2077.58)">
|
||||||
|
<path
|
||||||
|
d="M411.597,1355.36L411.597,1339.8L410.589,1336.49L410.589,1309.28C410.589,1304 409.005,1299.89 405.837,1296.96C402.669,1294.04 397.869,1292.57 391.437,1292.57C387.117,1292.57 382.869,1293.24 378.693,1294.59C374.517,1295.93 370.989,1297.8 368.109,1300.2L361.053,1287.1C365.181,1283.93 370.101,1281.56 375.813,1279.97C381.525,1278.39 387.453,1277.6 393.597,1277.6C404.733,1277.6 413.349,1280.26 419.445,1285.59C425.541,1290.91 428.589,1299.15 428.589,1310.28L428.589,1355.36L411.597,1355.36ZM387.405,1356.36C381.645,1356.36 376.605,1355.38 372.285,1353.41C367.965,1351.44 364.629,1348.71 362.277,1345.2C359.925,1341.7 358.749,1337.74 358.749,1333.32C358.749,1329 359.781,1325.12 361.845,1321.66C363.909,1318.2 367.293,1315.47 371.997,1313.45C376.701,1311.43 382.941,1310.43 390.717,1310.43L413.037,1310.43L413.037,1322.38L392.013,1322.38C385.869,1322.38 381.741,1323.36 379.629,1325.33C377.517,1327.3 376.461,1329.72 376.461,1332.6C376.461,1335.87 377.757,1338.46 380.349,1340.38C382.941,1342.3 386.541,1343.26 391.149,1343.26C395.565,1343.26 399.525,1342.25 403.029,1340.24C406.533,1338.22 409.053,1335.24 410.589,1331.31L413.613,1342.11C411.885,1346.62 408.789,1350.12 404.325,1352.62C399.861,1355.12 394.221,1356.36 387.405,1356.36Z"
|
||||||
|
style="fill: var(--color-brand); fill-rule: nonzero"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M494.253,1356.36C488.013,1356.36 482.325,1354.92 477.189,1352.04C472.053,1349.16 467.973,1344.82 464.949,1339.01C461.925,1333.2 460.413,1325.84 460.413,1316.91C460.413,1307.88 461.877,1300.49 464.805,1294.73C467.733,1288.97 471.741,1284.67 476.829,1281.84C481.917,1279.01 487.725,1277.6 494.253,1277.6C501.837,1277.6 508.533,1279.23 514.341,1282.49C520.149,1285.76 524.757,1290.32 528.165,1296.17C531.573,1302.03 533.277,1308.94 533.277,1316.91C533.277,1324.88 531.573,1331.81 528.165,1337.71C524.757,1343.62 520.149,1348.2 514.341,1351.47C508.533,1354.73 501.837,1356.36 494.253,1356.36ZM451.629,1383.29L451.629,1278.46L468.765,1278.46L468.765,1296.6L468.189,1317.05L469.629,1337.5L469.629,1383.29L451.629,1383.29ZM492.237,1340.95C496.557,1340.95 500.421,1340 503.829,1338.08C507.237,1336.15 509.949,1333.37 511.965,1329.72C513.981,1326.08 514.989,1321.8 514.989,1316.91C514.989,1311.91 513.981,1307.62 511.965,1304.02C509.949,1300.42 507.237,1297.66 503.829,1295.74C500.421,1293.82 496.557,1292.86 492.237,1292.86C487.917,1292.86 484.029,1293.82 480.573,1295.74C477.117,1297.66 474.381,1300.42 472.365,1304.02C470.349,1307.62 469.341,1311.91 469.341,1316.91C469.341,1321.8 470.349,1326.08 472.365,1329.72C474.381,1333.37 477.117,1336.15 480.573,1338.08C484.029,1340 487.917,1340.95 492.237,1340.95Z"
|
||||||
|
style="fill: var(--color-brand); fill-rule: nonzero"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M593.037,1356.36C586.797,1356.36 581.109,1354.92 575.973,1352.04C570.837,1349.16 566.757,1344.82 563.733,1339.01C560.709,1333.2 559.197,1325.84 559.197,1316.91C559.197,1307.88 560.661,1300.49 563.589,1294.73C566.517,1288.97 570.525,1284.67 575.613,1281.84C580.701,1279.01 586.509,1277.6 593.037,1277.6C600.621,1277.6 607.317,1279.23 613.125,1282.49C618.933,1285.76 623.541,1290.32 626.949,1296.17C630.357,1302.03 632.061,1308.94 632.061,1316.91C632.061,1324.88 630.357,1331.81 626.949,1337.71C623.541,1343.62 618.933,1348.2 613.125,1351.47C607.317,1354.73 600.621,1356.36 593.037,1356.36ZM550.413,1383.29L550.413,1278.46L567.549,1278.46L567.549,1296.6L566.973,1317.05L568.413,1337.5L568.413,1383.29L550.413,1383.29ZM591.021,1340.95C595.341,1340.95 599.205,1340 602.613,1338.08C606.021,1336.15 608.733,1333.37 610.749,1329.72C612.765,1326.08 613.773,1321.8 613.773,1316.91C613.773,1311.91 612.765,1307.62 610.749,1304.02C608.733,1300.42 606.021,1297.66 602.613,1295.74C599.205,1293.82 595.341,1292.86 591.021,1292.86C586.701,1292.86 582.813,1293.82 579.357,1295.74C575.901,1297.66 573.165,1300.42 571.149,1304.02C569.133,1307.62 568.125,1311.91 568.125,1316.91C568.125,1321.8 569.133,1326.08 571.149,1329.72C573.165,1333.37 575.901,1336.15 579.357,1338.08C582.813,1340 586.701,1340.95 591.021,1340.95Z"
|
||||||
|
style="fill: var(--color-brand); fill-rule: nonzero"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<ProgressBar class="loading-bar" :progress="loadingProgress" />
|
||||||
|
<span v-if="message">{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="gradient-bg" data-tauri-drag-region></div>
|
||||||
|
<div class="cube-bg"></div>
|
||||||
|
<div class="base-bg"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||||
|
import { loading_listener } from '@/helpers/events.js'
|
||||||
|
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||||
|
import { XIcon } from '@modrinth/assets'
|
||||||
|
import { MaximizeIcon, MinimizeIcon } from '@/assets/icons/index.js'
|
||||||
|
import { getOS } from '@/helpers/utils.js'
|
||||||
|
import { useLoading } from '@/store/loading.js'
|
||||||
|
|
||||||
|
const doneLoading = ref(false)
|
||||||
|
const loadingProgress = ref(0)
|
||||||
|
const hidden = ref(false)
|
||||||
|
const message = ref()
|
||||||
|
|
||||||
|
const loading = useLoading()
|
||||||
|
|
||||||
|
watch(loading, (newValue) => {
|
||||||
|
if (!newValue.barEnabled) {
|
||||||
|
if (loading.loading) {
|
||||||
|
loadingProgress.value = 0
|
||||||
|
fakeLoadingIncrease()
|
||||||
|
} else {
|
||||||
|
loadingProgress.value = 100
|
||||||
|
doneLoading.value = true
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
hidden.value = true
|
||||||
|
loading.setEnabled(true)
|
||||||
|
}, 250)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function fakeLoadingIncrease() {
|
||||||
|
if (loadingProgress.value < 95) {
|
||||||
|
setTimeout(() => {
|
||||||
|
loadingProgress.value += 1
|
||||||
|
fakeLoadingIncrease()
|
||||||
|
}, 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const os = ref('')
|
||||||
|
getOS().then((x) => (os.value = x))
|
||||||
|
|
||||||
|
loading_listener(async (e) => {
|
||||||
|
console.log(e)
|
||||||
|
if (e.event.type === 'directory_move') {
|
||||||
|
loadingProgress.value = 100 * (e.fraction ?? 1)
|
||||||
|
message.value = 'Updating app directory...'
|
||||||
|
} else if (e.event.type === 'launcher_update') {
|
||||||
|
loadingProgress.value = 100 * (e.fraction ?? 1)
|
||||||
|
message.value = 'Updating Modrinth App...'
|
||||||
|
} else if (e.event.type === 'checking_for_updates') {
|
||||||
|
loadingProgress.value = 100 * (e.fraction ?? 1)
|
||||||
|
message.value = 'Checking for updates...'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleClose = async () => {
|
||||||
|
await getCurrentWindow().close()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.splash-screen {
|
||||||
|
transition: opacity 0.25s ease-in-out;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
&.fade-out {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-buttons {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-logo-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
z-index: 9998;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-logo {
|
||||||
|
height: 2.25rem;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar {
|
||||||
|
max-width: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gradient-bg {
|
||||||
|
position: absolute;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
background: linear-gradient(180deg, rgba(66, 131, 92, 0.275) 0%, rgba(17, 35, 43, 0.5) 97.29%),
|
||||||
|
linear-gradient(0deg, rgba(22, 24, 28, 0.64), rgba(22, 24, 28, 0.64));
|
||||||
|
z-index: 9997;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cube-bg {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
width: 180vw;
|
||||||
|
height: 180vh;
|
||||||
|
opacity: 0.8;
|
||||||
|
background: #16181c url('@/assets/loading/cube.png') center no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
|
||||||
|
z-index: 9996;
|
||||||
|
}
|
||||||
|
|
||||||
|
.base-bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: var(--color-bg);
|
||||||
|
z-index: 9995;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+15
-50
@@ -1,82 +1,48 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Modal, Button } from 'omorphia'
|
import { Button } from '@modrinth/ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useFetch } from '@/helpers/fetch.js'
|
|
||||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||||
import { get_categories } from '@/helpers/tags.js'
|
import { get_categories } from '@/helpers/tags.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { install as packInstall } from '@/helpers/pack.js'
|
import { get_version, get_project } from '@/helpers/cache.js'
|
||||||
import mixpanel from 'mixpanel-browser'
|
import { install as installVersion } from '@/store/install.js'
|
||||||
import ModInstallModal from '@/components/ui/ModInstallModal.vue'
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const confirmModal = ref(null)
|
const confirmModal = ref(null)
|
||||||
const project = ref(null)
|
const project = ref(null)
|
||||||
const version = ref(null)
|
const version = ref(null)
|
||||||
const categories = ref(null)
|
const categories = ref(null)
|
||||||
const installing = ref(false)
|
const installing = ref(false)
|
||||||
const modInstallModal = ref(null)
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
async show(event) {
|
async show(event) {
|
||||||
if (event.event === 'InstallVersion') {
|
if (event.event === 'InstallVersion') {
|
||||||
version.value = await useFetch(
|
version.value = await get_version(event.id, 'must_revalidate').catch(handleError)
|
||||||
`https://api.modrinth.com/v2/version/${encodeURIComponent(event.id)}`,
|
project.value = await get_project(version.value.project_id, 'must_revalidate').catch(
|
||||||
'version',
|
handleError,
|
||||||
)
|
|
||||||
project.value = await useFetch(
|
|
||||||
`https://api.modrinth.com/v2/project/${encodeURIComponent(version.value.project_id)}`,
|
|
||||||
'project',
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
project.value = await useFetch(
|
project.value = await get_project(event.id, 'must_revalidate').catch(handleError)
|
||||||
`https://api.modrinth.com/v2/project/${encodeURIComponent(event.id)}`,
|
version.value = await get_version(
|
||||||
'project',
|
project.value.versions[project.value.versions.length - 1],
|
||||||
)
|
'must_revalidate',
|
||||||
version.value = await useFetch(
|
).catch(handleError)
|
||||||
`https://api.modrinth.com/v2/version/${encodeURIComponent(project.value.versions[0])}`,
|
|
||||||
'version',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
categories.value = (await get_categories().catch(handleError)).filter(
|
categories.value = (await get_categories().catch(handleError)).filter(
|
||||||
(cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod',
|
(cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod',
|
||||||
)
|
)
|
||||||
confirmModal.value.show()
|
confirmModal.value.show()
|
||||||
categories.value = (await get_categories().catch(handleError)).filter(
|
|
||||||
(cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod',
|
|
||||||
)
|
|
||||||
confirmModal.value.show()
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
async function install() {
|
async function install() {
|
||||||
confirmModal.value.hide()
|
confirmModal.value.hide()
|
||||||
if (project.value.project_type === 'modpack') {
|
await installVersion(project.value.id, version.value.id, null, 'URLConfirmModal')
|
||||||
await packInstall(
|
|
||||||
project.value.id,
|
|
||||||
version.value.id,
|
|
||||||
project.value.title,
|
|
||||||
project.value.icon_url,
|
|
||||||
).catch(handleError)
|
|
||||||
|
|
||||||
mixpanel.track('PackInstall', {
|
|
||||||
id: project.value.id,
|
|
||||||
version_id: version.value.id,
|
|
||||||
title: project.value.title,
|
|
||||||
source: 'ProjectPage',
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
modInstallModal.value.show(
|
|
||||||
project.value.id,
|
|
||||||
[version.value],
|
|
||||||
project.value.title,
|
|
||||||
project.value.project_type,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="confirmModal" :header="`Install ${project?.title}`">
|
<ModalWrapper ref="confirmModal" :header="`Install ${project?.title}`">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<SearchCard
|
<SearchCard
|
||||||
:project="project"
|
:project="project"
|
||||||
@@ -95,8 +61,7 @@ async function install() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
<ModInstallModal ref="modInstallModal" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
+26
-40
@@ -1,9 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal
|
<ModalWrapper ref="incompatibleModal" header="Incompatibility warning" :on-hide="onInstall">
|
||||||
ref="incompatibleModal"
|
|
||||||
header="Incompatibility warning"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
>
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>
|
<p>
|
||||||
This {{ versions?.length > 0 ? 'project' : 'version' }} is not compatible with the instance
|
This {{ versions?.length > 0 ? 'project' : 'version' }} is not compatible with the instance
|
||||||
@@ -12,13 +8,11 @@
|
|||||||
</p>
|
</p>
|
||||||
<table>
|
<table>
|
||||||
<tr class="header">
|
<tr class="header">
|
||||||
<th>{{ instance?.metadata.name }}</th>
|
<th>{{ instance?.name }}</th>
|
||||||
<th>{{ projectTitle }}</th>
|
<th>{{ project.title }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="content">
|
<tr class="content">
|
||||||
<td class="data">
|
<td class="data">{{ instance?.loader }} {{ instance?.game_version }}</td>
|
||||||
{{ instance?.metadata.loader }} {{ instance?.metadata.game_version }}
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<DropdownSelect
|
<DropdownSelect
|
||||||
v-if="versions?.length > 1"
|
v-if="versions?.length > 1"
|
||||||
@@ -52,50 +46,42 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Modal, XIcon, DownloadIcon, DropdownSelect, formatCategory } from 'omorphia'
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
||||||
|
import { Button, DropdownSelect } from '@modrinth/ui'
|
||||||
|
import { formatCategory } from '@modrinth/utils'
|
||||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { handleError, useTheming } from '@/store/state.js'
|
import { handleError } from '@/store/state.js'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const instance = ref(null)
|
const instance = ref(null)
|
||||||
const project = ref(null)
|
const project = ref(null)
|
||||||
const projectType = ref(null)
|
|
||||||
const projectTitle = ref(null)
|
|
||||||
const versions = ref(null)
|
const versions = ref(null)
|
||||||
const selectedVersion = ref(null)
|
const selectedVersion = ref(null)
|
||||||
const incompatibleModal = ref(null)
|
const incompatibleModal = ref(null)
|
||||||
const installing = ref(false)
|
const installing = ref(false)
|
||||||
|
|
||||||
let markInstalled = () => {}
|
const onInstall = ref(() => {})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
show: (
|
show: (instanceVal, projectVal, projectVersions, callback) => {
|
||||||
instanceVal,
|
|
||||||
projectTitleVal,
|
|
||||||
selectedVersions,
|
|
||||||
extMarkInstalled,
|
|
||||||
projectIdVal,
|
|
||||||
projectTypeVal,
|
|
||||||
) => {
|
|
||||||
instance.value = instanceVal
|
instance.value = instanceVal
|
||||||
projectTitle.value = projectTitleVal
|
versions.value = projectVersions
|
||||||
versions.value = selectedVersions
|
selectedVersion.value = projectVersions[0]
|
||||||
selectedVersion.value = selectedVersions[0]
|
|
||||||
|
|
||||||
project.value = projectIdVal
|
project.value = projectVal
|
||||||
projectType.value = projectTypeVal
|
|
||||||
|
onInstall.value = callback
|
||||||
|
installing.value = false
|
||||||
|
|
||||||
incompatibleModal.value.show()
|
incompatibleModal.value.show()
|
||||||
markInstalled = extMarkInstalled
|
|
||||||
|
|
||||||
mixpanel_track('ProjectInstallStart', { source: 'ProjectIncompatibilityWarningModal' })
|
trackEvent('ProjectInstallStart', { source: 'ProjectIncompatibilityWarningModal' })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -103,16 +89,16 @@ const install = async () => {
|
|||||||
installing.value = true
|
installing.value = true
|
||||||
await installMod(instance.value.path, selectedVersion.value.id).catch(handleError)
|
await installMod(instance.value.path, selectedVersion.value.id).catch(handleError)
|
||||||
installing.value = false
|
installing.value = false
|
||||||
markInstalled()
|
onInstall.value(selectedVersion.value.id)
|
||||||
incompatibleModal.value.hide()
|
incompatibleModal.value.hide()
|
||||||
|
|
||||||
mixpanel_track('ProjectInstall', {
|
trackEvent('ProjectInstall', {
|
||||||
loader: instance.value.metadata.loader,
|
loader: instance.value.loader,
|
||||||
game_version: instance.value.metadata.game_version,
|
game_version: instance.value.game_version,
|
||||||
id: project.value,
|
id: project.value,
|
||||||
version_id: selectedVersion.value.id,
|
version_id: selectedVersion.value.id,
|
||||||
project_type: projectType.value,
|
project_type: project.value.project_type,
|
||||||
title: projectTitle.value,
|
title: project.value.title,
|
||||||
source: 'ProjectIncompatibilityWarningModal',
|
source: 'ProjectIncompatibilityWarningModal',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
+28
-26
@@ -1,54 +1,56 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Modal, XIcon, DownloadIcon } from 'omorphia'
|
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
||||||
|
import { Button } from '@modrinth/ui'
|
||||||
import { install as pack_install } from '@/helpers/pack'
|
import { install as pack_install } from '@/helpers/pack'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { handleError } from '@/store/state.js'
|
import { handleError } from '@/store/state.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
const versionId = ref()
|
||||||
|
const project = ref()
|
||||||
const version = ref('')
|
|
||||||
const title = ref('')
|
|
||||||
const projectId = ref('')
|
|
||||||
const icon = ref('')
|
|
||||||
const confirmModal = ref(null)
|
const confirmModal = ref(null)
|
||||||
const installing = ref(false)
|
const installing = ref(false)
|
||||||
|
|
||||||
|
const onInstall = ref(() => {})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
show: (projectIdVal, versionId, projectTitle, projectIcon) => {
|
show: (projectVal, versionIdVal, callback) => {
|
||||||
projectId.value = projectIdVal
|
project.value = projectVal
|
||||||
version.value = versionId
|
versionId.value = versionIdVal
|
||||||
title.value = projectTitle
|
|
||||||
icon.value = projectIcon
|
|
||||||
installing.value = false
|
installing.value = false
|
||||||
confirmModal.value.show()
|
confirmModal.value.show()
|
||||||
|
|
||||||
mixpanel_track('PackInstallStart')
|
onInstall.value = callback
|
||||||
|
|
||||||
|
trackEvent('PackInstallStart')
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
async function install() {
|
async function install() {
|
||||||
installing.value = true
|
installing.value = true
|
||||||
console.log(`Installing ${projectId.value} ${version.value} ${title.value} ${icon.value}`)
|
|
||||||
confirmModal.value.hide()
|
confirmModal.value.hide()
|
||||||
|
|
||||||
await pack_install(
|
await pack_install(
|
||||||
projectId.value,
|
project.value.id,
|
||||||
version.value,
|
versionId.value,
|
||||||
title.value,
|
project.value.title,
|
||||||
icon.value ? icon.value : null,
|
project.value.icon_url,
|
||||||
).catch(handleError)
|
).catch(handleError)
|
||||||
mixpanel_track('PackInstall', {
|
trackEvent('PackInstall', {
|
||||||
id: projectId.value,
|
id: project.value.id,
|
||||||
version_id: version.value,
|
version_id: versionId.value,
|
||||||
title: title.value,
|
title: project.value.title,
|
||||||
source: 'ConfirmModal',
|
source: 'ConfirmModal',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onInstall.value(versionId.value)
|
||||||
|
installing.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="confirmModal" header="Are you sure?" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="confirmModal" header="Are you sure?" :on-hide="onInstall">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>You already have this modpack installed. Are you sure you want to install it again?</p>
|
<p>You already have this modpack installed. Are you sure you want to install it again?</p>
|
||||||
<div class="input-group push-right">
|
<div class="input-group push-right">
|
||||||
@@ -58,7 +60,7 @@ async function install() {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
Loaded 100 of 1852 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user