Compare commits
744 commits
main
...
immediate-
Author | SHA1 | Date | |
---|---|---|---|
7fcd9c3f06 | |||
8bfacc139a | |||
a9a8c338a6 | |||
262319a97c | |||
0379beb0ba | |||
13ada86934 | |||
fae5f9bfab | |||
7d4fc5e8e1 | |||
26a71caced | |||
b1ad0a0d58 | |||
4a9f258e34 | |||
301b0e7dfc | |||
2f806dde95 | |||
30ef53403b | |||
ade9a523ac | |||
464dddff13 | |||
e8965866e6 | |||
e3d9b2001f | |||
e4bc7f2add | |||
edc87ac75e | |||
5c7773c7bb | |||
3546632bbf | |||
9a48454a9f | |||
0e2c0b9bfb | |||
84c78a4262 | |||
cfbe4affc0 | |||
e8f017b15e | |||
22a81ab142 | |||
93d450a600 | |||
50bb6d867b | |||
6cc2f53501 | |||
f9776ce1ae | |||
18c5ca216c | |||
3f0d915c75 | |||
a8f77a12df | |||
44785d3498 | |||
473109b1d9 | |||
f398a1c871 | |||
9871e16e28 | |||
b22d4622ed | |||
f05d462a73 | |||
c183018fb1 | |||
f9c11a1149 | |||
45a876a0d5 | |||
4d88a13f5e | |||
eeb4d26812 | |||
2429c283aa | |||
1f1e3e8456 | |||
64e1f294e6 | |||
e801c71fdf | |||
4677ac779a | |||
ed32b7964d | |||
76f8b0e38e | |||
e24bdc2b6f | |||
4bcefb744d | |||
4d03a695aa | |||
ca3768ca5d | |||
6bdd0ba4a9 | |||
633a84581d | |||
4a590d3d0a | |||
1905aa0ae8 | |||
026e716710 | |||
9e6f24cc92 | |||
75a8098590 | |||
1f20074d4e | |||
fb394c6e1a | |||
465dd15e2c | |||
f676613173 | |||
be6209ee44 | |||
15a3694533 | |||
9fd16825e2 | |||
129b770ffa | |||
42353373db | |||
5f7c44f478 | |||
2df13a2e17 | |||
dc116fc3b1 | |||
cd3534f6fc | |||
01bd41413d | |||
654a271eae | |||
efd48e0364 | |||
09447d562e | |||
e57c99399d | |||
a3612dd4ee | |||
e9328cadea | |||
8fa19656ae | |||
d58d8aea71 | |||
5462bb1438 | |||
9dadde6884 | |||
81a1822e70 | |||
974953ba01 | |||
27fd143318 | |||
3bc71c688a | |||
d869b2ddbb | |||
fb3ae98419 | |||
70df451e64 | |||
2fb616ebf1 | |||
bd25e0cd75 | |||
62d4add6c1 | |||
3f5491d379 | |||
e35d0f680f | |||
187ece1905 | |||
2b99f4ece3 | |||
8bf98be472 | |||
0506505449 | |||
3edc36d5e0 | |||
6ffa969955 | |||
6213fca9ed | |||
56477d4e96 | |||
104f193a76 | |||
293b90a6d2 | |||
8159937827 | |||
aa35602827 | |||
42c4845261 | |||
710f627016 | |||
4389b78410 | |||
fde823fabf | |||
cce8f14d72 | |||
c8356570a3 | |||
021baa54d3 | |||
ddd5d9e0c3 | |||
920fb20d8e | |||
438b3e0598 | |||
763b24aa92 | |||
65013f0149 | |||
24795ba9f8 | |||
aa29e479b9 | |||
dd25044afd | |||
8c1979481e | |||
2a1684d902 | |||
b377cad1e6 | |||
4e09e347e2 | |||
ea6fccb54e | |||
c784bc5dbd | |||
edba931afe | |||
208882e8ec | |||
e0cb7242d6 | |||
b3ab32180c | |||
2506ba1b2e | |||
0d0c63f596 | |||
8abb68c553 | |||
f6147c6c13 | |||
b5fdb43cbf | |||
30057985c4 | |||
a95037d80a | |||
99e21ad284 | |||
d90bcdb063 | |||
771d51bcc3 | |||
c7e49672f5 | |||
3331ed2155 | |||
bc34d72b57 | |||
b333deb731 | |||
614cbc1146 | |||
a985286c88 | |||
1297408171 | |||
cc536bdbf4 | |||
ea859f59b0 | |||
a04ccd0d11 | |||
c1b4eb5b04 | |||
3f059e17be | |||
48442aee1d | |||
9ca13d1250 | |||
2c3be4533e | |||
7bf2152353 | |||
a6f4622837 | |||
2f55c7b126 | |||
14d1a2d1ea | |||
332f3e532b | |||
28a7fbb309 | |||
4caf86b60e | |||
5a85d6e78e | |||
20cfa932a4 | |||
9e998db456 | |||
3d4a7638a4 | |||
ab8da19e23 | |||
b8335108e4 | |||
403276d307 | |||
748a456cfb | |||
0cd0c813f2 | |||
f647ff0ee9 | |||
c2d708a621 | |||
35343bd790 | |||
cc5d4a7b3a | |||
ae655111de | |||
b768c61ef8 | |||
d95367b31d | |||
1e4ad4db4c | |||
d8ba959d1e | |||
0742cecd41 | |||
ed4a797ad3 | |||
505246954b | |||
eecc21db91 | |||
962eaa9df7 | |||
0190ada1a1 | |||
b5a1b3a124 | |||
1f3b8cdfd8 | |||
1f2c26cdba | |||
3b6bef1cda | |||
858b0e3dd7 | |||
718ebd56ac | |||
1511260666 | |||
4ff7c22505 | |||
057ccfde11 | |||
edf4e75ae2 | |||
62d9d1310d | |||
e592a50d7c | |||
c785053b86 | |||
e9081d2a52 | |||
98c67e1165 | |||
6c7d4259e1 | |||
d8e3381fb3 | |||
bdb9c75c74 | |||
a67b7847b1 | |||
bab081d4a9 | |||
0e5099416c | |||
20efa661b0 | |||
94ba593be9 | |||
c9295d3a85 | |||
d55770797a | |||
b4b67a98da | |||
453c0b62f4 | |||
a3fa74735f | |||
a3cab94a68 | |||
c4e7233604 | |||
889eb311f9 | |||
03120d5a98 | |||
9446efadd5 | |||
9c21c23364 | |||
ba6d3c7e60 | |||
cb1fff8d86 | |||
c400db41c3 | |||
de4743828a | |||
700a442ee4 | |||
dd3904badd | |||
0d360fb7e7 | |||
2429231965 | |||
570137040c | |||
ad3bb91bc1 | |||
161be30b2b | |||
0a4bcd5ccd | |||
3a5859b815 | |||
1ea5f56549 | |||
a7b02f2f1f | |||
32306cc6c3 | |||
8cfb289dc7 | |||
220062acdb | |||
e5d5bc2d34 | |||
17cc81f15d | |||
eba42489e9 | |||
51dee70ced | |||
11561e50f9 | |||
2095cc8d03 | |||
6e61ef297c | |||
58e810dfbe | |||
b2497373f0 | |||
18841f4551 | |||
da6ceb8479 | |||
6b811dce55 | |||
8982a53b47 | |||
3cf702a2ba | |||
cd79150a84 | |||
343e2802c3 | |||
dc8b579488 | |||
066001c57a | |||
24a0f62801 | |||
ef512e6ea1 | |||
c6b2eeb86d | |||
e457e58b49 | |||
cac0398276 | |||
e93562b95b | |||
f6dbcb7709 | |||
a82a0636cf | |||
2fc814124f | |||
a43d5d595a | |||
ceaaf9ab8a | |||
a01ee40591 | |||
26c2674652 | |||
9595f75a9a | |||
2189ce407b | |||
7b4f97fa08 | |||
f208472841 | |||
4e4a9f806f | |||
afe6d9f7b3 | |||
2dac66d7c6 | |||
83b09a8073 | |||
13d47d91bf | |||
004f764c2b | |||
a815122e3c | |||
b88e7faa72 | |||
bb22355a57 | |||
591f433135 | |||
f726376ab8 | |||
74bd89b721 | |||
aa4c6e5496 | |||
e8d696c18c | |||
d473d52047 | |||
36c8058920 | |||
8d31f3cf62 | |||
5021d2e344 | |||
92653eaf96 | |||
2f6e39c0bd | |||
5e52ecf42e | |||
b2ae33344b | |||
b24e8cb9e6 | |||
73b1c7b811 | |||
210fada19a | |||
002a1cfc16 | |||
e9e25306eb | |||
5931a72de2 | |||
3d0ce5449d | |||
31c39bc761 | |||
1d2b8a43c0 | |||
6d587e6530 | |||
853585c0bc | |||
6826fe003c | |||
c3bbc92fa2 | |||
ed35c496dc | |||
dc8ac98a6e | |||
337850c33a | |||
08f1b6a3c9 | |||
c8ad68c80b | |||
7b056364da | |||
7f3cad2528 | |||
5d290ecd35 | |||
b702b31744 | |||
3dbe621059 | |||
55195676b8 | |||
76cb49c381 | |||
95c4cc09af | |||
a5b30e762a | |||
5bbf467be0 | |||
46c771f351 | |||
94ea4f8e5c | |||
fc8a0e4904 | |||
9eb77cb7fd | |||
e1bbd67a9a | |||
625b248a95 | |||
94c365b1c3 | |||
f70e9290ce | |||
57b011aea7 | |||
c8097f0f1a | |||
5999af76c6 | |||
05717d6bc3 | |||
53dd86fa6e | |||
363f2e84fb | |||
066ce07512 | |||
f5b1b65db8 | |||
6e6ee4db68 | |||
ac1c417e1c | |||
4e14232b5a | |||
eddfca06ab | |||
61e1eada01 | |||
85322f9e90 | |||
d329d74fec | |||
ac6a21374f | |||
b385be51d6 | |||
d8524b087c | |||
c491122937 | |||
13337950dc | |||
281ab9194b | |||
a1881bff3d | |||
c50208b019 | |||
a8974f01eb | |||
b79a0dadcb | |||
c4c92ed366 | |||
78fd37a4c6 | |||
9de6e67cf1 | |||
33d5753ca7 | |||
8d3feef9a1 | |||
8580332c82 | |||
4d8c56689c | |||
5cbb816c1c | |||
b6594051d9 | |||
50415a949d | |||
4b03454bce | |||
f1b649e996 | |||
db5397f41a | |||
c34f40e30d | |||
dd4d80872e | |||
eb381767cd | |||
0aff3c29bc | |||
e7fdb3881a | |||
5977ff8f6b | |||
dd13b96728 | |||
01fdeb7292 | |||
6a3831c437 | |||
c485864ee8 | |||
2ab7d3209e | |||
654b2e8398 | |||
3f573c9af3 | |||
cbd9a9312c | |||
2656b60347 | |||
fbb7ee50dd | |||
4187932aa7 | |||
a19fb71c70 | |||
e21a6be4b6 | |||
b53c78c2ba | |||
db63fffe18 | |||
41ab8da5ad | |||
f68effc7e2 | |||
f21bfb9d78 | |||
f4cc95da5a | |||
3a32490937 | |||
545d69aa6d | |||
aa5ca42676 | |||
5197170b3d | |||
47eec049fc | |||
022a0497c3 | |||
e2f936538e | |||
b323fbb486 | |||
0c4e265530 | |||
111a4f2aa8 | |||
46710bf8cb | |||
1f938211a8 | |||
8d362fc394 | |||
79849fd37d | |||
a838d587ae | |||
3a25da5f14 | |||
a1e72e78d7 | |||
48fb6ecd1a | |||
3c62e393a3 | |||
034ef554fb | |||
2da9bf8f0e | |||
eb5fb0df29 | |||
479a4069b2 | |||
e22575805b | |||
c0984db612 | |||
9a9c1b0487 | |||
072619e539 | |||
9084459933 | |||
36f9eda3a8 | |||
99160638df | |||
2574d5311d | |||
7816727e26 | |||
892de53603 | |||
8de1ca86a9 | |||
01ba87cd76 | |||
83222631ab | |||
b74581908e | |||
896b8970b6 | |||
c8602ef52b | |||
ac1423f90c | |||
d0e4ec0ad5 | |||
7509f203cc | |||
17b575070f | |||
4a872236e1 | |||
d5440349c9 | |||
0f9b5f2d09 | |||
4db6c4b88a | |||
6e1094a5d1 | |||
15df3485d1 | |||
ea86df7174 | |||
66c466c9f0 | |||
96d5e1b89b | |||
4b4caa798a | |||
73503945fb | |||
43b679d676 | |||
011b375d02 | |||
9f1f2b15a4 | |||
a1309ea897 | |||
a4073703fd | |||
84b9e3fec1 | |||
6bbd91fafc | |||
d78f1c8000 | |||
64262001e8 | |||
6b648f3d38 | |||
1eeadbcd97 | |||
f016d277b7 | |||
9c2545ab16 | |||
b36d3b4385 | |||
acbc932542 | |||
3590d5abff | |||
c9c09b95a3 | |||
9128eb5760 | |||
513d9f4209 | |||
06393211b1 | |||
ac3130d37e | |||
3e2952890f | |||
a0751a0f84 | |||
fa45beb8ca | |||
539b70cd52 | |||
e96458fafa | |||
a1542bcec5 | |||
e00da485e8 | |||
513eea8d14 | |||
490e9131b5 | |||
9ceb0ae7cb | |||
6d59a943da | |||
00d71fbeab | |||
4459d11a97 | |||
1eab0146dd | |||
f345484e5b | |||
65adaf335c | |||
437e4eae44 | |||
f7d12d209c | |||
8a5678bec5 | |||
1f99162b5a | |||
8c5f2c897e | |||
9ada9bc1a9 | |||
8fd22f6deb | |||
c1e78b4397 | |||
32a2c90761 | |||
dae3841f10 | |||
4d27643d39 | |||
c2047e5f3b | |||
18142ecccb | |||
440cb1f29c | |||
64b1ab1112 | |||
3da88100df | |||
3e3201ad0d | |||
a2bda05211 | |||
1ed956114f | |||
2e27a513ac | |||
a8fa685cfa | |||
b2036762b5 | |||
067a16c9dc | |||
265cf12d39 | |||
b580d6dcfb | |||
affd527bc1 | |||
7d928e53aa | |||
b10afebc98 | |||
1a8a901e0a | |||
d936604f35 | |||
4dcc265be0 | |||
3e6e399544 | |||
9af63b362d | |||
090a3bc0a8 | |||
3331723496 | |||
999d6c812f | |||
c9c1e0c6c5 | |||
1e55ae5327 | |||
5b96881177 | |||
daa1a35fc3 | |||
ef895e787a | |||
2f16cdf77b | |||
e990795783 | |||
8dde496757 | |||
35f950c6e3 | |||
5fbabb0b70 | |||
ff9cc2e9e5 | |||
3793acd9bb | |||
ebae259f5d | |||
3296ee1c4b | |||
2f87363b89 | |||
bacf021a28 | |||
1138e22f58 | |||
d6b5bc58ce | |||
bd2264c125 | |||
86f69e84c1 | |||
488f133a90 | |||
77d8e70059 | |||
f64b228cb9 | |||
90f37471e5 | |||
b192c89146 | |||
ae10d3667c | |||
f727d101fc | |||
9bbec66ea5 | |||
0146789514 | |||
b38ab066d9 | |||
37514e0720 | |||
aa9be97f83 | |||
d8c6559967 | |||
72b014fe67 | |||
8eb4eab2b0 | |||
07361ff6fe | |||
64212512ca | |||
5e762ddd04 | |||
74f36a093b | |||
c01a8c2f78 | |||
90c26432f5 | |||
6f25005057 | |||
23c8818ed2 | |||
16d05c8935 | |||
c5541d297d | |||
a120b35f4f | |||
9740d28530 | |||
8e9434cdd5 | |||
f5be78d101 | |||
bd95cc449f | |||
bdd4b0f143 | |||
a60c8374ed | |||
1013c34840 | |||
7b7b87316d | |||
6567ff7435 | |||
22a75c4589 | |||
67b5ecca51 | |||
cdbd9ad101 | |||
1e96638219 | |||
7371abbaec | |||
cfb493c593 | |||
ac61a0377f | |||
bb3f629672 | |||
3ab68f9296 | |||
01a4ac9c13 | |||
66e1db1fdb | |||
688449ed62 | |||
5ca4e58fad | |||
deb0f7b9c6 | |||
40a1f48267 | |||
bc367b1d2a | |||
f6a7cdc430 | |||
d5bcbf54f9 | |||
4b2734610f | |||
c4645f79c6 | |||
cf9bbfc78f | |||
6cc40eb095 | |||
95acb147d1 | |||
21fea87551 | |||
2a2124c5a0 | |||
1a1e5c2e1d | |||
c9d9d53fb1 | |||
dc81d1c14c | |||
b938bdf138 | |||
e74aabb988 | |||
ab24ce08e3 | |||
c2435bb9dd | |||
d678e68899 | |||
dbb6f4165b | |||
9a1a7b374f | |||
ec373069b3 | |||
329bc68bf5 | |||
2a77941dff | |||
d36c361b47 | |||
b17963169f | |||
118361723c | |||
97e2e2c1c8 | |||
dbee2d9ecc | |||
1283494b46 | |||
e72c732d58 | |||
d40dfc345f | |||
70f60193b0 | |||
9e60d4979d | |||
3562c8ae11 | |||
093de43d54 | |||
86ad3bd4fc | |||
8045d65e99 | |||
63a1fe2c70 | |||
55760bc42b | |||
983013446d | |||
569dace244 | |||
8e5a2f6e59 | |||
41a1732df2 | |||
487af1c789 | |||
5168f326a3 | |||
4feaa40de7 | |||
7f5aaada88 | |||
725103a77c | |||
a878ea0b39 | |||
0cc89996c6 | |||
c72099fc39 | |||
84c223d471 | |||
82f9e36e5a | |||
7c8c2ff5b8 | |||
dc73b89b29 | |||
2596bf0990 | |||
7169dfe61a | |||
5ba5eca1a1 | |||
4209bfd3aa | |||
c007fc7478 | |||
903fa2cf11 | |||
7d91dea822 | |||
4fc4f1cb75 | |||
45d2cf49e0 | |||
b798f31669 | |||
7e1524362c | |||
e04dd85957 | |||
258e1efdce | |||
f6e484034c | |||
5676f45781 | |||
e11d651e33 | |||
09a6a9bf85 | |||
1b64419ef1 | |||
5edff4a3c5 | |||
b043d8abb7 | |||
e15868d499 | |||
a892a507be | |||
33a5f30ae4 | |||
38b6c7fa6c | |||
bd88625d25 | |||
5fca61f581 | |||
cc6cef02c1 | |||
546c5105b2 | |||
f65749e2d4 | |||
fb8f00137c | |||
20b071aa2d | |||
b7c1b495af | |||
4d80c53dd0 | |||
035e2add0b | |||
f70cc5205c | |||
fa948e8639 | |||
4cc6789b5b | |||
4753efa33c | |||
283a4b23ba | |||
3b7f1be9a2 | |||
c2e12e2827 | |||
8b6620ca2f | |||
f1e2d5572a | |||
49fcfd74df | |||
511ec1b129 | |||
94843a77ac | |||
8873391496 | |||
b77b654df1 | |||
c65e1f88d2 | |||
9cd20e3cea | |||
f04bd8a7ad | |||
fa82939e62 | |||
a1fefcf27a | |||
65b6440024 | |||
6e0064c5fc | |||
b047f9ce28 | |||
d97596a16a | |||
5b6d0f42fd | |||
4a89fadedd | |||
886071af4d | |||
12c9c324a1 | |||
e311bd9f76 | |||
707c23b188 | |||
49e78793c5 | |||
8d31330d3e | |||
17397dbe08 | |||
b98544ed1f | |||
043675f3f8 | |||
3b1cb02663 | |||
bc68bc0312 | |||
b3819228ed | |||
c23c65733b | |||
cfefdbc7a7 | |||
70103e8111 | |||
240705652c | |||
d42c9547ab | |||
ac85b3508b | |||
9ece4dddd3 | |||
36f5d9acc6 | |||
d4956f3ec7 | |||
8279c8d0ba | |||
74e3ba42e0 | |||
784ae0a02d | |||
901d803ba9 | |||
bdb693302a | |||
f8a7d1d634 | |||
770078f236 | |||
f1dd39885b | |||
a29115ba78 | |||
cd5e0aeec1 | |||
75fa0ff708 |
|
@ -90,7 +90,13 @@ export default tseslint.config(
|
||||||
"no-invalid-regexp": "error",
|
"no-invalid-regexp": "error",
|
||||||
"no-constant-condition": ["error", { "checkLoops": false }],
|
"no-constant-condition": ["error", { "checkLoops": false }],
|
||||||
"no-duplicate-imports": "error",
|
"no-duplicate-imports": "error",
|
||||||
"dot-notation": "error",
|
"@typescript-eslint/dot-notation": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"allowPrivateClassPropertyAccess": true,
|
||||||
|
"allowProtectedClassPropertyAccess": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"no-useless-escape": [
|
"no-useless-escape": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
|
|
|
@ -312,7 +312,7 @@ export const commonOpts = {
|
||||||
logLevel: "info",
|
logLevel: "info",
|
||||||
bundle: true,
|
bundle: true,
|
||||||
watch,
|
watch,
|
||||||
minify: !watch,
|
minify: !watch && !IS_REPORTER,
|
||||||
sourcemap: watch ? "inline" : "",
|
sourcemap: watch ? "inline" : "",
|
||||||
legalComments: "linked",
|
legalComments: "linked",
|
||||||
banner,
|
banner,
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import pup, { JSHandle } from "puppeteer-core";
|
import pup, { JSHandle } from "puppeteer-core";
|
||||||
|
|
||||||
for (const variable of ["DISCORD_TOKEN", "CHROMIUM_BIN"]) {
|
for (const variable of ["CHROMIUM_BIN"]) {
|
||||||
if (!process.env[variable]) {
|
if (!process.env[variable]) {
|
||||||
console.error(`Missing environment variable ${variable}`);
|
console.error(`Missing environment variable ${variable}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
@ -214,7 +214,7 @@ page.on("console", async e => {
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case "WebpackInterceptor:":
|
case "WebpackInterceptor:":
|
||||||
const patchFailMatch = message.match(/Patch by (.+?) (had no effect|errored|found no module) \(Module id is (.+?)\): (.+)/)!;
|
const patchFailMatch = message.match(/Patch by (.+?) (had no effect|errored|found no module|took [\d.]+?ms) \(Module id is (.+?)\): (.+)/)!;
|
||||||
if (!patchFailMatch) break;
|
if (!patchFailMatch) break;
|
||||||
|
|
||||||
console.error(await getText());
|
console.error(await getText());
|
||||||
|
@ -291,7 +291,7 @@ page.on("error", e => console.error("[Error]", e.message));
|
||||||
page.on("pageerror", e => {
|
page.on("pageerror", e => {
|
||||||
if (e.message.includes("Sentry successfully disabled")) return;
|
if (e.message.includes("Sentry successfully disabled")) return;
|
||||||
|
|
||||||
if (!e.message.startsWith("Object") && !e.message.includes("Cannot find module")) {
|
if (!e.message.startsWith("Object") && !e.message.includes("Cannot find module") && !/^.{1,2}$/.test(e.message)) {
|
||||||
console.error("[Page Error]", e.message);
|
console.error("[Page Error]", e.message);
|
||||||
report.otherErrors.push(e.message);
|
report.otherErrors.push(e.message);
|
||||||
} else {
|
} else {
|
||||||
|
@ -299,20 +299,9 @@ page.on("pageerror", e => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function reporterRuntime(token: string) {
|
|
||||||
Vencord.Webpack.waitFor(
|
|
||||||
"loginToken",
|
|
||||||
m => {
|
|
||||||
console.log("[PUP_DEBUG]", "Logging in with token...");
|
|
||||||
m.loginToken(token);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await page.evaluateOnNewDocument(`
|
await page.evaluateOnNewDocument(`
|
||||||
if (location.host.endsWith("discord.com")) {
|
if (location.host.endsWith("discord.com")) {
|
||||||
${readFileSync("./dist/browser.js", "utf-8")};
|
${readFileSync("./dist/browser.js", "utf-8")};
|
||||||
(${reporterRuntime.toString()})(${JSON.stringify(process.env.DISCORD_TOKEN)});
|
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@ export * as Util from "./utils";
|
||||||
export * as QuickCss from "./utils/quickCss";
|
export * as QuickCss from "./utils/quickCss";
|
||||||
export * as Updater from "./utils/updater";
|
export * as Updater from "./utils/updater";
|
||||||
export * as Webpack from "./webpack";
|
export * as Webpack from "./webpack";
|
||||||
|
export * as WebpackPatcher from "./webpack/patchWebpack";
|
||||||
export { PlainSettings, Settings };
|
export { PlainSettings, Settings };
|
||||||
|
|
||||||
import "./utils/quickCss";
|
import "./utils/quickCss";
|
||||||
import "./webpack/patchWebpack";
|
|
||||||
|
|
||||||
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
|
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
|
||||||
import { StartAt } from "@utils/types";
|
import { StartAt } from "@utils/types";
|
||||||
|
@ -39,7 +39,7 @@ import { localStorage } from "./utils/localStorage";
|
||||||
import { relaunch } from "./utils/native";
|
import { relaunch } from "./utils/native";
|
||||||
import { getCloudSettings, putCloudSettings } from "./utils/settingsSync";
|
import { getCloudSettings, putCloudSettings } from "./utils/settingsSync";
|
||||||
import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
|
import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
|
||||||
import { onceReady } from "./webpack";
|
import { onceDiscordLoaded } from "./webpack";
|
||||||
import { SettingsRouter } from "./webpack/common";
|
import { SettingsRouter } from "./webpack/common";
|
||||||
|
|
||||||
if (IS_REPORTER) {
|
if (IS_REPORTER) {
|
||||||
|
@ -86,7 +86,7 @@ async function syncSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
await onceReady;
|
await onceDiscordLoaded;
|
||||||
startAllPlugins(StartAt.WebpackReady);
|
startAllPlugins(StartAt.WebpackReady);
|
||||||
|
|
||||||
syncSettings();
|
syncSettings();
|
||||||
|
@ -125,7 +125,7 @@ async function init() {
|
||||||
const pendingPatches = patches.filter(p => !p.all && p.predicate?.() !== false);
|
const pendingPatches = patches.filter(p => !p.all && p.predicate?.() !== false);
|
||||||
if (pendingPatches.length)
|
if (pendingPatches.length)
|
||||||
PMLogger.warn(
|
PMLogger.warn(
|
||||||
"Webpack has finished initialising, but some patches haven't been applied yet.",
|
"Webpack has finished initializing, but some patches haven't been applied yet.",
|
||||||
"This might be expected since some Modules are lazy loaded, but please verify",
|
"This might be expected since some Modules are lazy loaded, but please verify",
|
||||||
"that all plugins are working as intended.",
|
"that all plugins are working as intended.",
|
||||||
"You are seeing this warning because this is a Development build of Vencord.",
|
"You are seeing this warning because this is a Development build of Vencord.",
|
||||||
|
|
|
@ -8,13 +8,12 @@ import "./ChatButton.css";
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { waitFor } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
|
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
|
||||||
import { Channel } from "discord-types/general";
|
import { Channel } from "discord-types/general";
|
||||||
import { HTMLProps, MouseEventHandler, ReactNode } from "react";
|
import { HTMLProps, MouseEventHandler, ReactNode } from "react";
|
||||||
|
|
||||||
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;
|
const ChannelTextAreaClasses = findByProps<Record<"button" | "buttonContainer", string>>("buttonContainer", "channelTextArea");
|
||||||
waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
|
|
||||||
|
|
||||||
export interface ChatBarProps {
|
export interface ChatBarProps {
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
|
|
|
@ -17,14 +17,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { mergeDefaults } from "@utils/mergeDefaults";
|
import { mergeDefaults } from "@utils/mergeDefaults";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCode } from "@webpack";
|
||||||
import { MessageActions, SnowflakeUtils } from "@webpack/common";
|
import { MessageActions, SnowflakeUtils } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
import type { PartialDeep } from "type-fest";
|
import type { PartialDeep } from "type-fest";
|
||||||
|
|
||||||
import { Argument } from "./types";
|
import { Argument } from "./types";
|
||||||
|
|
||||||
const createBotMessage = findByCodeLazy('username:"Clyde"');
|
const createBotMessage = findByCode('username:"Clyde"');
|
||||||
|
|
||||||
export function generateId() {
|
export function generateId() {
|
||||||
return `-${SnowflakeUtils.fromTimestamp(Date.now())}`;
|
return `-${SnowflakeUtils.fromTimestamp(Date.now())}`;
|
||||||
|
|
|
@ -16,23 +16,22 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { waitFor } from "@webpack";
|
import { find } from "@webpack";
|
||||||
|
|
||||||
let NoticesModule: any;
|
const Notices = find(m => m.show && m.dismiss && !m.suppressAll);
|
||||||
waitFor(m => m.show && m.dismiss && !m.suppressAll, m => NoticesModule = m);
|
|
||||||
|
|
||||||
export const noticesQueue = [] as any[];
|
export const noticesQueue = [] as any[];
|
||||||
export let currentNotice: any = null;
|
export let currentNotice: any = null;
|
||||||
|
|
||||||
export function popNotice() {
|
export function popNotice() {
|
||||||
NoticesModule.dismiss();
|
Notices.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function nextNotice() {
|
export function nextNotice() {
|
||||||
currentNotice = noticesQueue.shift();
|
currentNotice = noticesQueue.shift();
|
||||||
|
|
||||||
if (currentNotice) {
|
if (currentNotice) {
|
||||||
NoticesModule.show(...currentNotice, "VencordNotice");
|
Notices.show(...currentNotice, "VencordNotice");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,10 @@ export interface Settings {
|
||||||
autoUpdate: boolean;
|
autoUpdate: boolean;
|
||||||
autoUpdateNotification: boolean,
|
autoUpdateNotification: boolean,
|
||||||
useQuickCss: boolean;
|
useQuickCss: boolean;
|
||||||
enableReactDevtools: boolean;
|
|
||||||
themeLinks: string[];
|
themeLinks: string[];
|
||||||
|
eagerPatches: boolean;
|
||||||
enabledThemes: string[];
|
enabledThemes: string[];
|
||||||
|
enableReactDevtools: boolean;
|
||||||
frameless: boolean;
|
frameless: boolean;
|
||||||
transparent: boolean;
|
transparent: boolean;
|
||||||
winCtrlQ: boolean;
|
winCtrlQ: boolean;
|
||||||
|
@ -81,6 +82,7 @@ const DefaultSettings: Settings = {
|
||||||
autoUpdateNotification: true,
|
autoUpdateNotification: true,
|
||||||
useQuickCss: true,
|
useQuickCss: true,
|
||||||
themeLinks: [],
|
themeLinks: [],
|
||||||
|
eagerPatches: IS_REPORTER,
|
||||||
enabledThemes: [],
|
enabledThemes: [],
|
||||||
enableReactDevtools: false,
|
enableReactDevtools: false,
|
||||||
frameless: false,
|
frameless: false,
|
||||||
|
@ -116,7 +118,6 @@ const saveSettingsOnFrequentAction = debounce(async () => {
|
||||||
}
|
}
|
||||||
}, 60_000);
|
}, 60_000);
|
||||||
|
|
||||||
|
|
||||||
export const SettingsStore = new SettingsStoreClass(settings, {
|
export const SettingsStore = new SettingsStoreClass(settings, {
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
getDefaultValue({
|
getDefaultValue({
|
||||||
|
|
|
@ -89,8 +89,8 @@ export const isStyleEnabled = (name: string) => requireStyle(name).dom?.isConnec
|
||||||
* // -- plugin.ts --
|
* // -- plugin.ts --
|
||||||
* import pluginStyle from "./plugin.css?managed";
|
* import pluginStyle from "./plugin.css?managed";
|
||||||
* import { setStyleVars } from "@api/Styles";
|
* import { setStyleVars } from "@api/Styles";
|
||||||
* import { findByPropsLazy } from "@webpack";
|
* import { findByProps } from "@webpack";
|
||||||
* const classNames = findByPropsLazy("thin", "scrollerBase"); // { thin: "thin-31rlnD scrollerBase-_bVAAt", ... }
|
* const classNames = findByProps("thin", "scrollerBase"); // { thin: "thin-31rlnD scrollerBase-_bVAAt", ... }
|
||||||
*
|
*
|
||||||
* // Inside some plugin method like "start()"
|
* // Inside some plugin method like "start()"
|
||||||
* setStyleClassNames(pluginStyle, classNames);
|
* setStyleClassNames(pluginStyle, classNames);
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { proxyLazy } from "@utils/lazy";
|
import { proxyLazy } from "@utils/lazy";
|
||||||
import { Logger } from "@utils/Logger";
|
import { findByFactoryCode } from "@webpack";
|
||||||
import { findModuleId, proxyLazyWebpack, wreq } from "@webpack";
|
|
||||||
|
|
||||||
interface UserSettingDefinition<T> {
|
interface UserSettingDefinition<T> {
|
||||||
/**
|
/**
|
||||||
|
@ -43,12 +42,7 @@ interface UserSettingDefinition<T> {
|
||||||
userSettingsAPIName: string;
|
userSettingsAPIName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UserSettings: Record<PropertyKey, UserSettingDefinition<any>> | undefined = proxyLazyWebpack(() => {
|
export const UserSettings = findByFactoryCode<Record<PropertyKey, UserSettingDefinition<any>>>('"textAndImages","renderSpoilers"');
|
||||||
const modId = findModuleId('"textAndImages","renderSpoilers"');
|
|
||||||
if (modId == null) return new Logger("UserSettingsAPI ").error("Didn't find settings module.");
|
|
||||||
|
|
||||||
return wreq(modId as any);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the setting with the given setting group and name.
|
* Get the setting with the given setting group and name.
|
||||||
|
@ -56,7 +50,7 @@ export const UserSettings: Record<PropertyKey, UserSettingDefinition<any>> | und
|
||||||
* @param group The setting group
|
* @param group The setting group
|
||||||
* @param name The name of the setting
|
* @param name The name of the setting
|
||||||
*/
|
*/
|
||||||
export function getUserSetting<T = any>(group: string, name: string): UserSettingDefinition<T> | undefined {
|
export function getUserSetting<T = any>(group: string, name: string): UserSettingDefinition<T> {
|
||||||
if (!Vencord.Plugins.isPluginEnabled("UserSettingsAPI")) throw new Error("Cannot use UserSettingsAPI without setting as dependency.");
|
if (!Vencord.Plugins.isPluginEnabled("UserSettingsAPI")) throw new Error("Cannot use UserSettingsAPI without setting as dependency.");
|
||||||
|
|
||||||
for (const key in UserSettings) {
|
for (const key in UserSettings) {
|
||||||
|
@ -66,10 +60,12 @@ export function getUserSetting<T = any>(group: string, name: string): UserSettin
|
||||||
return userSetting;
|
return userSetting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new Error(`UserSettingsAPI: Setting ${group}.${name} not found.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link getUserSettingDefinition}, lazy.
|
* Lazy version of {@link getUserSetting}
|
||||||
*
|
*
|
||||||
* Get the setting with the given setting group and name.
|
* Get the setting with the given setting group and name.
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Parser } from "@webpack/common";
|
import { Parser } from "@webpack/common";
|
||||||
|
|
||||||
const CodeContainerClasses = findByPropsLazy("markup", "codeContainer");
|
const CodeContainerClasses = findByProps("markup", "codeContainer");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders code in a Discord codeblock
|
* Renders code in a Discord codeblock
|
||||||
|
|
|
@ -24,13 +24,12 @@ import { classNameFactory } from "@api/Styles";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { gitRemote } from "@shared/vencordUserAgent";
|
import { gitRemote } from "@shared/vencordUserAgent";
|
||||||
import { proxyLazy } from "@utils/lazy";
|
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes, isObjectEmpty } from "@utils/misc";
|
import { classes, isObjectEmpty } from "@utils/misc";
|
||||||
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { OptionType, Plugin } from "@utils/types";
|
import { OptionType, Plugin } from "@utils/types";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { find, findByProps, findComponentByCode } from "@webpack";
|
||||||
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common";
|
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserUtils } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
import { Constructor } from "type-fest";
|
import { Constructor } from "type-fest";
|
||||||
|
|
||||||
|
@ -50,9 +49,9 @@ import { GithubButton, WebsiteButton } from "./LinkIconButton";
|
||||||
|
|
||||||
const cl = classNameFactory("vc-plugin-modal-");
|
const cl = classNameFactory("vc-plugin-modal-");
|
||||||
|
|
||||||
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
|
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
|
||||||
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
|
const AvatarStyles = findByProps("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
|
||||||
const UserRecord: Constructor<Partial<User>> = proxyLazy(() => UserStore.getCurrentUser().constructor) as any;
|
const UserRecord = find<Constructor<Partial<User>>>(m => m?.prototype?.getAvatarURL && m?.prototype?.hasHadPremium);
|
||||||
|
|
||||||
interface PluginModalProps extends ModalProps {
|
interface PluginModalProps extends ModalProps {
|
||||||
plugin: Plugin;
|
plugin: Plugin;
|
||||||
|
|
|
@ -33,19 +33,19 @@ import { Margins } from "@utils/margins";
|
||||||
import { classes, isObjectEmpty } from "@utils/misc";
|
import { classes, isObjectEmpty } from "@utils/misc";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import { Plugin } from "@utils/types";
|
import { Plugin } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common";
|
import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common";
|
||||||
|
|
||||||
import Plugins, { ExcludedPlugins } from "~plugins";
|
import Plugins, { ExcludedPlugins } from "~plugins";
|
||||||
|
|
||||||
// Avoid circular dependency
|
// Avoid circular dependency
|
||||||
const { startDependenciesRecursive, startPlugin, stopPlugin } = proxyLazy(() => require("../../plugins"));
|
const PluginManager = proxyLazy(() => require("../../plugins")) as typeof import("../../plugins");
|
||||||
|
|
||||||
const cl = classNameFactory("vc-plugins-");
|
const cl = classNameFactory("vc-plugins-");
|
||||||
const logger = new Logger("PluginSettings", "#a6d189");
|
const logger = new Logger("PluginSettings", "#a6d189");
|
||||||
|
|
||||||
const InputStyles = findByPropsLazy("inputWrapper", "inputDefault", "error");
|
const InputStyles = findByProps("inputWrapper", "inputDefault", "error");
|
||||||
const ButtonClasses = findByPropsLazy("button", "disabled", "enabled");
|
const ButtonClasses = findByProps("button", "disabled", "enabled");
|
||||||
|
|
||||||
|
|
||||||
function showErrorToast(message: string) {
|
function showErrorToast(message: string) {
|
||||||
|
@ -100,7 +100,7 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
|
||||||
|
|
||||||
// If we're enabling a plugin, make sure all deps are enabled recursively.
|
// If we're enabling a plugin, make sure all deps are enabled recursively.
|
||||||
if (!wasEnabled) {
|
if (!wasEnabled) {
|
||||||
const { restartNeeded, failures } = startDependenciesRecursive(plugin);
|
const { restartNeeded, failures } = PluginManager.startDependenciesRecursive(plugin);
|
||||||
if (failures.length) {
|
if (failures.length) {
|
||||||
logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`);
|
logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`);
|
||||||
showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null);
|
showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null);
|
||||||
|
@ -126,7 +126,7 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin);
|
const result = wasEnabled ? PluginManager.stopPlugin(plugin) : PluginManager.startPlugin(plugin);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
settings.enabled = false;
|
settings.enabled = false;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import "./Switch.css";
|
import "./Switch.css";
|
||||||
|
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
|
|
||||||
interface SwitchProps {
|
interface SwitchProps {
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
|
@ -29,7 +29,7 @@ interface SwitchProps {
|
||||||
|
|
||||||
const SWITCH_ON = "var(--green-360)";
|
const SWITCH_ON = "var(--green-360)";
|
||||||
const SWITCH_OFF = "var(--primary-400)";
|
const SWITCH_OFF = "var(--primary-400)";
|
||||||
const SwitchClasses = findByPropsLazy("slider", "input", "container");
|
const SwitchClasses = findByProps("slider", "input", "container");
|
||||||
|
|
||||||
export function Switch({ checked, onChange, disabled }: SwitchProps) {
|
export function Switch({ checked, onChange, disabled }: SwitchProps) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { Margins } from "@utils/margins";
|
||||||
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
|
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
|
||||||
import { makeCodeblock } from "@utils/text";
|
import { makeCodeblock } from "@utils/text";
|
||||||
import { Patch, ReplaceFn } from "@utils/types";
|
import { Patch, ReplaceFn } from "@utils/types";
|
||||||
import { search } from "@webpack";
|
import { searchFactories } from "@webpack";
|
||||||
import { Button, Clipboard, Forms, Parser, React, Switch, TextArea, TextInput } from "@webpack/common";
|
import { Button, Clipboard, Forms, Parser, React, Switch, TextArea, TextInput } from "@webpack/common";
|
||||||
|
|
||||||
import { SettingsTab, wrapTab } from "./shared";
|
import { SettingsTab, wrapTab } from "./shared";
|
||||||
|
@ -33,7 +33,7 @@ if (IS_DEV) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const findCandidates = debounce(function ({ find, setModule, setError }) {
|
const findCandidates = debounce(function ({ find, setModule, setError }) {
|
||||||
const candidates = search(find);
|
const candidates = searchFactories(find);
|
||||||
const keys = Object.keys(candidates);
|
const keys = Object.keys(candidates);
|
||||||
const len = keys.length;
|
const len = keys.length;
|
||||||
if (len === 0)
|
if (len === 0)
|
||||||
|
@ -56,7 +56,7 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
|
||||||
const [compileResult, setCompileResult] = React.useState<[boolean, string]>();
|
const [compileResult, setCompileResult] = React.useState<[boolean, string]>();
|
||||||
|
|
||||||
const [patchedCode, matchResult, diff] = React.useMemo(() => {
|
const [patchedCode, matchResult, diff] = React.useMemo(() => {
|
||||||
const src: string = fact.toString().replaceAll("\n", "");
|
const src = String(fact).replaceAll("\n", "");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new RegExp(match);
|
new RegExp(match);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings, useSettings } from "@api/Settings";
|
import { useSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { DeleteIcon, FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons";
|
import { DeleteIcon, FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons";
|
||||||
|
@ -27,9 +27,9 @@ import { openInviteModal } from "@utils/discord";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { showItemInFolder } from "@utils/native";
|
import { showItemInFolder } from "@utils/native";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import { findLazy } from "@webpack";
|
import { findComponentByFields } from "@webpack";
|
||||||
import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
|
import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
|
||||||
import type { ComponentType, Ref, SyntheticEvent } from "react";
|
import type { Ref, SyntheticEvent } from "react";
|
||||||
|
|
||||||
import Plugins from "~plugins";
|
import Plugins from "~plugins";
|
||||||
|
|
||||||
|
@ -37,14 +37,14 @@ import { AddonCard } from "./AddonCard";
|
||||||
import { QuickAction, QuickActionCard } from "./quickActions";
|
import { QuickAction, QuickActionCard } from "./quickActions";
|
||||||
import { SettingsTab, wrapTab } from "./shared";
|
import { SettingsTab, wrapTab } from "./shared";
|
||||||
|
|
||||||
type FileInput = ComponentType<{
|
type FileInputProps = {
|
||||||
ref: Ref<HTMLInputElement>;
|
ref: Ref<HTMLInputElement>;
|
||||||
onChange: (e: SyntheticEvent<HTMLInputElement>) => void;
|
onChange: (e: SyntheticEvent<HTMLInputElement>) => void;
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
filters?: { name?: string; extensions: string[]; }[];
|
filters?: { name?: string; extensions: string[]; }[];
|
||||||
}>;
|
};
|
||||||
|
|
||||||
const FileInput: FileInput = findLazy(m => m.prototype?.activateUploadDialogue && m.prototype.setRef);
|
const FileInput = findComponentByFields<FileInputProps>("activateUploadDialogue", "setRef");
|
||||||
|
|
||||||
const cl = classNameFactory("vc-settings-theme-");
|
const cl = classNameFactory("vc-settings-theme-");
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ function ThemesTab() {
|
||||||
Icon={PaintbrushIcon}
|
Icon={PaintbrushIcon}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{Settings.plugins.ClientTheme.enabled && (
|
{Vencord.Plugins.isPluginEnabled("ClientTheme") && (
|
||||||
<QuickAction
|
<QuickAction
|
||||||
text="Edit ClientTheme"
|
text="Edit ClientTheme"
|
||||||
action={() => openPluginModal(Plugins.ClientTheme)}
|
action={() => openPluginModal(Plugins.ClientTheme)}
|
||||||
|
|
|
@ -23,35 +23,61 @@ if (IS_DEV || IS_REPORTER) {
|
||||||
var logger = new Logger("Tracer", "#FFD166");
|
var logger = new Logger("Tracer", "#FFD166");
|
||||||
}
|
}
|
||||||
|
|
||||||
const noop = function () { };
|
export const beginTrace = !(IS_DEV || IS_REPORTER) ? () => { } :
|
||||||
|
|
||||||
export const beginTrace = !(IS_DEV || IS_REPORTER) ? noop :
|
|
||||||
function beginTrace(name: string, ...args: any[]) {
|
function beginTrace(name: string, ...args: any[]) {
|
||||||
if (name in traces)
|
if (name in traces) {
|
||||||
throw new Error(`Trace ${name} already exists!`);
|
throw new Error(`Trace ${name} already exists!`);
|
||||||
|
}
|
||||||
|
|
||||||
traces[name] = [performance.now(), args];
|
traces[name] = [performance.now(), args];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const finishTrace = !(IS_DEV || IS_REPORTER) ? noop : function finishTrace(name: string) {
|
export const finishTrace = !(IS_DEV || IS_REPORTER) ? () => 0 :
|
||||||
|
function finishTrace(name: string) {
|
||||||
const end = performance.now();
|
const end = performance.now();
|
||||||
|
|
||||||
const [start, args] = traces[name];
|
const [start, args] = traces[name];
|
||||||
delete traces[name];
|
delete traces[name];
|
||||||
|
|
||||||
logger.debug(`${name} took ${end - start}ms`, args);
|
const totalTime = end - start;
|
||||||
|
logger.debug(`${name} took ${totalTime}ms`, args);
|
||||||
|
|
||||||
|
return totalTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Func = (...args: any[]) => any;
|
type Func = (...args: any[]) => any;
|
||||||
type TraceNameMapper<F extends Func> = (...args: Parameters<F>) => string;
|
type TraceNameMapper<F extends Func> = (...args: Parameters<F>) => string;
|
||||||
|
|
||||||
const noopTracer =
|
function noopTracerWithResults<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) {
|
||||||
<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) => f;
|
return function (this: unknown, ...args: Parameters<F>): [ReturnType<F>, number] {
|
||||||
|
return [f.apply(this, args), 0];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function noopTracer<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const traceFunctionWithResults = !(IS_DEV || IS_REPORTER)
|
||||||
|
? noopTracerWithResults
|
||||||
|
: function traceFunctionWithResults<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): (this: unknown, ...args: Parameters<F>) => [ReturnType<F>, number] {
|
||||||
|
return function (this: unknown, ...args: Parameters<F>) {
|
||||||
|
const traceName = mapper?.(...args) ?? name;
|
||||||
|
|
||||||
|
beginTrace(traceName, ...arguments);
|
||||||
|
try {
|
||||||
|
return [f.apply(this, args), finishTrace(traceName)];
|
||||||
|
} catch (e) {
|
||||||
|
finishTrace(traceName);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const traceFunction = !(IS_DEV || IS_REPORTER)
|
export const traceFunction = !(IS_DEV || IS_REPORTER)
|
||||||
? noopTracer
|
? noopTracer
|
||||||
: function traceFunction<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): F {
|
: function traceFunction<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): F {
|
||||||
return function (this: any, ...args: Parameters<F>) {
|
return function (this: unknown, ...args: Parameters<F>) {
|
||||||
const traceName = mapper?.(...args) ?? name;
|
const traceName = mapper?.(...args) ?? name;
|
||||||
|
|
||||||
beginTrace(traceName, ...arguments);
|
beginTrace(traceName, ...arguments);
|
||||||
|
|
|
@ -8,10 +8,11 @@ import { Logger } from "@utils/Logger";
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import * as Webpack from "@webpack";
|
import * as Webpack from "@webpack";
|
||||||
import { wreq } from "@webpack";
|
import { wreq } from "@webpack";
|
||||||
|
import { AnyModuleFactory, ModuleFactory } from "webpack";
|
||||||
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
|
|
||||||
|
|
||||||
export async function loadLazyChunks() {
|
export async function loadLazyChunks() {
|
||||||
|
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LazyChunkLoaderLogger.log("Loading all chunks...");
|
LazyChunkLoaderLogger.log("Loading all chunks...");
|
||||||
|
|
||||||
|
@ -25,16 +26,12 @@ export async function loadLazyChunks() {
|
||||||
// True if resolved, false otherwise
|
// True if resolved, false otherwise
|
||||||
const chunksSearchPromises = [] as Array<() => boolean>;
|
const chunksSearchPromises = [] as Array<() => boolean>;
|
||||||
|
|
||||||
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
|
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g);
|
||||||
|
|
||||||
async function searchAndLoadLazyChunks(factoryCode: string) {
|
async function searchAndLoadLazyChunks(factoryCode: string) {
|
||||||
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
||||||
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
|
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
|
||||||
|
|
||||||
// Workaround for a chunk that depends on the ChannelMessage component but may be be force loaded before
|
|
||||||
// the chunk containing the component
|
|
||||||
const shouldForceDefer = factoryCode.includes(".Messages.GUILD_FEED_UNFEATURE_BUTTON_TEXT");
|
|
||||||
|
|
||||||
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
|
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
|
||||||
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : [];
|
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : [];
|
||||||
|
|
||||||
|
@ -69,19 +66,14 @@ export async function loadLazyChunks() {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Array.from(validChunkGroups)
|
Array.from(validChunkGroups)
|
||||||
.map(([chunkIds]) =>
|
.map(([chunkIds]) =>
|
||||||
Promise.all(chunkIds.map(id => wreq.e(id as any).catch(() => { })))
|
Promise.all(chunkIds.map(id => wreq.e(id)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Requires the entry points for all valid chunk groups
|
// Requires the entry points for all valid chunk groups
|
||||||
for (const [, entryPoint] of validChunkGroups) {
|
for (const [, entryPoint] of validChunkGroups) {
|
||||||
try {
|
try {
|
||||||
if (shouldForceDefer) {
|
if (wreq.m[entryPoint]) wreq(entryPoint);
|
||||||
deferredRequires.add(entryPoint);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wreq.m[entryPoint]) wreq(entryPoint as any);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
@ -109,32 +101,33 @@ export async function loadLazyChunks() {
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Webpack.factoryListeners.add(factory => {
|
function factoryListener(factory: AnyModuleFactory | ModuleFactory) {
|
||||||
let isResolved = false;
|
let isResolved = false;
|
||||||
searchAndLoadLazyChunks(factory.toString()).then(() => isResolved = true);
|
searchAndLoadLazyChunks(String(factory))
|
||||||
|
.then(() => isResolved = true)
|
||||||
chunksSearchPromises.push(() => isResolved);
|
.catch(() => isResolved = true);
|
||||||
});
|
|
||||||
|
|
||||||
for (const factoryId in wreq.m) {
|
|
||||||
let isResolved = false;
|
|
||||||
searchAndLoadLazyChunks(wreq.m[factoryId].toString()).then(() => isResolved = true);
|
|
||||||
|
|
||||||
chunksSearchPromises.push(() => isResolved);
|
chunksSearchPromises.push(() => isResolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Webpack.factoryListeners.add(factoryListener);
|
||||||
|
for (const factoryId in wreq.m) {
|
||||||
|
factoryListener(wreq.m[factoryId]);
|
||||||
|
}
|
||||||
|
|
||||||
await chunksSearchingDone;
|
await chunksSearchingDone;
|
||||||
|
Webpack.factoryListeners.delete(factoryListener);
|
||||||
|
|
||||||
// Require deferred entry points
|
// Require deferred entry points
|
||||||
for (const deferredRequire of deferredRequires) {
|
for (const deferredRequire of deferredRequires) {
|
||||||
wreq!(deferredRequire as any);
|
wreq(deferredRequire);
|
||||||
}
|
}
|
||||||
|
|
||||||
// All chunks Discord has mapped to asset files, even if they are not used anymore
|
// All chunks Discord has mapped to asset files, even if they are not used anymore
|
||||||
const allChunks = [] as number[];
|
const allChunks = [] as number[];
|
||||||
|
|
||||||
// Matches "id" or id:
|
// Matches "id" or id:
|
||||||
for (const currentMatch of wreq!.u.toString().matchAll(/(?:"([\deE]+?)"(?![,}]))|(?:([\deE]+?):)/g)) {
|
for (const currentMatch of String(wreq.u).matchAll(/(?:"([\deE]+?)"(?![,}]))|(?:([\deE]+?):)/g)) {
|
||||||
const id = currentMatch[1] ?? currentMatch[2];
|
const id = currentMatch[1] ?? currentMatch[2];
|
||||||
if (id == null) continue;
|
if (id == null) continue;
|
||||||
|
|
||||||
|
@ -143,7 +136,8 @@ export async function loadLazyChunks() {
|
||||||
|
|
||||||
if (allChunks.length === 0) throw new Error("Failed to get all chunks");
|
if (allChunks.length === 0) throw new Error("Failed to get all chunks");
|
||||||
|
|
||||||
// Chunks that are not loaded (not used) by Discord code anymore
|
// Chunks which our regex could not catch to load
|
||||||
|
// It will always contain WebWorker assets, and also currently contains some language packs which are loaded differently
|
||||||
const chunksLeft = allChunks.filter(id => {
|
const chunksLeft = allChunks.filter(id => {
|
||||||
return !(validChunks.has(id) || invalidChunks.has(id));
|
return !(validChunks.has(id) || invalidChunks.has(id));
|
||||||
});
|
});
|
||||||
|
@ -153,12 +147,9 @@ export async function loadLazyChunks() {
|
||||||
.then(r => r.text())
|
.then(r => r.text())
|
||||||
.then(t => t.includes("importScripts("));
|
.then(t => t.includes("importScripts("));
|
||||||
|
|
||||||
// Loads and requires a chunk
|
// Loads the chunk. Currently this only happens with the language packs which are loaded differently
|
||||||
if (!isWorkerAsset) {
|
if (!isWorkerAsset) {
|
||||||
await wreq.e(id as any);
|
await wreq.e(id);
|
||||||
// Technically, the id of the chunk does not match the entry point
|
|
||||||
// But, still try it because we have no way to get the actual entry point
|
|
||||||
if (wreq.m[id]) wreq(id as any);
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -4,22 +4,39 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
|
import { SYM_PROXY_INNER_GET, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
|
||||||
import * as Webpack from "@webpack";
|
import * as Webpack from "@webpack";
|
||||||
import { patches } from "plugins";
|
import { addPatch, patches } from "plugins";
|
||||||
|
|
||||||
import { loadLazyChunks } from "./loadLazyChunks";
|
import { loadLazyChunks } from "./loadLazyChunks";
|
||||||
|
|
||||||
|
async function runReporter() {
|
||||||
const ReporterLogger = new Logger("Reporter");
|
const ReporterLogger = new Logger("Reporter");
|
||||||
|
|
||||||
async function runReporter() {
|
|
||||||
try {
|
try {
|
||||||
ReporterLogger.log("Starting test...");
|
ReporterLogger.log("Starting test...");
|
||||||
|
|
||||||
let loadLazyChunksResolve: (value: void | PromiseLike<void>) => void;
|
let loadLazyChunksResolve: (value: void) => void;
|
||||||
const loadLazyChunksDone = new Promise<void>(r => loadLazyChunksResolve = r);
|
const loadLazyChunksDone = new Promise<void>(r => loadLazyChunksResolve = r);
|
||||||
|
|
||||||
Webpack.beforeInitListeners.add(() => loadLazyChunks().then((loadLazyChunksResolve)));
|
// The main patch for starting the reporter chunk loading
|
||||||
|
addPatch({
|
||||||
|
find: '"Could not find app-mount"',
|
||||||
|
replacement: {
|
||||||
|
match: /(?<="use strict";)/,
|
||||||
|
replace: "Vencord.Webpack._initReporter();"
|
||||||
|
}
|
||||||
|
}, "Vencord Reporter");
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
Vencord.Webpack._initReporter = function () {
|
||||||
|
// initReporter is called in the patched entry point of Discord
|
||||||
|
// setImmediate to only start searching for lazy chunks after Discord initialized the app
|
||||||
|
setTimeout(() => loadLazyChunks().then(loadLazyChunksResolve), 0);
|
||||||
|
};
|
||||||
|
|
||||||
await loadLazyChunksDone;
|
await loadLazyChunksDone;
|
||||||
|
|
||||||
for (const patch of patches) {
|
for (const patch of patches) {
|
||||||
|
@ -28,52 +45,158 @@ async function runReporter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [searchType, args] of Webpack.lazyWebpackSearchHistory) {
|
for (const [plugin, moduleId, match, totalTime] of Vencord.WebpackPatcher.patchTimings) {
|
||||||
let method = searchType;
|
if (totalTime > 3) {
|
||||||
|
new Logger("WebpackInterceptor").warn(`Patch by ${plugin} took ${totalTime}ms (Module id is ${String(moduleId)}): ${match}`);
|
||||||
if (searchType === "findComponent") method = "find";
|
}
|
||||||
if (searchType === "findExportedComponent") method = "findByProps";
|
|
||||||
if (searchType === "waitFor" || searchType === "waitForComponent") {
|
|
||||||
if (typeof args[0] === "string") method = "findByProps";
|
|
||||||
else method = "find";
|
|
||||||
}
|
}
|
||||||
if (searchType === "waitForStore") method = "findStore";
|
|
||||||
|
|
||||||
let result: any;
|
await Promise.all(Webpack.webpackSearchHistory.map(async ([searchType, args]) => {
|
||||||
|
args = [...args];
|
||||||
|
|
||||||
|
let result = null as any;
|
||||||
try {
|
try {
|
||||||
if (method === "proxyLazyWebpack" || method === "LazyComponentWebpack") {
|
switch (searchType) {
|
||||||
|
case "webpackDependantLazy":
|
||||||
|
case "webpackDependantLazyComponent": {
|
||||||
const [factory] = args;
|
const [factory] = args;
|
||||||
result = factory();
|
result = factory();
|
||||||
} else if (method === "extractAndLoadChunks") {
|
break;
|
||||||
const [code, matcher] = args;
|
}
|
||||||
|
case "extractAndLoadChunks": {
|
||||||
|
const extractAndLoadChunks = args.shift();
|
||||||
|
|
||||||
result = await Webpack.extractAndLoadChunks(code, matcher);
|
result = await extractAndLoadChunks();
|
||||||
if (result === false) result = null;
|
if (result === false) {
|
||||||
} else if (method === "mapMangledModule") {
|
result = null;
|
||||||
const [code, mapper] = args;
|
|
||||||
|
|
||||||
result = Webpack.mapMangledModule(code, mapper);
|
|
||||||
if (Object.keys(result).length !== Object.keys(mapper).length) throw new Error("Webpack Find Fail");
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
result = Webpack[method](...args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null || (result.$$vencordInternal != null && result.$$vencordInternal() == null)) throw new Error("Webpack Find Fail");
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
const findResult = args.shift();
|
||||||
|
|
||||||
|
if (findResult != null) {
|
||||||
|
if (findResult.$$vencordCallbackCalled != null && findResult.$$vencordCallbackCalled()) {
|
||||||
|
result = findResult;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findResult[SYM_PROXY_INNER_GET] != null) {
|
||||||
|
result = findResult[SYM_PROXY_INNER_VALUE];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findResult[SYM_LAZY_COMPONENT_INNER] != null) {
|
||||||
|
result = findResult[SYM_LAZY_COMPONENT_INNER]();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchType === "mapMangledModule") {
|
||||||
|
result = findResult;
|
||||||
|
|
||||||
|
for (const innerMap in result) {
|
||||||
|
if (
|
||||||
|
(result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) ||
|
||||||
|
(result[innerMap][SYM_LAZY_COMPONENT_INNER] != null && result[innerMap][SYM_LAZY_COMPONENT_INNER]() == null)
|
||||||
|
) {
|
||||||
|
throw new Error("Webpack Find Fail");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can happen if a `find` was immediately found
|
||||||
|
result = findResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
throw new Error("Webpack Find Fail");
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
let logMessage = searchType;
|
let logMessage = searchType;
|
||||||
if (method === "find" || method === "proxyLazyWebpack" || method === "LazyComponentWebpack") logMessage += `(${args[0].toString().slice(0, 147)}...)`;
|
|
||||||
else if (method === "extractAndLoadChunks") logMessage += `([${args[0].map(arg => `"${arg}"`).join(", ")}], ${args[1].toString()})`;
|
|
||||||
else if (method === "mapMangledModule") {
|
|
||||||
const failedMappings = Object.keys(args[1]).filter(key => result?.[key] == null);
|
|
||||||
|
|
||||||
logMessage += `("${args[0]}", {\n${failedMappings.map(mapping => `\t${mapping}: ${args[1][mapping].toString().slice(0, 147)}...`).join(",\n")}\n})`;
|
let filterName = "";
|
||||||
|
let parsedArgs = args;
|
||||||
|
|
||||||
|
if (args[0].$$vencordProps != null) {
|
||||||
|
if (["find", "findComponent", "waitFor"].includes(searchType)) {
|
||||||
|
filterName = args[0].$$vencordProps[0];
|
||||||
|
parsedArgs = args[0].$$vencordProps.slice(1);
|
||||||
|
} else {
|
||||||
|
parsedArgs = args[0].$$vencordProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringifyFilter(code: Webpack.CodeFilterWithSingle) {
|
||||||
|
if (Array.isArray(code)) {
|
||||||
|
return `[${code.map(arg => arg instanceof RegExp ? String(arg) : JSON.stringify(arg)).join(", ")}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code instanceof RegExp ? String(code) : JSON.stringify(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if parsedArgs is the same as args, it means vencordProps of the filter was not available (like in normal filter functions),
|
||||||
|
// so log the filter function instead
|
||||||
|
if (
|
||||||
|
parsedArgs === args &&
|
||||||
|
["waitFor", "find", "findComponent", "webpackDependantLazy", "webpackDependantLazyComponent"].includes(searchType)
|
||||||
|
) {
|
||||||
|
let filter = String(parsedArgs[0]);
|
||||||
|
if (filter.length > 150) {
|
||||||
|
filter = filter.slice(0, 147) + "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
logMessage += `(${filter})`;
|
||||||
|
} else if (searchType === "extractAndLoadChunks") {
|
||||||
|
const [code, matcher] = parsedArgs;
|
||||||
|
|
||||||
|
let regexStr: string;
|
||||||
|
if (matcher === Webpack.DefaultExtractAndLoadChunksRegex) {
|
||||||
|
regexStr = "DefaultExtractAndLoadChunksRegex";
|
||||||
|
} else {
|
||||||
|
regexStr = String(matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
logMessage += `(${stringifyFilter(code)}, ${regexStr})`;
|
||||||
|
} else if (searchType === "mapMangledModule") {
|
||||||
|
const [code, mappers] = parsedArgs;
|
||||||
|
|
||||||
|
const parsedFailedMappers = Object.entries<any>(mappers)
|
||||||
|
.filter(([key]) =>
|
||||||
|
result == null ||
|
||||||
|
(result[key]?.[SYM_PROXY_INNER_GET] != null && result[key][SYM_PROXY_INNER_VALUE] == null) ||
|
||||||
|
(result[key]?.[SYM_LAZY_COMPONENT_INNER] != null && result[key][SYM_LAZY_COMPONENT_INNER]() == null)
|
||||||
|
)
|
||||||
|
.map(([key, filter]) => {
|
||||||
|
let parsedFilter: string;
|
||||||
|
|
||||||
|
if (filter.$$vencordProps != null) {
|
||||||
|
const filterName = filter.$$vencordProps[0];
|
||||||
|
parsedFilter = `${filterName}(${filter.$$vencordProps.slice(1).map((arg: any) => arg instanceof RegExp ? String(arg) : JSON.stringify(arg)).join(", ")})`;
|
||||||
|
} else {
|
||||||
|
parsedFilter = String(filter);
|
||||||
|
if (parsedFilter.length > 150) {
|
||||||
|
parsedFilter = parsedFilter.slice(0, 147) + "...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [key, parsedFilter];
|
||||||
|
});
|
||||||
|
|
||||||
|
logMessage += `(${stringifyFilter(code)}, {\n${parsedFailedMappers.map(([key, parsedFilter]) => `\t${key}: ${parsedFilter}`).join(",\n")}\n})`;
|
||||||
|
} else {
|
||||||
|
logMessage += `(${filterName.length ? `${filterName}(` : ""}${parsedArgs.map(stringifyFilter).join(", ")})${filterName.length ? ")" : ""}`;
|
||||||
}
|
}
|
||||||
else logMessage += `(${args.map(arg => `"${arg}"`).join(", ")})`;
|
|
||||||
|
|
||||||
ReporterLogger.log("Webpack Find Fail:", logMessage);
|
ReporterLogger.log("Webpack Find Fail:", logMessage);
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
|
|
||||||
ReporterLogger.log("Finished test");
|
ReporterLogger.log("Finished test");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -81,4 +204,5 @@ async function runReporter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runReporter();
|
// Run after the Vencord object has been created
|
||||||
|
setTimeout(runReporter, 0);
|
||||||
|
|
7
src/globals.d.ts
vendored
7
src/globals.d.ts
vendored
|
@ -64,13 +64,8 @@ declare global {
|
||||||
export var Vesktop: any;
|
export var Vesktop: any;
|
||||||
export var VesktopNative: any;
|
export var VesktopNative: any;
|
||||||
|
|
||||||
interface Window {
|
interface Window extends Record<PropertyKey, any> {
|
||||||
webpackChunkdiscord_app: {
|
|
||||||
push(chunk: any): any;
|
|
||||||
pop(): any;
|
|
||||||
};
|
|
||||||
_: LoDashStatic;
|
_: LoDashStatic;
|
||||||
[k: string]: any;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||||
|
import { WebpackRequire } from "webpack";
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
disableAnalytics: {
|
disableAnalytics: {
|
||||||
|
@ -81,9 +82,9 @@ export default definePlugin({
|
||||||
Object.defineProperty(Function.prototype, "g", {
|
Object.defineProperty(Function.prototype, "g", {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
|
|
||||||
set(v: any) {
|
set(this: WebpackRequire, globalObj: WebpackRequire["g"]) {
|
||||||
Object.defineProperty(this, "g", {
|
Object.defineProperty(this, "g", {
|
||||||
value: v,
|
value: globalObj,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
writable: true
|
writable: true
|
||||||
|
@ -92,11 +93,11 @@ export default definePlugin({
|
||||||
// Ensure this is most likely the Sentry WebpackInstance.
|
// Ensure this is most likely the Sentry WebpackInstance.
|
||||||
// Function.g is a very generic property and is not uncommon for another WebpackInstance (or even a React component: <g></g>) to include it
|
// Function.g is a very generic property and is not uncommon for another WebpackInstance (or even a React component: <g></g>) to include it
|
||||||
const { stack } = new Error();
|
const { stack } = new Error();
|
||||||
if (!(stack?.includes("discord.com") || stack?.includes("discordapp.com")) || !String(this).includes("exports:{}") || this.c != null) {
|
if (this.c != null || !stack?.includes("http") || !String(this).includes("exports:{}")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const assetPath = stack?.match(/\/assets\/.+?\.js/)?.[0];
|
const assetPath = stack.match(/http.+?(?=:\d+?:\d+?$)/m)?.[0];
|
||||||
if (!assetPath) {
|
if (!assetPath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +107,8 @@ export default definePlugin({
|
||||||
srcRequest.send();
|
srcRequest.send();
|
||||||
|
|
||||||
// Final condition to see if this is the Sentry WebpackInstance
|
// Final condition to see if this is the Sentry WebpackInstance
|
||||||
if (!srcRequest.responseText.includes("window.DiscordSentry=")) {
|
// This is matching window.DiscordSentry=, but without `window` to avoid issues on some proxies
|
||||||
|
if (!srcRequest.responseText.includes(".DiscordSentry=")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import BackupAndRestoreTab from "@components/VencordSettings/BackupAndRestoreTab";
|
import BackupAndRestoreTab from "@components/VencordSettings/BackupAndRestoreTab";
|
||||||
import CloudTab from "@components/VencordSettings/CloudTab";
|
import CloudTab from "@components/VencordSettings/CloudTab";
|
||||||
import PatchHelperTab from "@components/VencordSettings/PatchHelperTab";
|
import PatchHelperTab from "@components/VencordSettings/PatchHelperTab";
|
||||||
|
@ -33,11 +33,27 @@ import gitHash from "~git-hash";
|
||||||
type SectionType = "HEADER" | "DIVIDER" | "CUSTOM";
|
type SectionType = "HEADER" | "DIVIDER" | "CUSTOM";
|
||||||
type SectionTypes = Record<SectionType, SectionType>;
|
type SectionTypes = Record<SectionType, SectionType>;
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
settingsLocation: {
|
||||||
|
type: OptionType.SELECT,
|
||||||
|
description: "Where to put the Vencord settings section",
|
||||||
|
options: [
|
||||||
|
{ label: "At the very top", value: "top" },
|
||||||
|
{ label: "Above the Nitro section", value: "aboveNitro", default: true },
|
||||||
|
{ label: "Below the Nitro section", value: "belowNitro" },
|
||||||
|
{ label: "Above Activity Settings", value: "aboveActivity" },
|
||||||
|
{ label: "Below Activity Settings", value: "belowActivity" },
|
||||||
|
{ label: "At the very bottom", value: "bottom" },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
description: "Adds Settings UI and debug info",
|
description: "Adds Settings UI and debug info",
|
||||||
authors: [Devs.Ven, Devs.Megu],
|
authors: [Devs.Ven, Devs.Megu],
|
||||||
required: true,
|
required: true,
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
|
@ -136,12 +152,12 @@ export default definePlugin({
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
},
|
},
|
||||||
|
|
||||||
isRightSpot({ header, settings }: { header?: string; settings?: string[]; }) {
|
isRightSpot({ header, settingsChilds }: { header?: string; settingsChilds?: string[]; }) {
|
||||||
const firstChild = settings?.[0];
|
const firstChild = settingsChilds?.[0];
|
||||||
// lowest two elements... sanity backup
|
// lowest two elements... sanity backup
|
||||||
if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true;
|
if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true;
|
||||||
|
|
||||||
const { settingsLocation } = Settings.plugins.Settings;
|
const { settingsLocation } = settings.store;
|
||||||
|
|
||||||
if (settingsLocation === "bottom") return firstChild === "LOGOUT";
|
if (settingsLocation === "bottom") return firstChild === "LOGOUT";
|
||||||
if (settingsLocation === "belowActivity") return firstChild === "CHANGELOG";
|
if (settingsLocation === "belowActivity") return firstChild === "CHANGELOG";
|
||||||
|
@ -181,21 +197,6 @@ export default definePlugin({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
options: {
|
|
||||||
settingsLocation: {
|
|
||||||
type: OptionType.SELECT,
|
|
||||||
description: "Where to put the Vencord settings section",
|
|
||||||
options: [
|
|
||||||
{ label: "At the very top", value: "top" },
|
|
||||||
{ label: "Above the Nitro section", value: "aboveNitro", default: true },
|
|
||||||
{ label: "Below the Nitro section", value: "belowNitro" },
|
|
||||||
{ label: "Above Activity Settings", value: "aboveActivity" },
|
|
||||||
{ label: "Below Activity Settings", value: "belowActivity" },
|
|
||||||
{ label: "At the very bottom", value: "bottom" },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
get electronVersion() {
|
get electronVersion() {
|
||||||
return VencordNative.native.getVersions().electron || window.armcord?.electron || null;
|
return VencordNative.native.getVersions().electron || window.armcord?.electron || null;
|
||||||
},
|
},
|
||||||
|
|
|
@ -59,7 +59,7 @@ const TrustedRolesIds = [
|
||||||
|
|
||||||
const AsyncFunction = async function () { }.constructor;
|
const AsyncFunction = async function () { }.constructor;
|
||||||
|
|
||||||
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
|
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame");
|
||||||
|
|
||||||
async function forceUpdate() {
|
async function forceUpdate() {
|
||||||
const outdated = await checkForUpdates();
|
const outdated = await checkForUpdates();
|
||||||
|
|
|
@ -21,12 +21,12 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
import { findByProps, findComponentByCode } from "@webpack";
|
||||||
|
|
||||||
type AnonUpload = Upload & { anonymise?: boolean; };
|
type AnonUpload = Upload & { anonymise?: boolean; };
|
||||||
|
|
||||||
const ActionBarIcon = findByCodeLazy(".actionBarIcon)");
|
const ActionBarIcon = findComponentByCode(".actionBarIcon)");
|
||||||
const UploadDraft = findByPropsLazy("popFirstFile", "update");
|
const UploadDraft = findByProps("popFirstFile", "update");
|
||||||
|
|
||||||
const enum Methods {
|
const enum Methods {
|
||||||
Random,
|
Random,
|
||||||
|
|
|
@ -20,10 +20,10 @@ import { popNotice, showNotice } from "@api/Notices";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { ReporterTestable } from "@utils/types";
|
import definePlugin, { ReporterTestable } from "@utils/types";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCode } from "@webpack";
|
||||||
import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common";
|
import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common";
|
||||||
|
|
||||||
const fetchApplicationsRPC = findByCodeLazy("APPLICATION_RPC(", "Client ID");
|
const fetchApplicationsRPC = findByCode("APPLICATION_RPC(", "Client ID");
|
||||||
|
|
||||||
async function lookupAsset(applicationId: string, key: string): Promise<string> {
|
async function lookupAsset(applicationId: string, key: string): Promise<string> {
|
||||||
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
|
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
|
||||||
|
|
|
@ -17,15 +17,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByProps, findComponentByCode, findStore } from "@webpack";
|
||||||
import { useStateFromStores } from "@webpack/common";
|
import { useStateFromStores } from "@webpack/common";
|
||||||
import type { CSSProperties } from "react";
|
import type { CSSProperties } from "react";
|
||||||
|
|
||||||
import { ExpandedGuildFolderStore, settings } from ".";
|
import { ExpandedGuildFolderStore, settings } from ".";
|
||||||
|
|
||||||
const ChannelRTCStore = findStoreLazy("ChannelRTCStore");
|
const ChannelRTCStore = findStore("ChannelRTCStore");
|
||||||
const Animations = findByPropsLazy("a", "animated", "useTransition");
|
const Animations = findByProps("a", "animated", "useTransition");
|
||||||
const GuildsBar = findComponentByCodeLazy('("guildsnav")');
|
const GuildsBar = findComponentByCode('("guildsnav")');
|
||||||
|
|
||||||
export default ErrorBoundary.wrap(guildsBarProps => {
|
export default ErrorBoundary.wrap(guildsBarProps => {
|
||||||
const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());
|
const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
|
import { find, findByProps, findStore } from "@webpack";
|
||||||
import { FluxDispatcher, i18n, useMemo } from "@webpack/common";
|
import { FluxDispatcher, i18n, useMemo } from "@webpack/common";
|
||||||
|
|
||||||
import FolderSideBar from "./FolderSideBar";
|
import FolderSideBar from "./FolderSideBar";
|
||||||
|
@ -30,10 +30,10 @@ enum FolderIconDisplay {
|
||||||
MoreThanOneFolderExpanded
|
MoreThanOneFolderExpanded
|
||||||
}
|
}
|
||||||
|
|
||||||
const GuildsTree = findLazy(m => m.prototype?.moveNextTo);
|
const GuildsTree = find(m => m.prototype?.moveNextTo);
|
||||||
const SortedGuildStore = findStoreLazy("SortedGuildStore");
|
const SortedGuildStore = findStore("SortedGuildStore");
|
||||||
export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore");
|
export const ExpandedGuildFolderStore = findStore("ExpandedGuildFolderStore");
|
||||||
const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand");
|
const FolderUtils = findByProps("move", "toggleGuildFolderExpand");
|
||||||
|
|
||||||
let lastGuildId = null as string | null;
|
let lastGuildId = null as string | null;
|
||||||
let dispatchingFoldersClose = false;
|
let dispatchingFoldersClose = false;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
@ -31,7 +31,7 @@ const settings = definePluginSettings({
|
||||||
noSpellCheck: {
|
noSpellCheck: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Disable spellcheck in notes",
|
description: "Disable spellcheck in notes",
|
||||||
disabled: () => Settings.plugins.BetterNotesBox.hide,
|
disabled: () => settings.store.hide,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,12 +10,12 @@ import { ImageIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { getCurrentGuild, openImageModal } from "@utils/discord";
|
import { getCurrentGuild, openImageModal } from "@utils/discord";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Clipboard, GuildStore, Menu, PermissionStore } from "@webpack/common";
|
import { Clipboard, GuildStore, Menu, PermissionStore } from "@webpack/common";
|
||||||
|
|
||||||
const GuildSettingsActions = findByPropsLazy("open", "selectRole", "updateGuild");
|
const GuildSettingsActions = findByProps("open", "selectRole", "updateGuild");
|
||||||
|
|
||||||
const DeveloperMode = getUserSettingLazy("appearance", "developerMode")!;
|
const DeveloperMode = getUserSettingLazy("appearance", "developerMode");
|
||||||
|
|
||||||
function PencilIcon() {
|
function PencilIcon() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -16,16 +16,32 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { Clipboard, Toasts } from "@webpack/common";
|
import { Clipboard, Toasts } from "@webpack/common";
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
bothStyles: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Show both role dot and coloured names",
|
||||||
|
restartNeeded: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
copyRoleColorInProfilePopout: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Allow click on role dot in profile popout to copy role color",
|
||||||
|
restartNeeded: true,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "BetterRoleDot",
|
name: "BetterRoleDot",
|
||||||
authors: [Devs.Ven, Devs.AutumnVN],
|
authors: [Devs.Ven, Devs.AutumnVN],
|
||||||
description:
|
description:
|
||||||
"Copy role colour on RoleDot (accessibility setting) click. Also allows using both RoleDot and coloured names simultaneously",
|
"Copy role colour on RoleDot (accessibility setting) click. Also allows using both RoleDot and coloured names simultaneously",
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
|
@ -39,7 +55,7 @@ export default definePlugin({
|
||||||
find: '"dot"===',
|
find: '"dot"===',
|
||||||
all: true,
|
all: true,
|
||||||
noWarn: true,
|
noWarn: true,
|
||||||
predicate: () => Settings.plugins.BetterRoleDot.bothStyles,
|
predicate: () => settings.store.bothStyles,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /"(?:username|dot)"===\i(?!\.\i)/g,
|
match: /"(?:username|dot)"===\i(?!\.\i)/g,
|
||||||
replace: "true",
|
replace: "true",
|
||||||
|
@ -49,7 +65,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".ADD_ROLE_A11Y_LABEL",
|
find: ".ADD_ROLE_A11Y_LABEL",
|
||||||
all: true,
|
all: true,
|
||||||
predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles,
|
predicate: () => settings.store.copyRoleColorInProfilePopout && !settings.store.bothStyles,
|
||||||
noWarn: true,
|
noWarn: true,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /"dot"===\i/,
|
match: /"dot"===\i/,
|
||||||
|
@ -59,7 +75,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".roleVerifiedIcon",
|
find: ".roleVerifiedIcon",
|
||||||
all: true,
|
all: true,
|
||||||
predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles,
|
predicate: () => settings.store.copyRoleColorInProfilePopout && !settings.store.bothStyles,
|
||||||
noWarn: true,
|
noWarn: true,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /"dot"===\i/,
|
match: /"dot"===\i/,
|
||||||
|
@ -68,21 +84,6 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
options: {
|
|
||||||
bothStyles: {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
description: "Show both role dot and coloured names",
|
|
||||||
restartNeeded: true,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
copyRoleColorInProfilePopout: {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
description: "Allow click on role dot in profile popout to copy role color",
|
|
||||||
restartNeeded: true,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
copyToClipBoard(color: string) {
|
copyToClipBoard(color: string) {
|
||||||
Clipboard.copy(color);
|
Clipboard.copy(color);
|
||||||
Toasts.show({
|
Toasts.show({
|
||||||
|
|
|
@ -21,20 +21,20 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy, findExportedComponentLazy, findStoreLazy } from "@webpack";
|
import { findByProps, findExportedComponent, findStore } from "@webpack";
|
||||||
import { Constants, React, RestAPI, Tooltip } from "@webpack/common";
|
import { Constants, React, RestAPI, Tooltip } from "@webpack/common";
|
||||||
|
|
||||||
import { RenameButton } from "./components/RenameButton";
|
import { RenameButton } from "./components/RenameButton";
|
||||||
import { Session, SessionInfo } from "./types";
|
import { Session, SessionInfo } from "./types";
|
||||||
import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
|
import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
|
||||||
|
|
||||||
const AuthSessionsStore = findStoreLazy("AuthSessionsStore");
|
const AuthSessionsStore = findStore("AuthSessionsStore");
|
||||||
const UserSettingsModal = findByPropsLazy("saveAccountChanges", "open");
|
const UserSettingsModal = findByProps("saveAccountChanges", "open");
|
||||||
|
|
||||||
const TimestampClasses = findByPropsLazy("timestampTooltip", "blockquoteContainer");
|
const TimestampClasses = findByProps("timestampTooltip", "blockquoteContainer");
|
||||||
const SessionIconClasses = findByPropsLazy("sessionIcon");
|
const SessionIconClasses = findByProps("sessionIcon");
|
||||||
|
|
||||||
const BlobMask = findExportedComponentLazy("BlobMask");
|
const BlobMask = findExportedComponent("BlobMask");
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
backgroundCheck: {
|
backgroundCheck: {
|
||||||
|
|
|
@ -8,16 +8,17 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
|
import { SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
|
||||||
|
import { NoopComponent } from "@utils/react";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { waitFor } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { ComponentDispatch, FocusLock, i18n, Menu, useEffect, useRef } from "@webpack/common";
|
import { ComponentDispatch, FocusLock, i18n, Menu, useEffect, useRef } from "@webpack/common";
|
||||||
import type { HTMLAttributes, ReactElement } from "react";
|
import type { HTMLAttributes, ReactElement } from "react";
|
||||||
|
|
||||||
type SettingsEntry = { section: string, label: string; };
|
type SettingsEntry = { section: string, label: string; };
|
||||||
|
|
||||||
const cl = classNameFactory("");
|
const cl = classNameFactory("");
|
||||||
let Classes: Record<string, string>;
|
const Classes = findByProps("animating", "baseLayer", "bg", "layer", "layers");
|
||||||
waitFor(["animating", "baseLayer", "bg", "layer", "layers"], m => Classes = m);
|
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
disableFade: {
|
disableFade: {
|
||||||
|
@ -132,7 +133,7 @@ export default definePlugin({
|
||||||
// try catch will only catch errors in the Layer function (hence why it's called as a plain function rather than a component), but
|
// try catch will only catch errors in the Layer function (hence why it's called as a plain function rather than a component), but
|
||||||
// not in children
|
// not in children
|
||||||
Layer(props: LayerProps) {
|
Layer(props: LayerProps) {
|
||||||
if (!FocusLock || !ComponentDispatch || !Classes) {
|
if (FocusLock === NoopComponent || ComponentDispatch[SYM_PROXY_INNER_VALUE] == null || Classes[SYM_PROXY_INNER_VALUE] == null) {
|
||||||
new Logger("BetterSettings").error("Failed to find some components");
|
new Logger("BetterSettings").error("Failed to find some components");
|
||||||
return props.children;
|
return props.children;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
|
|
||||||
import * as t from "./types/stores";
|
import * as t from "./types/stores";
|
||||||
|
|
||||||
export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore");
|
export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStore("ApplicationStreamPreviewStore");
|
||||||
export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore");
|
export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStore("ApplicationStreamingStore");
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ function setCss() {
|
||||||
style.textContent = `
|
style.textContent = `
|
||||||
.vc-nsfw-img [class^=imageWrapper] img,
|
.vc-nsfw-img [class^=imageWrapper] img,
|
||||||
.vc-nsfw-img [class^=wrapperPaused] video {
|
.vc-nsfw-img [class^=wrapperPaused] video {
|
||||||
filter: blur(${Settings.plugins.BlurNSFW.blurAmount}px);
|
filter: blur(${settings.store.blurAmount}px);
|
||||||
transition: filter 0.2s;
|
transition: filter 0.2s;
|
||||||
}
|
}
|
||||||
.vc-nsfw-img [class^=imageWrapper]:hover img,
|
.vc-nsfw-img [class^=imageWrapper]:hover img,
|
||||||
|
@ -36,10 +36,20 @@ function setCss() {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
blurAmount: {
|
||||||
|
type: OptionType.NUMBER,
|
||||||
|
description: "Blur Amount",
|
||||||
|
default: 10,
|
||||||
|
onChange: setCss
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "BlurNSFW",
|
name: "BlurNSFW",
|
||||||
description: "Blur attachments in NSFW channels until hovered",
|
description: "Blur attachments in NSFW channels until hovered",
|
||||||
authors: [Devs.Ven],
|
authors: [Devs.Ven],
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
|
@ -51,15 +61,6 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
options: {
|
|
||||||
blurAmount: {
|
|
||||||
type: OptionType.NUMBER,
|
|
||||||
description: "Blur Amount",
|
|
||||||
default: 10,
|
|
||||||
onChange: setCss
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
style = document.createElement("style");
|
style = document.createElement("style");
|
||||||
style.id = "VcBlurNsfw";
|
style.id = "VcBlurNsfw";
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { useTimer } from "@utils/react";
|
import { useTimer } from "@utils/react";
|
||||||
|
@ -25,7 +25,7 @@ import { React } from "@webpack/common";
|
||||||
|
|
||||||
function formatDuration(ms: number) {
|
function formatDuration(ms: number) {
|
||||||
// here be dragons (moment fucking sucks)
|
// here be dragons (moment fucking sucks)
|
||||||
const human = Settings.plugins.CallTimer.format === "human";
|
const human = settings.store.format === "human";
|
||||||
|
|
||||||
const format = (n: number) => human ? n : n.toString().padStart(2, "0");
|
const format = (n: number) => human ? n : n.toString().padStart(2, "0");
|
||||||
const unit = (s: string) => human ? s : "";
|
const unit = (s: string) => human ? s : "";
|
||||||
|
@ -46,15 +46,7 @@ function formatDuration(ms: number) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
const settings = definePluginSettings({
|
||||||
name: "CallTimer",
|
|
||||||
description: "Adds a timer to vcs",
|
|
||||||
authors: [Devs.Ven],
|
|
||||||
|
|
||||||
startTime: 0,
|
|
||||||
interval: void 0 as NodeJS.Timeout | undefined,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
format: {
|
format: {
|
||||||
type: OptionType.SELECT,
|
type: OptionType.SELECT,
|
||||||
description: "The timer format. This can be any valid moment.js format",
|
description: "The timer format. This can be any valid moment.js format",
|
||||||
|
@ -70,7 +62,16 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "CallTimer",
|
||||||
|
description: "Adds a timer to vcs",
|
||||||
|
authors: [Devs.Ven],
|
||||||
|
settings,
|
||||||
|
|
||||||
|
startTime: 0,
|
||||||
|
interval: void 0 as NodeJS.Timeout | undefined,
|
||||||
|
|
||||||
patches: [{
|
patches: [{
|
||||||
find: "renderConnectionStatus(){",
|
find: "renderConnectionStatus(){",
|
||||||
|
|
|
@ -11,10 +11,10 @@ import { Devs } from "@utils/constants";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||||
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCode, findComponentByCode, findStore } from "@webpack";
|
||||||
import { Button, Forms, useStateFromStores } from "@webpack/common";
|
import { Button, Forms, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
||||||
|
|
||||||
const colorPresets = [
|
const colorPresets = [
|
||||||
"#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D",
|
"#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D",
|
||||||
|
@ -30,21 +30,21 @@ function onPickColor(color: number) {
|
||||||
updateColorVars(hexColor);
|
updateColorVars(hexColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"===');
|
const saveClientTheme = findByCode('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"===');
|
||||||
|
|
||||||
function setTheme(theme: string) {
|
function setTheme(theme: string) {
|
||||||
saveClientTheme({ theme });
|
saveClientTheme({ theme });
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThemeStore = findStoreLazy("ThemeStore");
|
const ThemeStore = findStore("ThemeStore");
|
||||||
const NitroThemeStore = findStoreLazy("ClientThemesBackgroundStore");
|
const ClientThemesBackgroundStore = findStore("ClientThemesBackgroundStore");
|
||||||
|
|
||||||
function ThemeSettings() {
|
function ThemeSettings() {
|
||||||
const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme);
|
const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme);
|
||||||
const isLightTheme = theme === "light";
|
const isLightTheme = theme === "light";
|
||||||
const oppositeTheme = isLightTheme ? "dark" : "light";
|
const oppositeTheme = isLightTheme ? "dark" : "light";
|
||||||
|
|
||||||
const nitroTheme = useStateFromStores([NitroThemeStore], () => NitroThemeStore.gradientPreset);
|
const nitroTheme = useStateFromStores([ClientThemesBackgroundStore], () => ClientThemesBackgroundStore.gradientPreset);
|
||||||
const nitroThemeEnabled = nitroTheme !== undefined;
|
const nitroThemeEnabled = nitroTheme !== undefined;
|
||||||
|
|
||||||
const selectedLuminance = relativeLuminance(settings.store.color);
|
const selectedLuminance = relativeLuminance(settings.store.color);
|
||||||
|
|
|
@ -19,11 +19,13 @@
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { getCurrentChannel, getCurrentGuild } from "@utils/discord";
|
import { getCurrentChannel, getCurrentGuild } from "@utils/discord";
|
||||||
import { SYM_LAZY_CACHED, SYM_LAZY_GET } from "@utils/lazy";
|
import { SYM_LAZY_CACHED, SYM_LAZY_GET } from "@utils/lazy";
|
||||||
|
import { SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact";
|
||||||
import { relaunch } from "@utils/native";
|
import { relaunch } from "@utils/native";
|
||||||
import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches";
|
import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches";
|
||||||
|
import { SYM_PROXY_INNER_GET, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
|
||||||
import definePlugin, { PluginNative, StartAt } from "@utils/types";
|
import definePlugin, { PluginNative, StartAt } from "@utils/types";
|
||||||
import * as Webpack from "@webpack";
|
import * as Webpack from "@webpack";
|
||||||
import { extract, filters, findAll, findModuleId, search } from "@webpack";
|
import { cacheFindAll, cacheFindModuleId, extract, filters, searchFactories } from "@webpack";
|
||||||
import * as Common from "@webpack/common";
|
import * as Common from "@webpack/common";
|
||||||
import { loadLazyChunks } from "debug/loadLazyChunks";
|
import { loadLazyChunks } from "debug/loadLazyChunks";
|
||||||
import type { ComponentType } from "react";
|
import type { ComponentType } from "react";
|
||||||
|
@ -32,27 +34,29 @@ const DESKTOP_ONLY = (f: string) => () => {
|
||||||
throw new Error(`'${f}' is Discord Desktop only.`);
|
throw new Error(`'${f}' is Discord Desktop only.`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const define: typeof Object.defineProperty =
|
|
||||||
(obj, prop, desc) => {
|
|
||||||
if (Object.hasOwn(desc, "value"))
|
|
||||||
desc.writable = true;
|
|
||||||
|
|
||||||
return Object.defineProperty(obj, prop, {
|
type Define = typeof Object.defineProperty;
|
||||||
|
const define: Define = (target, p, attributes) => {
|
||||||
|
if (Object.hasOwn(attributes, "value")) {
|
||||||
|
attributes.writable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.defineProperty(target, p, {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
...desc
|
...attributes
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeShortcuts() {
|
function makeShortcuts() {
|
||||||
function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn) {
|
function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn, shouldReturnFactory = false) {
|
||||||
const cache = new Map<string, unknown>();
|
const cache = new Map<string, unknown>();
|
||||||
|
|
||||||
return function (...filterProps: unknown[]) {
|
return function (...filterProps: unknown[]) {
|
||||||
const cacheKey = String(filterProps);
|
const cacheKey = String(filterProps);
|
||||||
if (cache.has(cacheKey)) return cache.get(cacheKey);
|
if (cache.has(cacheKey)) return cache.get(cacheKey);
|
||||||
|
|
||||||
const matches = findAll(filterFactory(...filterProps));
|
const matches = cacheFindAll(filterFactory(...filterProps), shouldReturnFactory);
|
||||||
|
|
||||||
const result = (() => {
|
const result = (() => {
|
||||||
switch (matches.length) {
|
switch (matches.length) {
|
||||||
|
@ -60,50 +64,71 @@ function makeShortcuts() {
|
||||||
case 1: return matches[0];
|
case 1: return matches[0];
|
||||||
default:
|
default:
|
||||||
const uniqueMatches = [...new Set(matches)];
|
const uniqueMatches = [...new Set(matches)];
|
||||||
if (uniqueMatches.length > 1)
|
if (uniqueMatches.length > 1) {
|
||||||
console.warn(`Warning: This filter matches ${matches.length} modules. Make it more specific!\n`, uniqueMatches);
|
console.warn(`Warning: This filter matches ${matches.length} modules. Make it more specific!\n`, uniqueMatches);
|
||||||
|
}
|
||||||
|
|
||||||
return matches[0];
|
return uniqueMatches[0];
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if (result && cacheKey) cache.set(cacheKey, result);
|
if (result && cacheKey) cache.set(cacheKey, result);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let fakeRenderWin: WeakRef<Window> | undefined;
|
let fakeRenderWin: WeakRef<Window> | undefined;
|
||||||
|
|
||||||
const find = newFindWrapper(f => f);
|
const find = newFindWrapper(f => f);
|
||||||
const findByProps = newFindWrapper(filters.byProps);
|
const findByProps = newFindWrapper(filters.byProps);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...Object.fromEntries(Object.keys(Common).map(key => [key, { getter: () => Common[key] }])),
|
|
||||||
wp: Webpack,
|
wp: Webpack,
|
||||||
wpc: { getter: () => Webpack.cache },
|
wpc: { getter: () => Webpack.cache },
|
||||||
wreq: { getter: () => Webpack.wreq },
|
wreq: { getter: () => Webpack.wreq },
|
||||||
wpsearch: search,
|
|
||||||
wpex: extract,
|
WebpackInstances: { getter: () => Vencord.WebpackPatcher.allWebpackInstances },
|
||||||
wpexs: (code: string) => extract(findModuleId(code)!),
|
|
||||||
loadLazyChunks: IS_DEV ? loadLazyChunks : () => { throw new Error("loadLazyChunks is dev only."); },
|
loadLazyChunks: IS_DEV ? loadLazyChunks : () => { throw new Error("loadLazyChunks is dev only."); },
|
||||||
|
|
||||||
|
wpsearch: searchFactories,
|
||||||
|
wpex: extract,
|
||||||
|
wpexs: (...code: Webpack.CodeFilter) => extract(cacheFindModuleId(...code)!),
|
||||||
|
|
||||||
|
filters,
|
||||||
find,
|
find,
|
||||||
findAll: findAll,
|
findAll: cacheFindAll,
|
||||||
findByProps,
|
findComponent: find,
|
||||||
findAllByProps: (...props: string[]) => findAll(filters.byProps(...props)),
|
findAllComponents: cacheFindAll,
|
||||||
findByCode: newFindWrapper(filters.byCode),
|
findExportedComponent: (...props: Webpack.PropsFilter) => findByProps(...props)[props[0]],
|
||||||
findAllByCode: (code: string) => findAll(filters.byCode(code)),
|
|
||||||
findComponentByCode: newFindWrapper(filters.componentByCode),
|
findComponentByCode: newFindWrapper(filters.componentByCode),
|
||||||
findAllComponentsByCode: (...code: string[]) => findAll(filters.componentByCode(...code)),
|
findAllComponentsByCode: (...code: Webpack.PropsFilter) => cacheFindAll(filters.componentByCode(...code)),
|
||||||
findExportedComponent: (...props: string[]) => findByProps(...props)[props[0]],
|
findComponentByFields: newFindWrapper(filters.componentByFields),
|
||||||
|
findAllComponentsByFields: (...fields: Webpack.PropsFilter) => cacheFindAll(filters.componentByFields(...fields)),
|
||||||
|
findByProps,
|
||||||
|
findAllByProps: (...props: Webpack.PropsFilter) => cacheFindAll(filters.byProps(...props)),
|
||||||
|
findProp: (...props: Webpack.PropsFilter) => findByProps(...props)[props[0]],
|
||||||
|
findByCode: newFindWrapper(filters.byCode),
|
||||||
|
findAllByCode: (code: Webpack.CodeFilter) => cacheFindAll(filters.byCode(...code)),
|
||||||
findStore: newFindWrapper(filters.byStoreName),
|
findStore: newFindWrapper(filters.byStoreName),
|
||||||
PluginsApi: { getter: () => Vencord.Plugins },
|
findByFactoryCode: newFindWrapper(filters.byFactoryCode),
|
||||||
|
findAllByFactoryCode: (...code: Webpack.CodeFilter) => cacheFindAll(filters.byFactoryCode(...code)),
|
||||||
|
findModuleFactory: newFindWrapper(filters.byFactoryCode, true),
|
||||||
|
findAllModuleFactories: (...code: Webpack.CodeFilter) => cacheFindAll(filters.byFactoryCode(...code), true),
|
||||||
|
|
||||||
plugins: { getter: () => Vencord.Plugins.plugins },
|
plugins: { getter: () => Vencord.Plugins.plugins },
|
||||||
|
PluginsApi: { getter: () => Vencord.Plugins },
|
||||||
Settings: { getter: () => Vencord.Settings },
|
Settings: { getter: () => Vencord.Settings },
|
||||||
Api: { getter: () => Vencord.Api },
|
Api: { getter: () => Vencord.Api },
|
||||||
Util: { getter: () => Vencord.Util },
|
Util: { getter: () => Vencord.Util },
|
||||||
|
|
||||||
reload: () => location.reload(),
|
reload: () => location.reload(),
|
||||||
restart: IS_WEB ? DESKTOP_ONLY("restart") : relaunch,
|
restart: IS_WEB ? DESKTOP_ONLY("restart") : relaunch,
|
||||||
|
|
||||||
canonicalizeMatch,
|
canonicalizeMatch,
|
||||||
canonicalizeReplace,
|
canonicalizeReplace,
|
||||||
canonicalizeReplacement,
|
canonicalizeReplacement,
|
||||||
|
|
||||||
|
preEnable: (plugin: string) => (Vencord.Settings.plugins[plugin] ??= { enabled: true }).enabled = true,
|
||||||
fakeRender: (component: ComponentType, props: any) => {
|
fakeRender: (component: ComponentType, props: any) => {
|
||||||
const prevWin = fakeRenderWin?.deref();
|
const prevWin = fakeRenderWin?.deref();
|
||||||
const win = prevWin?.closed === false
|
const win = prevWin?.closed === false
|
||||||
|
@ -133,8 +158,6 @@ function makeShortcuts() {
|
||||||
Common.ReactDOM.render(Common.React.createElement(component, props), doc.body.appendChild(document.createElement("div")));
|
Common.ReactDOM.render(Common.React.createElement(component, props), doc.body.appendChild(document.createElement("div")));
|
||||||
},
|
},
|
||||||
|
|
||||||
preEnable: (plugin: string) => (Vencord.Settings.plugins[plugin] ??= { enabled: true }).enabled = true,
|
|
||||||
|
|
||||||
channel: { getter: () => getCurrentChannel(), preload: false },
|
channel: { getter: () => getCurrentChannel(), preload: false },
|
||||||
channelId: { getter: () => Common.SelectedChannelStore.getChannelId(), preload: false },
|
channelId: { getter: () => Common.SelectedChannelStore.getChannelId(), preload: false },
|
||||||
guild: { getter: () => getCurrentGuild(), preload: false },
|
guild: { getter: () => getCurrentGuild(), preload: false },
|
||||||
|
@ -143,6 +166,7 @@ function makeShortcuts() {
|
||||||
meId: { getter: () => Common.UserStore.getCurrentUser().id, preload: false },
|
meId: { getter: () => Common.UserStore.getCurrentUser().id, preload: false },
|
||||||
messages: { getter: () => Common.MessageStore.getMessages(Common.SelectedChannelStore.getChannelId()), preload: false },
|
messages: { getter: () => Common.MessageStore.getMessages(Common.SelectedChannelStore.getChannelId()), preload: false },
|
||||||
|
|
||||||
|
...Object.fromEntries(Object.keys(Common).map(key => [key, { getter: () => Common[key] }])),
|
||||||
Stores: {
|
Stores: {
|
||||||
getter: () => Object.fromEntries(
|
getter: () => Object.fromEntries(
|
||||||
Common.Flux.Store.getAll()
|
Common.Flux.Store.getAll()
|
||||||
|
@ -157,11 +181,39 @@ function loadAndCacheShortcut(key: string, val: any, forceLoad: boolean) {
|
||||||
const currentVal = val.getter();
|
const currentVal = val.getter();
|
||||||
if (!currentVal || val.preload === false) return currentVal;
|
if (!currentVal || val.preload === false) return currentVal;
|
||||||
|
|
||||||
const value = currentVal[SYM_LAZY_GET]
|
function unwrapProxy(value: any) {
|
||||||
? forceLoad ? currentVal[SYM_LAZY_GET]() : currentVal[SYM_LAZY_CACHED]
|
if (value[SYM_LAZY_GET]) {
|
||||||
: currentVal;
|
return forceLoad ? value[SYM_LAZY_GET]() : value[SYM_LAZY_CACHED];
|
||||||
|
} else if (value[SYM_PROXY_INNER_GET]) {
|
||||||
|
return forceLoad ? value[SYM_PROXY_INNER_GET]() : value[SYM_PROXY_INNER_VALUE];
|
||||||
|
} else if (value[SYM_LAZY_COMPONENT_INNER]) {
|
||||||
|
return value[SYM_LAZY_COMPONENT_INNER]() != null ? value[SYM_LAZY_COMPONENT_INNER]() : value;
|
||||||
|
}
|
||||||
|
|
||||||
if (value) define(window.shortcutList, key, { value });
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = unwrapProxy(currentVal);
|
||||||
|
if (value != null && typeof value === "object") {
|
||||||
|
const descriptors = Object.getOwnPropertyDescriptors(value);
|
||||||
|
|
||||||
|
for (const propKey in descriptors) {
|
||||||
|
if (value[propKey] == null) continue;
|
||||||
|
|
||||||
|
const descriptor = descriptors[propKey];
|
||||||
|
if (descriptor.writable === true || descriptor.set != null) {
|
||||||
|
const currentValue = value[propKey];
|
||||||
|
const newValue = unwrapProxy(currentValue);
|
||||||
|
if (newValue != null && currentValue !== newValue) {
|
||||||
|
value[propKey] = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
define(window.shortcutList, key, { value });
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -176,8 +228,10 @@ export default definePlugin({
|
||||||
const shortcuts = makeShortcuts();
|
const shortcuts = makeShortcuts();
|
||||||
window.shortcutList = {};
|
window.shortcutList = {};
|
||||||
|
|
||||||
for (const [key, val] of Object.entries(shortcuts)) {
|
for (const key in shortcuts) {
|
||||||
if ("getter" in val) {
|
const val = shortcuts[key];
|
||||||
|
|
||||||
|
if (Object.hasOwn(val, "getter")) {
|
||||||
define(window.shortcutList, key, {
|
define(window.shortcutList, key, {
|
||||||
get: () => loadAndCacheShortcut(key, val, true)
|
get: () => loadAndCacheShortcut(key, val, true)
|
||||||
});
|
});
|
||||||
|
@ -191,8 +245,8 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unproxy loaded modules
|
// Unproxy loaded modules
|
||||||
Webpack.onceReady.then(() => {
|
Webpack.onceDiscordLoaded.then(() => {
|
||||||
setTimeout(() => this.eagerLoad(false), 1000);
|
setTimeout(() => this.eagerLoad(false), 1000);
|
||||||
|
|
||||||
if (!IS_WEB) {
|
if (!IS_WEB) {
|
||||||
|
@ -203,13 +257,13 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
async eagerLoad(forceLoad: boolean) {
|
async eagerLoad(forceLoad: boolean) {
|
||||||
await Webpack.onceReady;
|
await Webpack.onceDiscordLoaded;
|
||||||
|
|
||||||
const shortcuts = makeShortcuts();
|
const shortcuts = makeShortcuts();
|
||||||
|
for (const key in shortcuts) {
|
||||||
|
const val = shortcuts[key];
|
||||||
|
|
||||||
for (const [key, val] of Object.entries(shortcuts)) {
|
if (!Object.hasOwn(val, "getter") || val.preload === false) continue;
|
||||||
if (!Object.hasOwn(val, "getter") || (val as any).preload === false) continue;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadAndCacheShortcut(key, val, forceLoad);
|
loadAndCacheShortcut(key, val, forceLoad);
|
||||||
} catch { } // swallow not found errors in DEV
|
} catch { } // swallow not found errors in DEV
|
||||||
|
|
|
@ -8,10 +8,10 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { copyWithToast } from "@utils/misc";
|
import { copyWithToast } from "@utils/misc";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findProp } from "@webpack";
|
||||||
import { Menu } from "@webpack/common";
|
import { Menu } from "@webpack/common";
|
||||||
|
|
||||||
const { convertNameToSurrogate } = findByPropsLazy("convertNameToSurrogate");
|
const convertNameToSurrogate = findProp("convertNameToSurrogate");
|
||||||
|
|
||||||
interface Emoji {
|
interface Emoji {
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -55,7 +55,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
contextMenus: {
|
contextMenus: {
|
||||||
"expression-picker"(children, { target }: { target: Target }) {
|
"expression-picker"(children, { target }: { target: Target; }) {
|
||||||
if (target.dataset.type !== "emoji") return;
|
if (target.dataset.type !== "emoji") return;
|
||||||
|
|
||||||
children.push(
|
children.push(
|
||||||
|
|
|
@ -23,22 +23,12 @@ import { Logger } from "@utils/Logger";
|
||||||
import { closeAllModals } from "@utils/modal";
|
import { closeAllModals } from "@utils/modal";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { maybePromptToUpdate } from "@utils/updater";
|
import { maybePromptToUpdate } from "@utils/updater";
|
||||||
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { DraftType, ExpressionPickerStore, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
|
import { DraftType, ExpressionPickerStore, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
|
||||||
|
|
||||||
const CrashHandlerLogger = new Logger("CrashHandler");
|
const CrashHandlerLogger = new Logger("CrashHandler");
|
||||||
|
const ModalStack = findByProps("pushLazy", "popAll");
|
||||||
const { ModalStack, DraftManager } = proxyLazyWebpack(() => {
|
const DraftManager = findByProps("clearDraft", "saveDraft");
|
||||||
const [ModalStack, DraftManager] = findBulk(
|
|
||||||
filters.byProps("pushLazy", "popAll"),
|
|
||||||
filters.byProps("clearDraft", "saveDraft"),
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
ModalStack,
|
|
||||||
DraftManager
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
attemptToPreventCrashes: {
|
attemptToPreventCrashes: {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { getUserSettingLazy } from "@api/UserSettings";
|
import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
import { ErrorCard } from "@components/ErrorCard";
|
import { ErrorCard } from "@components/ErrorCard";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
|
@ -26,14 +26,14 @@ import { Margins } from "@utils/margins";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByCode, findByProps, findComponentByCode } from "@webpack";
|
||||||
import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common";
|
import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
const useProfileThemeStyle = findByCodeLazy("profileThemeStyle:", "--profile-gradient-primary-color");
|
const useProfileThemeStyle = findByCode("profileThemeStyle:", "--profile-gradient-primary-color");
|
||||||
const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile");
|
const ActivityComponent = findComponentByCode("onOpenGameProfile");
|
||||||
const ActivityClassName = findByPropsLazy("activity", "buttonColor");
|
const ActivityClassName = findByProps("activity", "buttonColor");
|
||||||
|
|
||||||
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
|
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame");
|
||||||
|
|
||||||
async function getApplicationAsset(key: string): Promise<string> {
|
async function getApplicationAsset(key: string): Promise<string> {
|
||||||
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
|
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
|
||||||
|
@ -261,7 +261,7 @@ const settings = definePluginSettings({
|
||||||
|
|
||||||
function onChange() {
|
function onChange() {
|
||||||
setRpc(true);
|
setRpc(true);
|
||||||
if (Settings.plugins.CustomRPC.enabled) setRpc();
|
if (Vencord.Plugins.isPluginEnabled("CustomRPC")) setRpc();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isStreamLinkDisabled() {
|
function isStreamLinkDisabled() {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findComponentByCode } from "@webpack";
|
||||||
import { Button, useEffect } from "@webpack/common";
|
import { Button, useEffect } from "@webpack/common";
|
||||||
|
|
||||||
import { useAuthorizationStore } from "../../lib/stores/AuthorizationStore";
|
import { useAuthorizationStore } from "../../lib/stores/AuthorizationStore";
|
||||||
|
@ -13,7 +13,7 @@ import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDeco
|
||||||
import { cl } from "../";
|
import { cl } from "../";
|
||||||
import { openChangeDecorationModal } from "../modals/ChangeDecorationModal";
|
import { openChangeDecorationModal } from "../modals/ChangeDecorationModal";
|
||||||
|
|
||||||
const CustomizationSection = findByCodeLazy(".customizationSectionBackground");
|
const CustomizationSection = findComponentByCode(".customizationSectionBackground");
|
||||||
|
|
||||||
export interface DecorSectionProps {
|
export interface DecorSectionProps {
|
||||||
hideTitle?: boolean;
|
hideTitle?: boolean;
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { React } from "@webpack/common";
|
import { React } from "@webpack/common";
|
||||||
|
|
||||||
import { cl } from "../";
|
import { cl } from "../";
|
||||||
import Grid, { GridProps } from "./Grid";
|
import Grid, { GridProps } from "./Grid";
|
||||||
|
|
||||||
const ScrollerClasses = findByPropsLazy("managedReactiveScroller");
|
const ScrollerClasses = findByProps("managedReactiveScroller");
|
||||||
|
|
||||||
type Section<SectionT, ItemT> = SectionT & {
|
type Section<SectionT, ItemT> = SectionT & {
|
||||||
items: Array<ItemT>;
|
items: Array<ItemT>;
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findComponentByCode, LazyComponentWebpack } from "@webpack";
|
import { NoopComponent } from "@utils/react";
|
||||||
|
import { findComponentByCode } from "@webpack";
|
||||||
import { React } from "@webpack/common";
|
import { React } from "@webpack/common";
|
||||||
import type { ComponentType, HTMLProps, PropsWithChildren } from "react";
|
import type { ComponentType, HTMLProps, PropsWithChildren } from "react";
|
||||||
|
|
||||||
|
@ -15,13 +16,10 @@ type DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTM
|
||||||
isSelected: boolean,
|
isSelected: boolean,
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export let DecorationGridItem: DecorationGridItemComponent;
|
export let DecorationGridItem: DecorationGridItemComponent = NoopComponent;
|
||||||
export const setDecorationGridItem = v => DecorationGridItem = v;
|
export const setDecorationGridItem = v => DecorationGridItem = v;
|
||||||
|
|
||||||
export const AvatarDecorationModalPreview = LazyComponentWebpack(() => {
|
export const AvatarDecorationModalPreview = findComponentByCode<any>(".shopPreviewBanner", component => React.memo(component));
|
||||||
const component = findComponentByCode(".shopPreviewBanner");
|
|
||||||
return React.memo(component);
|
|
||||||
});
|
|
||||||
|
|
||||||
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
|
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
|
||||||
avatarDecoration: AvatarDecoration;
|
avatarDecoration: AvatarDecoration;
|
||||||
|
@ -29,5 +27,5 @@ type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivEl
|
||||||
isSelected: boolean,
|
isSelected: boolean,
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export let DecorationGridDecoration: DecorationGridDecorationComponent;
|
export let DecorationGridDecoration: DecorationGridDecorationComponent = NoopComponent;
|
||||||
export const setDecorationGridDecoration = v => DecorationGridDecoration = v;
|
export const setDecorationGridDecoration = v => DecorationGridDecoration = v;
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack";
|
import { extractAndLoadChunksLazy, findByProps } from "@webpack";
|
||||||
|
|
||||||
export const cl = classNameFactory("vc-decor-");
|
export const cl = classNameFactory("vc-decor-");
|
||||||
export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton");
|
export const DecorationModalStyles = findByProps("modalFooterShopButton");
|
||||||
|
|
||||||
export const requireAvatarDecorationModal = extractAndLoadChunksLazy([".COLLECTIBLES_SHOP_FULLSCREEN&&"]);
|
export const requireAvatarDecorationModal = extractAndLoadChunksLazy(".COLLECTIBLES_SHOP_FULLSCREEN&&");
|
||||||
export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]);
|
export const requireCreateStickerModal = extractAndLoadChunksLazy("stickerInspected]:");
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { openInviteModal } from "@utils/discord";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes, copyWithToast } from "@utils/misc";
|
import { classes, copyWithToast } from "@utils/misc";
|
||||||
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { findComponentByCodeLazy } from "@webpack";
|
import { findComponentByCode } from "@webpack";
|
||||||
import { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from "@webpack/common";
|
import { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ import SectionedGridList from "../components/SectionedGridList";
|
||||||
import { openCreateDecorationModal } from "./CreateDecorationModal";
|
import { openCreateDecorationModal } from "./CreateDecorationModal";
|
||||||
import { openGuidelinesModal } from "./GuidelinesModal";
|
import { openGuidelinesModal } from "./GuidelinesModal";
|
||||||
|
|
||||||
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
|
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
|
||||||
|
|
||||||
function usePresets() {
|
function usePresets() {
|
||||||
const [presets, setPresets] = useState<Preset[]>([]);
|
const [presets, setPresets] = useState<Preset[]>([]);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { Link } from "@components/Link";
|
||||||
import { openInviteModal } from "@utils/discord";
|
import { openInviteModal } from "@utils/discord";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { filters, findComponentByCodeLazy, mapMangledModuleLazy } from "@webpack";
|
import { filters, findComponentByCode, mapMangledModule } from "@webpack";
|
||||||
import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common";
|
import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common";
|
||||||
|
|
||||||
import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants";
|
import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants";
|
||||||
|
@ -17,11 +17,11 @@ import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDeco
|
||||||
import { cl, DecorationModalStyles, requireAvatarDecorationModal, requireCreateStickerModal } from "../";
|
import { cl, DecorationModalStyles, requireAvatarDecorationModal, requireCreateStickerModal } from "../";
|
||||||
import { AvatarDecorationModalPreview } from "../components";
|
import { AvatarDecorationModalPreview } from "../components";
|
||||||
|
|
||||||
const FileUpload = findComponentByCodeLazy("fileUploadInput,");
|
const FileUpload = findComponentByCode("fileUploadInput,");
|
||||||
|
|
||||||
const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE=3]="POSITIVE', {
|
const { HelpMessage, HelpMessageTypes } = mapMangledModule('POSITIVE=3]="POSITIVE', {
|
||||||
|
HelpMessage: filters.componentByCode(".iconDiv,", "messageType"),
|
||||||
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"),
|
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"),
|
||||||
HelpMessage: filters.byCode(".iconDiv")
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function useObjectURL(object: Blob | MediaSource | null) {
|
function useObjectURL(object: Blob | MediaSource | null) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
|
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
|
||||||
import definePlugin, { OptionType, ReporterTestable } from "@utils/types";
|
import definePlugin, { OptionType, ReporterTestable } from "@utils/types";
|
||||||
import { filters, findAll, search } from "@webpack";
|
import { cacheFindAll, filters, searchFactories } from "@webpack";
|
||||||
|
|
||||||
const PORT = 8485;
|
const PORT = 8485;
|
||||||
const NAV_ID = "dev-companion-reconnect";
|
const NAV_ID = "dev-companion-reconnect";
|
||||||
|
@ -154,13 +154,13 @@ function initWs(isManual = false) {
|
||||||
case "testPatch": {
|
case "testPatch": {
|
||||||
const { find, replacement } = data as PatchData;
|
const { find, replacement } = data as PatchData;
|
||||||
|
|
||||||
const candidates = search(find);
|
const candidates = searchFactories(find);
|
||||||
const keys = Object.keys(candidates);
|
const keys = Object.keys(candidates);
|
||||||
if (keys.length !== 1)
|
if (keys.length !== 1)
|
||||||
return reply("Expected exactly one 'find' matches, found " + keys.length);
|
return reply("Expected exactly one 'find' matches, found " + keys.length);
|
||||||
|
|
||||||
const mod = candidates[keys[0]];
|
const mod = candidates[keys[0]];
|
||||||
let src = String(mod.original ?? mod).replaceAll("\n", "");
|
let src = String(mod).replaceAll("\n", "");
|
||||||
|
|
||||||
if (src.startsWith("function(")) {
|
if (src.startsWith("function(")) {
|
||||||
src = "0," + src;
|
src = "0," + src;
|
||||||
|
@ -201,22 +201,22 @@ function initWs(isManual = false) {
|
||||||
let results: any[];
|
let results: any[];
|
||||||
switch (type.replace("find", "").replace("Lazy", "")) {
|
switch (type.replace("find", "").replace("Lazy", "")) {
|
||||||
case "":
|
case "":
|
||||||
results = findAll(parsedArgs[0]);
|
results = cacheFindAll(parsedArgs[0]);
|
||||||
break;
|
break;
|
||||||
case "ByProps":
|
case "ByProps":
|
||||||
results = findAll(filters.byProps(...parsedArgs));
|
results = cacheFindAll(filters.byProps(...parsedArgs));
|
||||||
break;
|
break;
|
||||||
case "Store":
|
case "Store":
|
||||||
results = findAll(filters.byStoreName(parsedArgs[0]));
|
results = cacheFindAll(filters.byStoreName(parsedArgs[0]));
|
||||||
break;
|
break;
|
||||||
case "ByCode":
|
case "ByCode":
|
||||||
results = findAll(filters.byCode(...parsedArgs));
|
results = cacheFindAll(filters.byCode(...parsedArgs));
|
||||||
break;
|
break;
|
||||||
case "ModuleId":
|
case "ModuleId":
|
||||||
results = Object.keys(search(parsedArgs[0]));
|
results = Object.keys(searchFactories(parsedArgs[0]));
|
||||||
break;
|
break;
|
||||||
case "ComponentByCode":
|
case "ComponentByCode":
|
||||||
results = findAll(filters.componentByCode(...parsedArgs));
|
results = cacheFindAll(filters.componentByCode(...parsedArgs));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return reply("Unknown Find Type " + type);
|
return reply("Unknown Find Type " + type);
|
||||||
|
|
|
@ -23,12 +23,12 @@ import { Logger } from "@utils/Logger";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
|
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCode, findStore } from "@webpack";
|
||||||
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||||
import { Promisable } from "type-fest";
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
const StickersStore = findStoreLazy("StickersStore");
|
const StickersStore = findStore("StickersStore");
|
||||||
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
const uploadEmoji = findByCode(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
||||||
|
|
||||||
interface Sticker {
|
interface Sticker {
|
||||||
t: "Sticker";
|
t: "Sticker";
|
||||||
|
|
|
@ -23,12 +23,12 @@ import { ErrorCard } from "@components/ErrorCard";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Forms, React } from "@webpack/common";
|
import { Forms, React } from "@webpack/common";
|
||||||
|
|
||||||
import hideBugReport from "./hideBugReport.css?managed";
|
import hideBugReport from "./hideBugReport.css?managed";
|
||||||
|
|
||||||
const KbdStyles = findByPropsLazy("key", "combo");
|
const KbdStyles = findByProps("key", "combo");
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
toolbarDevMenu: {
|
toolbarDevMenu: {
|
||||||
|
|
|
@ -23,36 +23,36 @@ import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies";
|
||||||
import { getCurrentGuild } from "@utils/discord";
|
import { getCurrentGuild } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
import { findByCode, findByProps, findStore, webpackDependantLazy } from "@webpack";
|
||||||
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, IconUtils, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, IconUtils, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
||||||
import type { Emoji } from "@webpack/types";
|
import type { Emoji } from "@webpack/types";
|
||||||
import type { Message } from "discord-types/general";
|
import type { Message } from "discord-types/general";
|
||||||
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
||||||
import type { ReactElement, ReactNode } from "react";
|
import type { ReactElement, ReactNode } from "react";
|
||||||
|
|
||||||
const StickerStore = findStoreLazy("StickersStore") as {
|
const StickersStore = findStore("StickersStore") as {
|
||||||
getPremiumPacks(): StickerPack[];
|
getPremiumPacks(): StickerPack[];
|
||||||
getAllGuildStickers(): Map<string, Sticker[]>;
|
getAllGuildStickers(): Map<string, Sticker[]>;
|
||||||
getStickerById(id: string): Sticker | undefined;
|
getStickerById(id: string): Sticker | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore");
|
const UserSettingsProtoStore = findStore("UserSettingsProtoStore");
|
||||||
|
|
||||||
const BINARY_READ_OPTIONS = findByPropsLazy("readerFactory");
|
const BINARY_READ_OPTIONS = findByProps("readerFactory");
|
||||||
|
|
||||||
function searchProtoClassField(localName: string, protoClass: any) {
|
function searchProtoClassField(localName: string, protoClass: any) {
|
||||||
const field = protoClass?.fields?.find((field: any) => field.localName === localName);
|
const field = protoClass?.fields?.find((field: any) => field.localName === localName);
|
||||||
if (!field) return;
|
if (!field) return;
|
||||||
|
|
||||||
const fieldGetter = Object.values(field).find(value => typeof value === "function") as any;
|
const fieldGetter = Object.values<any>(field).find(value => typeof value === "function");
|
||||||
return fieldGetter?.();
|
return fieldGetter?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
const PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);
|
const PreloadedUserSettingsActionCreators = webpackDependantLazy(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);
|
||||||
const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass));
|
const AppearanceSettingsActionCreators = webpackDependantLazy(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass));
|
||||||
const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators));
|
const ClientThemeSettingsActionsCreators = webpackDependantLazy(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators));
|
||||||
|
|
||||||
const isUnusableRoleSubscriptionEmoji = findByCodeLazy(".getUserIsAdmin(");
|
const isUnusableRoleSubscriptionEmoji = findByCode(".getUserIsAdmin(");
|
||||||
|
|
||||||
const enum EmojiIntentions {
|
const enum EmojiIntentions {
|
||||||
REACTION,
|
REACTION,
|
||||||
|
@ -566,8 +566,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
|
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
||||||
if (StickerStore.getStickerById(gifMatch[1])) return null;
|
if (StickersStore.getStickerById(gifMatch[1])) return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +655,7 @@ export default definePlugin({
|
||||||
url = new URL(item);
|
url = new URL(item);
|
||||||
} catch { }
|
} catch { }
|
||||||
|
|
||||||
const stickerName = StickerStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
|
const stickerName = StickersStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
|
||||||
stickers.push({
|
stickers.push({
|
||||||
format_type: 1,
|
format_type: 1,
|
||||||
id: imgMatch[1],
|
id: imgMatch[1],
|
||||||
|
@ -668,9 +668,9 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = item.match(fakeNitroGifStickerRegex);
|
const gifMatch = item.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
if (!StickerStore.getStickerById(gifMatch[1])) continue;
|
if (!StickersStore.getStickerById(gifMatch[1])) continue;
|
||||||
|
|
||||||
const stickerName = StickerStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
|
const stickerName = StickersStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
|
||||||
stickers.push({
|
stickers.push({
|
||||||
format_type: 2,
|
format_type: 2,
|
||||||
id: gifMatch[1],
|
id: gifMatch[1],
|
||||||
|
@ -703,8 +703,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);
|
const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
||||||
if (StickerStore.getStickerById(gifMatch[1])) return true;
|
if (StickersStore.getStickerById(gifMatch[1])) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,8 +721,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const match = attachment.url.match(fakeNitroGifStickerRegex);
|
const match = attachment.url.match(fakeNitroGifStickerRegex);
|
||||||
if (match) {
|
if (match) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
||||||
if (StickerStore.getStickerById(match[1])) return false;
|
if (StickersStore.getStickerById(match[1])) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -878,7 +878,7 @@ export default definePlugin({
|
||||||
if (!s.enableStickerBypass)
|
if (!s.enableStickerBypass)
|
||||||
break stickerBypass;
|
break stickerBypass;
|
||||||
|
|
||||||
const sticker = StickerStore.getStickerById(extra.stickers?.[0]!);
|
const sticker = StickersStore.getStickerById(extra.stickers?.[0]!);
|
||||||
if (!sticker)
|
if (!sticker)
|
||||||
break stickerBypass;
|
break stickerBypass;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { Margins } from "@utils/margins";
|
||||||
import { classes, copyWithToast } from "@utils/misc";
|
import { classes, copyWithToast } from "@utils/misc";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
|
import { extractAndLoadChunksLazy, findComponentByCode } from "@webpack";
|
||||||
import { Button, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
|
import { Button, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
import virtualMerge from "virtual-merge";
|
import virtualMerge from "virtual-merge";
|
||||||
|
@ -108,10 +108,10 @@ interface ProfileModalProps {
|
||||||
isTryItOutFlow: boolean;
|
isTryItOutFlow: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCode<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
||||||
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
|
const ProfileModal = findComponentByCode<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
|
||||||
|
|
||||||
const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i(\("?.+?"?\)).then\(\i\.bind\(\i,"?(.+?)"?\)\)/);
|
const requireColorPicker = extractAndLoadChunksLazy("USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format");
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "FakeProfileThemes",
|
name: "FakeProfileThemes",
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { useCallback, useEffect, useRef, useState } from "@webpack/common";
|
import { useCallback, useEffect, useRef, useState } from "@webpack/common";
|
||||||
|
|
||||||
interface SearchBarComponentProps {
|
interface SearchBarComponentProps {
|
||||||
|
@ -35,7 +35,7 @@ interface SearchBarComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TSearchBarComponent =
|
type TSearchBarComponent =
|
||||||
React.FC<SearchBarComponentProps> & { Sizes: Record<"SMALL" | "MEDIUM" | "LARGE", string>; };
|
React.ComponentType<SearchBarComponentProps> & { Sizes: Record<"SMALL" | "MEDIUM" | "LARGE", string>; };
|
||||||
|
|
||||||
interface Gif {
|
interface Gif {
|
||||||
format: number;
|
format: number;
|
||||||
|
@ -60,7 +60,7 @@ interface Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const containerClasses: { searchBar: string; } = findByPropsLazy("searchBar", "searchBarFullRow");
|
const containerClasses: { searchBar: string; } = findByProps("searchBar", "searchBarFullRow");
|
||||||
|
|
||||||
export const settings = definePluginSettings({
|
export const settings = definePluginSettings({
|
||||||
searchOption: {
|
searchOption: {
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands";
|
import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
|
|
||||||
const FriendInvites = findByPropsLazy("createFriendInvite");
|
const FriendInvites = findByProps("createFriendInvite");
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "FriendInvites",
|
name: "FriendInvites",
|
||||||
|
|
|
@ -9,14 +9,14 @@ import { Devs } from "@utils/constants";
|
||||||
import { getCurrentChannel } from "@utils/discord";
|
import { getCurrentChannel } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, findLazy } from "@webpack";
|
import { find, findByCode, findByProps } from "@webpack";
|
||||||
import { Heading, RelationshipStore, Text } from "@webpack/common";
|
import { Heading, RelationshipStore, Text } from "@webpack/common";
|
||||||
|
|
||||||
const containerWrapper = findByPropsLazy("memberSinceWrapper");
|
const containerWrapper = findByProps("memberSinceWrapper");
|
||||||
const container = findByPropsLazy("memberSince");
|
const container = findByProps("memberSince");
|
||||||
const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
|
const getCreatedAtDate = findByCode('month:"short",day:"numeric"');
|
||||||
const locale = findByPropsLazy("getLocale");
|
const locale = findByProps("getLocale");
|
||||||
const section = findLazy((m: any) => m.section !== void 0 && m.heading !== void 0 && Object.values(m).length === 2);
|
const section = find((m: any) => m.section !== void 0 && m.heading !== void 0 && Object.values(m).length === 2);
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "FriendsSince",
|
name: "FriendsSince",
|
||||||
|
|
|
@ -22,13 +22,13 @@ import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findComponentByCodeLazy } from "@webpack";
|
import { findComponentByCode } from "@webpack";
|
||||||
|
|
||||||
import style from "./style.css?managed";
|
import style from "./style.css?managed";
|
||||||
|
|
||||||
const Button = findComponentByCodeLazy("Button.Sizes.NONE,disabled:");
|
const Button = findComponentByCode("Button.Sizes.NONE,disabled:");
|
||||||
|
|
||||||
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
|
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame");
|
||||||
|
|
||||||
function makeIcon(showCurrentGame?: boolean) {
|
function makeIcon(showCurrentGame?: boolean) {
|
||||||
const { oldIcon } = settings.use(["oldIcon"]);
|
const { oldIcon } = settings.use(["oldIcon"]);
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findLazy } from "@webpack";
|
import { find } from "@webpack";
|
||||||
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";
|
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";
|
||||||
import { Channel, Message } from "discord-types/general";
|
import { Channel, Message } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ const settings = definePluginSettings({
|
||||||
unholyMultiGreetEnabled?: boolean;
|
unholyMultiGreetEnabled?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const WELCOME_STICKERS = findLazy(m => Array.isArray(m) && m[0]?.name === "Wave");
|
const WELCOME_STICKERS = find(m => Array.isArray(m) && m[0]?.name === "Wave");
|
||||||
|
|
||||||
function greet(channel: Channel, message: Message, stickers: string[]) {
|
function greet(channel: Channel, message: Message, stickers: string[]) {
|
||||||
const options = MessageActions.getSendMessageOptionsForReply({
|
const options = MessageActions.getSendMessageOptionsForReply({
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { Flex } from "@components/Flex";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { Button, Forms, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "webpack/common";
|
import { Button, Forms, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "webpack/common";
|
||||||
|
|
||||||
const enum ActivitiesTypes {
|
const enum ActivitiesTypes {
|
||||||
|
@ -26,9 +26,9 @@ interface IgnoredActivity {
|
||||||
type: ActivitiesTypes;
|
type: ActivitiesTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RunningGameStore = findStoreLazy("RunningGameStore");
|
const RunningGameStore = findStore("RunningGameStore");
|
||||||
|
|
||||||
const ShowCurrentGame = getUserSettingLazy("status", "showCurrentGame")!;
|
const ShowCurrentGame = getUserSettingLazy("status", "showCurrentGame");
|
||||||
|
|
||||||
function ToggleIcon(activity: IgnoredActivity, tooltipText: string, path: string, fill: string) {
|
function ToggleIcon(activity: IgnoredActivity, tooltipText: string, path: string, fill: string) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -19,16 +19,26 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { ChannelStore, Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common";
|
import { ChannelStore, Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common";
|
||||||
import { Settings } from "Vencord";
|
|
||||||
|
|
||||||
const UserAffinitiesStore = findStoreLazy("UserAffinitiesStore");
|
const UserAffinitiesStore = findStore("UserAffinitiesStore");
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
sortByAffinity: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
default: true,
|
||||||
|
description: "Whether to sort implicit relationships by their affinity to you.",
|
||||||
|
restartNeeded: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "ImplicitRelationships",
|
name: "ImplicitRelationships",
|
||||||
description: "Shows your implicit relationships in the Friends tab.",
|
description: "Shows your implicit relationships in the Friends tab.",
|
||||||
authors: [Devs.Dolfies],
|
authors: [Devs.Dolfies],
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
// Counts header
|
// Counts header
|
||||||
{
|
{
|
||||||
|
@ -75,7 +85,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "getRelationshipCounts(){",
|
find: "getRelationshipCounts(){",
|
||||||
replacement: {
|
replacement: {
|
||||||
predicate: () => Settings.plugins.ImplicitRelationships.sortByAffinity,
|
predicate: () => settings.store.sortByAffinity,
|
||||||
match: /\}\)\.sortBy\((.+?)\)\.value\(\)/,
|
match: /\}\)\.sortBy\((.+?)\)\.value\(\)/,
|
||||||
replace: "}).sortBy(row => $self.wrapSort(($1), row)).value()"
|
replace: "}).sortBy(row => $self.wrapSort(($1), row)).value()"
|
||||||
}
|
}
|
||||||
|
@ -104,16 +114,6 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
settings: definePluginSettings(
|
|
||||||
{
|
|
||||||
sortByAffinity: {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
default: true,
|
|
||||||
description: "Whether to sort implicit relationships by their affinity to you.",
|
|
||||||
restartNeeded: true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
|
|
||||||
wrapSort(comparator: Function, row: any) {
|
wrapSort(comparator: Function, row: any) {
|
||||||
return row.type === 5
|
return row.type === 5
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { Link } from "@components/Link";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { ApplicationAssetUtils, FluxDispatcher, Forms } from "@webpack/common";
|
import { ApplicationAssetUtils, FluxDispatcher, Forms } from "@webpack/common";
|
||||||
|
|
||||||
interface ActivityAssets {
|
interface ActivityAssets {
|
||||||
|
@ -86,7 +86,7 @@ const placeholderId = "2a96cbd8b46e442fc41c2b86b821562f";
|
||||||
|
|
||||||
const logger = new Logger("LastFMRichPresence");
|
const logger = new Logger("LastFMRichPresence");
|
||||||
|
|
||||||
const presenceStore = findByPropsLazy("getLocalPresence");
|
const SelfPresenceStore = findStore("SelfPresenceStore");
|
||||||
|
|
||||||
async function getApplicationAsset(key: string): Promise<string> {
|
async function getApplicationAsset(key: string): Promise<string> {
|
||||||
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
|
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
|
||||||
|
@ -275,7 +275,7 @@ export default definePlugin({
|
||||||
|
|
||||||
async getActivity(): Promise<Activity | null> {
|
async getActivity(): Promise<Activity | null> {
|
||||||
if (settings.store.hideWithSpotify) {
|
if (settings.store.hideWithSpotify) {
|
||||||
for (const activity of presenceStore.getActivities()) {
|
for (const activity of SelfPresenceStore.getActivities()) {
|
||||||
if (activity.type === ActivityType.LISTENING && activity.application_id !== applicationId) {
|
if (activity.type === ActivityType.LISTENING && activity.application_id !== applicationId) {
|
||||||
// there is already music status because of Spotify or richerCider (probably more)
|
// there is already music status because of Spotify or richerCider (probably more)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -23,16 +23,16 @@ import { classNameFactory } from "@api/Styles";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { FluxStore } from "@webpack/types";
|
import { FluxStore } from "@webpack/types";
|
||||||
|
|
||||||
import { MemberCount } from "./MemberCount";
|
import { MemberCount } from "./MemberCount";
|
||||||
|
|
||||||
export const GuildMemberCountStore = findStoreLazy("GuildMemberCountStore") as FluxStore & { getMemberCount(guildId: string): number | null; };
|
export const GuildMemberCountStore = findStore("GuildMemberCountStore") as FluxStore & { getMemberCount(guildId: string): number | null; };
|
||||||
export const ChannelMemberStore = findStoreLazy("ChannelMemberStore") as FluxStore & {
|
export const ChannelMemberStore = findStore("ChannelMemberStore") as FluxStore & {
|
||||||
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
|
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
|
||||||
};
|
};
|
||||||
export const ThreadMemberListStore = findStoreLazy("ThreadMemberListStore") as FluxStore & {
|
export const ThreadMemberListStore = findStore("ThreadMemberListStore") as FluxStore & {
|
||||||
getMemberListSections(channelId: string): { [sectionId: string]: { sectionId: string; userIds: string[]; }; };
|
getMemberListSections(channelId: string): { [sectionId: string]: { sectionId: string; userIds: string[]; }; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,11 @@ import { addClickListener, removeClickListener } from "@api/MessageEvents";
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps, findStore } from "@webpack";
|
||||||
import { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from "@webpack/common";
|
import { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
const MessageActions = findByPropsLazy("deleteMessage", "startEditMessage");
|
const MessageActions = findByProps("deleteMessage", "startEditMessage");
|
||||||
const EditStore = findByPropsLazy("isEditing", "isEditingAny");
|
const EditMessageStore = findStore("EditMessageStore");
|
||||||
|
|
||||||
let isDeletePressed = false;
|
let isDeletePressed = false;
|
||||||
const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
|
const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
|
||||||
|
@ -74,7 +74,7 @@ export default definePlugin({
|
||||||
if (msg.deleted === true) return;
|
if (msg.deleted === true) return;
|
||||||
|
|
||||||
if (isMe) {
|
if (isMe) {
|
||||||
if (!settings.store.enableDoubleClickToEdit || EditStore.isEditing(channel.id, msg.id)) return;
|
if (!settings.store.enableDoubleClickToEdit || EditMessageStore.isEditing(channel.id, msg.id)) return;
|
||||||
|
|
||||||
MessageActions.startEditMessage(channel.id, msg.id, msg.content);
|
MessageActions.startEditMessage(channel.id, msg.id, msg.content);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { isNonNullish } from "@utils/guards";
|
import { isNonNullish } from "@utils/guards";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findExportedComponentLazy } from "@webpack";
|
import { findExportedComponent } from "@webpack";
|
||||||
import { SnowflakeUtils, Tooltip } from "@webpack/common";
|
import { SnowflakeUtils, Tooltip } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ interface Diff {
|
||||||
}
|
}
|
||||||
|
|
||||||
const DISCORD_KT_DELAY = 1471228928;
|
const DISCORD_KT_DELAY = 1471228928;
|
||||||
const HiddenVisually = findExportedComponentLazy("HiddenVisually");
|
const HiddenVisually = findExportedComponent("HiddenVisually");
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "MessageLatency",
|
name: "MessageLatency",
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { Devs } from "@utils/constants.js";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { Queue } from "@utils/Queue";
|
import { Queue } from "@utils/Queue";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByProps, findComponentByCode } from "@webpack";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
ChannelStore,
|
ChannelStore,
|
||||||
|
@ -47,14 +47,14 @@ const messageCache = new Map<string, {
|
||||||
fetched: boolean;
|
fetched: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const Embed = findComponentByCodeLazy(".inlineMediaEmbed");
|
const Embed = findComponentByCode(".inlineMediaEmbed");
|
||||||
const AutoModEmbed = findComponentByCodeLazy(".withFooter]:", "childrenMessageContent:");
|
const AutoModEmbed = findComponentByCode(".withFooter]:", "childrenMessageContent:");
|
||||||
const ChannelMessage = findComponentByCodeLazy("childrenExecutedCommand:", ".hideAccessories");
|
const ChannelMessage = findComponentByCode("childrenExecutedCommand:", ".hideAccessories");
|
||||||
|
|
||||||
const SearchResultClasses = findByPropsLazy("message", "searchResult");
|
const SearchResultClasses = findByProps("message", "searchResult");
|
||||||
const EmbedClasses = findByPropsLazy("embedAuthorIcon", "embedAuthor", "embedAuthor");
|
const EmbedClasses = findByProps("embedAuthorIcon", "embedAuthor", "embedAuthor");
|
||||||
|
|
||||||
const MessageDisplayCompact = getUserSettingLazy("textAndImages", "messageDisplayCompact")!;
|
const MessageDisplayCompact = getUserSettingLazy("textAndImages", "messageDisplayCompact");
|
||||||
|
|
||||||
const messageLinkRegex = /(?<!<)https?:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/(?:\d{17,20}|@me)\/(\d{17,20})\/(\d{17,20})/g;
|
const messageLinkRegex = /(?<!<)https?:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/(?:\d{17,20}|@me)\/(\d{17,20})\/(\d{17,20})/g;
|
||||||
const tenorRegex = /^https:\/\/(?:www\.)?tenor\.com\//;
|
const tenorRegex = /^https:\/\/(?:www\.)?tenor\.com\//;
|
||||||
|
@ -215,10 +215,9 @@ function computeWidthAndHeight(width: number, height: number) {
|
||||||
|
|
||||||
function withEmbeddedBy(message: Message, embeddedBy: string[]) {
|
function withEmbeddedBy(message: Message, embeddedBy: string[]) {
|
||||||
return new Proxy(message, {
|
return new Proxy(message, {
|
||||||
get(_, prop) {
|
get(target, prop, receiver) {
|
||||||
if (prop === "vencordEmbeddedBy") return embeddedBy;
|
if (prop === "vencordEmbeddedBy") return embeddedBy;
|
||||||
// @ts-ignore ts so bad
|
return Reflect.get(target, prop, receiver);
|
||||||
return Reflect.get(...arguments);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,13 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { TabBar, Text, Timestamp, TooltipContainer, useState } from "@webpack/common";
|
import { TabBar, Text, Timestamp, TooltipContainer, useState } from "@webpack/common";
|
||||||
|
|
||||||
import { parseEditContent } from ".";
|
import { parseEditContent } from ".";
|
||||||
|
|
||||||
const CodeContainerClasses = findByPropsLazy("markup", "codeContainer");
|
const CodeContainerClasses = findByProps("markup", "codeContainer");
|
||||||
const MiscClasses = findByPropsLazy("messageContent", "markupRtl");
|
const MiscClasses = findByProps("messageContent", "markupRtl");
|
||||||
|
|
||||||
const cl = classNameFactory("vc-ml-modal-");
|
const cl = classNameFactory("vc-ml-modal-");
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import "./messageLogger.css";
|
||||||
|
|
||||||
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import { updateMessage } from "@api/MessageUpdater";
|
import { updateMessage } from "@api/MessageUpdater";
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { disableStyle, enableStyle } from "@api/Styles";
|
import { disableStyle, enableStyle } from "@api/Styles";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
@ -28,7 +28,7 @@ import { proxyLazy } from "@utils/lazy";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
import { findByCode, findByProps } from "@webpack";
|
||||||
import { ChannelStore, FluxDispatcher, i18n, Menu, MessageStore, Parser, SelectedChannelStore, Timestamp, UserStore, useStateFromStores } from "@webpack/common";
|
import { ChannelStore, FluxDispatcher, i18n, Menu, MessageStore, Parser, SelectedChannelStore, Timestamp, UserStore, useStateFromStores } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -42,11 +42,11 @@ interface MLMessage extends Message {
|
||||||
firstEditTimestamp?: Date;
|
firstEditTimestamp?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = findByPropsLazy("edited", "communicationDisabled", "isSystemMessage");
|
const styles = findByProps("edited", "communicationDisabled", "isSystemMessage");
|
||||||
const getMessage = findByCodeLazy('replace(/^\\n+|\\n+$/g,"")');
|
const getMessage = findByCode('replace(/^\\n+|\\n+$/g,"")');
|
||||||
|
|
||||||
function addDeleteStyle() {
|
function addDeleteStyle() {
|
||||||
if (Settings.plugins.MessageLogger.deleteStyle === "text") {
|
if (settings.store.deleteStyle === "text") {
|
||||||
enableStyle(textStyle);
|
enableStyle(textStyle);
|
||||||
disableStyle(overlayStyle);
|
disableStyle(overlayStyle);
|
||||||
} else {
|
} else {
|
||||||
|
@ -142,58 +142,7 @@ export function parseEditContent(content: string, message: Message) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
const settings = definePluginSettings({
|
||||||
name: "MessageLogger",
|
|
||||||
description: "Temporarily logs deleted and edited messages.",
|
|
||||||
authors: [Devs.rushii, Devs.Ven, Devs.AutumnVN, Devs.Nickyux, Devs.Kyuuhachi],
|
|
||||||
dependencies: ["MessageUpdaterAPI"],
|
|
||||||
|
|
||||||
contextMenus: {
|
|
||||||
"message": patchMessageContextMenu,
|
|
||||||
"channel-context": patchChannelContextMenu,
|
|
||||||
"thread-context": patchChannelContextMenu,
|
|
||||||
"user-context": patchChannelContextMenu,
|
|
||||||
"gdm-context": patchChannelContextMenu
|
|
||||||
},
|
|
||||||
|
|
||||||
start() {
|
|
||||||
addDeleteStyle();
|
|
||||||
},
|
|
||||||
|
|
||||||
renderEdits: ErrorBoundary.wrap(({ message: { id: messageId, channel_id: channelId } }: { message: Message; }) => {
|
|
||||||
const message = useStateFromStores(
|
|
||||||
[MessageStore],
|
|
||||||
() => MessageStore.getMessage(channelId, messageId) as MLMessage,
|
|
||||||
null,
|
|
||||||
(oldMsg, newMsg) => oldMsg?.editHistory === newMsg?.editHistory
|
|
||||||
);
|
|
||||||
|
|
||||||
return Settings.plugins.MessageLogger.inlineEdits && (
|
|
||||||
<>
|
|
||||||
{message.editHistory?.map(edit => (
|
|
||||||
<div className="messagelogger-edited">
|
|
||||||
{parseEditContent(edit.content, message)}
|
|
||||||
<Timestamp
|
|
||||||
timestamp={edit.timestamp}
|
|
||||||
isEdited={true}
|
|
||||||
isInline={false}
|
|
||||||
>
|
|
||||||
<span className={styles.edited}>{" "}({i18n.Messages.MESSAGE_EDITED})</span>
|
|
||||||
</Timestamp>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}, { noop: true }),
|
|
||||||
|
|
||||||
makeEdit(newMessage: any, oldMessage: any): any {
|
|
||||||
return {
|
|
||||||
timestamp: new Date(newMessage.edited_timestamp),
|
|
||||||
content: oldMessage.content
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
options: {
|
|
||||||
deleteStyle: {
|
deleteStyle: {
|
||||||
type: OptionType.SELECT,
|
type: OptionType.SELECT,
|
||||||
description: "The style of deleted messages",
|
description: "The style of deleted messages",
|
||||||
|
@ -249,6 +198,58 @@ export default definePlugin({
|
||||||
description: "Comma-separated list of guild IDs to ignore",
|
description: "Comma-separated list of guild IDs to ignore",
|
||||||
default: ""
|
default: ""
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "MessageLogger",
|
||||||
|
description: "Temporarily logs deleted and edited messages.",
|
||||||
|
authors: [Devs.rushii, Devs.Ven, Devs.AutumnVN, Devs.Nickyux, Devs.Kyuuhachi],
|
||||||
|
dependencies: ["MessageUpdaterAPI"],
|
||||||
|
settings,
|
||||||
|
|
||||||
|
contextMenus: {
|
||||||
|
"message": patchMessageContextMenu,
|
||||||
|
"channel-context": patchChannelContextMenu,
|
||||||
|
"thread-context": patchChannelContextMenu,
|
||||||
|
"user-context": patchChannelContextMenu,
|
||||||
|
"gdm-context": patchChannelContextMenu
|
||||||
|
},
|
||||||
|
|
||||||
|
start() {
|
||||||
|
addDeleteStyle();
|
||||||
|
},
|
||||||
|
|
||||||
|
renderEdits: ErrorBoundary.wrap(({ message: { id: messageId, channel_id: channelId } }: { message: Message; }) => {
|
||||||
|
const message = useStateFromStores(
|
||||||
|
[MessageStore],
|
||||||
|
() => MessageStore.getMessage(channelId, messageId) as MLMessage,
|
||||||
|
null,
|
||||||
|
(oldMsg, newMsg) => oldMsg?.editHistory === newMsg?.editHistory
|
||||||
|
);
|
||||||
|
|
||||||
|
return settings.store.inlineEdits && (
|
||||||
|
<>
|
||||||
|
{message.editHistory?.map(edit => (
|
||||||
|
<div className="messagelogger-edited">
|
||||||
|
{parseEditContent(edit.content, message)}
|
||||||
|
<Timestamp
|
||||||
|
timestamp={edit.timestamp}
|
||||||
|
isEdited={true}
|
||||||
|
isInline={false}
|
||||||
|
>
|
||||||
|
<span className={styles.edited}>{" "}({i18n.Messages.MESSAGE_EDITED})</span>
|
||||||
|
</Timestamp>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}, { noop: true }),
|
||||||
|
|
||||||
|
makeEdit(newMessage: any, oldMessage: any): any {
|
||||||
|
return {
|
||||||
|
timestamp: new Date(newMessage.edited_timestamp),
|
||||||
|
content: oldMessage.content
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDelete(cache: any, data: { ids: string[], id: string; mlDeleted?: boolean; }, isBulk: boolean) {
|
handleDelete(cache: any, data: { ids: string[], id: string; mlDeleted?: boolean; }, isBulk: boolean) {
|
||||||
|
@ -285,7 +286,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldIgnore(message: any, isEdit = false) {
|
shouldIgnore(message: any, isEdit = false) {
|
||||||
const { ignoreBots, ignoreSelf, ignoreUsers, ignoreChannels, ignoreGuilds, logEdits, logDeletes } = Settings.plugins.MessageLogger;
|
const { ignoreBots, ignoreSelf, ignoreUsers, ignoreChannels, ignoreGuilds, logEdits, logDeletes } = settings.store;
|
||||||
const myId = UserStore.getCurrentUser().id;
|
const myId = UserStore.getCurrentUser().id;
|
||||||
|
|
||||||
return ignoreBots && message.author?.bot ||
|
return ignoreBots && message.author?.bot ||
|
||||||
|
@ -493,7 +494,7 @@ export default definePlugin({
|
||||||
match: /if\((\i)\.blocked\)return \i\.\i\.MESSAGE_GROUP_BLOCKED;/,
|
match: /if\((\i)\.blocked\)return \i\.\i\.MESSAGE_GROUP_BLOCKED;/,
|
||||||
replace: '$&else if($1.deleted) return"MESSAGE_GROUP_DELETED";',
|
replace: '$&else if($1.deleted) return"MESSAGE_GROUP_DELETED";',
|
||||||
},
|
},
|
||||||
predicate: () => Settings.plugins.MessageLogger.collapseDeleted
|
predicate: () => settings.store.collapseDeleted
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Message group rendering
|
// Message group rendering
|
||||||
|
@ -508,7 +509,7 @@ export default definePlugin({
|
||||||
replace: '$&$1.type==="MESSAGE_GROUP_DELETED"?$self.Messages.DELETED_MESSAGE_COUNT:',
|
replace: '$&$1.type==="MESSAGE_GROUP_DELETED"?$self.Messages.DELETED_MESSAGE_COUNT:',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
predicate: () => Settings.plugins.MessageLogger.collapseDeleted
|
predicate: () => settings.store.collapseDeleted
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, registerCommand, sendBotMessage, unregisterCommand } from "@api/Commands";
|
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, registerCommand, sendBotMessage, unregisterCommand } from "@api/Commands";
|
||||||
import * as DataStore from "@api/DataStore";
|
import * as DataStore from "@api/DataStore";
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ function createTagCommand(tag: Tag) {
|
||||||
return { content: `/${tag.name}` };
|
return { content: `/${tag.name}` };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.plugins.MessageTags.clyde) sendBotMessage(ctx.channel.id, {
|
if (settings.store.clyde) sendBotMessage(ctx.channel.id, {
|
||||||
content: `${EMOTE} The tag **${tag.name}** has been sent!`
|
content: `${EMOTE} The tag **${tag.name}** has been sent!`
|
||||||
});
|
});
|
||||||
return { content: tag.message.replaceAll("\\n", "\n") };
|
return { content: tag.message.replaceAll("\\n", "\n") };
|
||||||
|
@ -69,19 +69,21 @@ function createTagCommand(tag: Tag) {
|
||||||
}, "CustomTags");
|
}, "CustomTags");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
export default definePlugin({
|
|
||||||
name: "MessageTags",
|
|
||||||
description: "Allows you to save messages and to use them with a simple command.",
|
|
||||||
authors: [Devs.Luna],
|
|
||||||
options: {
|
|
||||||
clyde: {
|
clyde: {
|
||||||
name: "Clyde message on send",
|
name: "Clyde message on send",
|
||||||
description: "If enabled, clyde will send you an ephemeral message when a tag was used.",
|
description: "If enabled, clyde will send you an ephemeral message when a tag was used.",
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "MessageTags",
|
||||||
|
description: "Allows you to save messages and to use them with a simple command.",
|
||||||
|
authors: [Devs.Luna],
|
||||||
|
settings,
|
||||||
|
|
||||||
dependencies: ["CommandsAPI"],
|
dependencies: ["CommandsAPI"],
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { LazyComponentType } from "@utils/lazyReact";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findLazy } from "@webpack";
|
import { findByCode, findComponentByCode } from "@webpack";
|
||||||
import { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip } from "@webpack/common";
|
import { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip } from "@webpack/common";
|
||||||
import type { Permissions, RC } from "@webpack/types";
|
import type { Permissions } from "@webpack/types";
|
||||||
import type { Channel, Guild, Message, User } from "discord-types/general";
|
import type { Channel, Guild, Message, User } from "discord-types/general";
|
||||||
|
|
||||||
interface Tag {
|
interface Tag {
|
||||||
|
@ -59,9 +60,9 @@ const computePermissions: (options: {
|
||||||
overwrites?: Channel["permissionOverwrites"] | null;
|
overwrites?: Channel["permissionOverwrites"] | null;
|
||||||
checkElevated?: boolean /* = true */;
|
checkElevated?: boolean /* = true */;
|
||||||
excludeGuildPermissions?: boolean /* = false */;
|
excludeGuildPermissions?: boolean /* = false */;
|
||||||
}) => bigint = findByCodeLazy(".getCurrentUser()", ".computeLurkerPermissionsAllowList()");
|
}) => bigint = findByCode(".getCurrentUser()", ".computeLurkerPermissionsAllowList()");
|
||||||
|
|
||||||
const Tag = findLazy(m => m.Types?.[0] === "BOT") as RC<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };
|
const Tag = findComponentByCode(".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP_OFFICIAL,") as LazyComponentType<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };
|
||||||
|
|
||||||
const isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot();
|
const isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot();
|
||||||
|
|
||||||
|
|
|
@ -20,15 +20,15 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { isNonNullish } from "@utils/guards";
|
import { isNonNullish } from "@utils/guards";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common";
|
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common";
|
||||||
import { Channel, User } from "discord-types/general";
|
import { Channel, User } from "discord-types/general";
|
||||||
|
|
||||||
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
|
const SelectedChannelActionCreators = findByProps("selectPrivateChannel");
|
||||||
const UserUtils = findByPropsLazy("getGlobalName");
|
const UserUtils = findByProps("getGlobalName");
|
||||||
|
|
||||||
const ProfileListClasses = findByPropsLazy("emptyIconFriends", "emptyIconGuilds");
|
const ProfileListClasses = findByProps("emptyIconFriends", "emptyIconGuilds");
|
||||||
const GuildLabelClasses = findByPropsLazy("guildNick", "guildAvatarWithoutIcon");
|
const GuildLabelClasses = findByProps("guildNick", "guildAvatarWithoutIcon");
|
||||||
|
|
||||||
function getGroupDMName(channel: Channel) {
|
function getGroupDMName(channel: Channel) {
|
||||||
return channel.name ||
|
return channel.name ||
|
||||||
|
|
|
@ -24,18 +24,18 @@ import { definePluginSettings, migratePluginSettings } from "@api/Settings";
|
||||||
import { CogWheel } from "@components/Icons";
|
import { CogWheel } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
|
import { findByCode, findProp, mapMangledModule } from "@webpack";
|
||||||
import { Menu } from "@webpack/common";
|
import { Menu } from "@webpack/common";
|
||||||
import { Guild } from "discord-types/general";
|
import { Guild } from "discord-types/general";
|
||||||
|
|
||||||
const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings");
|
const updateGuildNotificationSettings = findProp("updateGuildNotificationSettings");
|
||||||
const { toggleShowAllChannels } = mapMangledModuleLazy(".onboardExistingMember(", {
|
const { toggleShowAllChannels } = mapMangledModule(".onboardExistingMember(", {
|
||||||
toggleShowAllChannels: m => {
|
toggleShowAllChannels: m => {
|
||||||
const s = String(m);
|
const s = String(m);
|
||||||
return s.length < 100 && !s.includes("onboardExistingMember") && !s.includes("getOptedInChannels");
|
return s.length < 100 && !s.includes("onboardExistingMember") && !s.includes("getOptedInChannels");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const isOptInEnabledForGuild = findByCodeLazy(".COMMUNITY)||", ".isOptInEnabled(");
|
const isOptInEnabledForGuild = findByCode(".COMMUNITY)||", ".isOptInEnabled(");
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
guild: {
|
guild: {
|
||||||
|
|
|
@ -16,19 +16,28 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { RelationshipStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
const RelationshipStore = findByPropsLazy("getRelationships", "isBlocked");
|
const settings = definePluginSettings({
|
||||||
|
ignoreBlockedMessages: {
|
||||||
|
description: "Completely ignores (recent) incoming messages from blocked users (locally).",
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
default: false,
|
||||||
|
restartNeeded: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "NoBlockedMessages",
|
name: "NoBlockedMessages",
|
||||||
description: "Hides all blocked messages from chat completely.",
|
description: "Hides all blocked messages from chat completely.",
|
||||||
authors: [Devs.rushii, Devs.Samu],
|
authors: [Devs.rushii, Devs.Samu],
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "Messages.BLOCKED_MESSAGES_HIDE",
|
find: "Messages.BLOCKED_MESSAGES_HIDE",
|
||||||
|
@ -44,7 +53,7 @@ export default definePlugin({
|
||||||
'"displayName","ReadStateStore")'
|
'"displayName","ReadStateStore")'
|
||||||
].map(find => ({
|
].map(find => ({
|
||||||
find,
|
find,
|
||||||
predicate: () => Settings.plugins.NoBlockedMessages.ignoreBlockedMessages === true,
|
predicate: () => settings.store.ignoreBlockedMessages === true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(?<=MESSAGE_CREATE:function\((\i)\){)/,
|
match: /(?<=MESSAGE_CREATE:function\((\i)\){)/,
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
|
|
||||||
const MessageRequestStore = findByPropsLazy("getMessageRequestsCount");
|
const MessageRequestStore = findStore("MessageRequestStore");
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
hideFriendRequestsCount: {
|
hideFriendRequestsCount: {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { ExpandableHeader } from "@components/ExpandableHeader";
|
import { ExpandableHeader } from "@components/ExpandableHeader";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
|
import { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
|
||||||
import type { Guild, GuildMember } from "discord-types/general";
|
import type { Guild, GuildMember } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -35,15 +35,9 @@ interface UserPermission {
|
||||||
|
|
||||||
type UserPermissions = Array<UserPermission>;
|
type UserPermissions = Array<UserPermission>;
|
||||||
|
|
||||||
const { RoleRootClasses, RoleClasses, RoleBorderClasses } = proxyLazyWebpack(() => {
|
const RoleRootClasses = findByProps("root", "showMoreButton", "collapseButton");
|
||||||
const [RoleRootClasses, RoleClasses, RoleBorderClasses] = findBulk(
|
const RoleClasses = findByProps("role", "roleCircle", "roleName");
|
||||||
filters.byProps("root", "showMoreButton", "collapseButton"),
|
const RoleBorderClasses = findByProps("roleCircle", "dot", "dotBorderColor");
|
||||||
filters.byProps("role", "roleCircle", "roleName"),
|
|
||||||
filters.byProps("roleCircle", "dot", "dotBorderColor")
|
|
||||||
) as Record<string, string>[];
|
|
||||||
|
|
||||||
return { RoleRootClasses, RoleClasses, RoleBorderClasses };
|
|
||||||
});
|
|
||||||
|
|
||||||
function UserPermissionsComponent({ guild, guildMember, forceOpen = false }: { guild: Guild; guildMember: GuildMember; forceOpen?: boolean; }) {
|
function UserPermissionsComponent({ guild, guildMember, forceOpen = false }: { guild: Guild; guildMember: GuildMember; forceOpen?: boolean; }) {
|
||||||
const stns = settings.use(["permissionsSortOrder"]);
|
const stns = settings.use(["permissionsSortOrder"]);
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { SafetyIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Button, ChannelStore, Dialog, GuildMemberStore, GuildStore, Menu, PermissionsBits, Popout, TooltipContainer, UserStore } from "@webpack/common";
|
import { Button, ChannelStore, Dialog, GuildMemberStore, GuildStore, Menu, PermissionsBits, Popout, TooltipContainer, UserStore } from "@webpack/common";
|
||||||
import type { Guild, GuildMember } from "discord-types/general";
|
import type { Guild, GuildMember } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission
|
||||||
import UserPermissions from "./components/UserPermissions";
|
import UserPermissions from "./components/UserPermissions";
|
||||||
import { getSortedRoles, sortPermissionOverwrites } from "./utils";
|
import { getSortedRoles, sortPermissionOverwrites } from "./utils";
|
||||||
|
|
||||||
const PopoutClasses = findByPropsLazy("container", "scroller", "list");
|
const PopoutClasses = findByProps("container", "scroller", "list");
|
||||||
const RoleButtonClasses = findByPropsLazy("button", "buttonInner", "icon", "banner");
|
const RoleButtonClasses = findByProps("button", "buttonInner", "icon", "banner");
|
||||||
|
|
||||||
export const enum PermissionsSortOrder {
|
export const enum PermissionsSortOrder {
|
||||||
HighestRole,
|
HighestRole,
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, Co
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { makeLazy } from "@utils/lazy";
|
import { makeLazy } from "@utils/lazy";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { DraftType, UploadHandler, UploadManager, UserUtils } from "@webpack/common";
|
import { DraftType, UploadHandler, UploadManager, UserUtils } from "@webpack/common";
|
||||||
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ const getFrames = makeLazy(() => Promise.all(
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
const UploadStore = findByPropsLazy("getUploads");
|
const UploadAttachmentStore = findStore("UploadAttachmentStore");
|
||||||
|
|
||||||
function loadImage(source: File | string) {
|
function loadImage(source: File | string) {
|
||||||
const isFile = source instanceof File;
|
const isFile = source instanceof File;
|
||||||
|
@ -58,7 +58,7 @@ async function resolveImage(options: Argument[], ctx: CommandContext, noServerPf
|
||||||
for (const opt of options) {
|
for (const opt of options) {
|
||||||
switch (opt.name) {
|
switch (opt.name) {
|
||||||
case "image":
|
case "image":
|
||||||
const upload = UploadStore.getUpload(ctx.channel.id, opt.name, DraftType.SlashCommand);
|
const upload = UploadAttachmentStore.getUpload(ctx.channel.id, opt.name, DraftType.SlashCommand);
|
||||||
if (upload) {
|
if (upload) {
|
||||||
if (!upload.isImage) {
|
if (!upload.isImage) {
|
||||||
UploadManager.clearAll(ctx.channel.id, DraftType.SlashCommand);
|
UploadManager.clearAll(ctx.channel.id, DraftType.SlashCommand);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModalLazy } from "@utils/modal";
|
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModalLazy } from "@utils/modal";
|
||||||
import { extractAndLoadChunksLazy, findComponentByCodeLazy, findExportedComponentLazy } from "@webpack";
|
import { extractAndLoadChunksLazy, findComponentByCode, findExportedComponent } from "@webpack";
|
||||||
import { Button, Forms, Text, TextInput, Toasts, useEffect, useState } from "@webpack/common";
|
import { Button, Forms, Text, TextInput, Toasts, useEffect, useState } from "@webpack/common";
|
||||||
|
|
||||||
import { DEFAULT_COLOR, SWATCHES } from "../constants";
|
import { DEFAULT_COLOR, SWATCHES } from "../constants";
|
||||||
|
@ -30,10 +30,10 @@ interface ColorPickerWithSwatchesProps {
|
||||||
renderCustomButton?: () => React.ReactNode;
|
renderCustomButton?: () => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCode<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
||||||
const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker");
|
const ColorPickerWithSwatches = findExportedComponent<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker");
|
||||||
|
|
||||||
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
export const requireSettingsMenu = extractAndLoadChunksLazy('name:"UserSettings"', /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
||||||
|
|
||||||
const cl = classNameFactory("vc-pindms-modal-");
|
const cl = classNameFactory("vc-pindms-modal-");
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||||
import { findByPropsLazy, findStoreLazy } from "@webpack";
|
import { findByProps, findStore } from "@webpack";
|
||||||
import { ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
|
import { ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
|
||||||
import { Channel } from "discord-types/general";
|
import { Channel } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ interface ChannelComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const headerClasses = findByPropsLazy("privateChannelsHeaderContainer");
|
const headerClasses = findByProps("privateChannelsHeaderContainer");
|
||||||
|
|
||||||
export const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
|
export const PrivateChannelSortStore = findStore("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
|
||||||
|
|
||||||
export let instance: any;
|
export let instance: any;
|
||||||
export const forceUpdate = () => instance?.props?._forceUpdate?.();
|
export const forceUpdate = () => instance?.props?._forceUpdate?.();
|
||||||
|
|
|
@ -21,11 +21,11 @@ import "./style.css";
|
||||||
import { addBadge, BadgePosition, BadgeUserArgs, ProfileBadge, removeBadge } from "@api/Badges";
|
import { addBadge, BadgePosition, BadgeUserArgs, ProfileBadge, removeBadge } from "@api/Badges";
|
||||||
import { addDecorator, removeDecorator } from "@api/MemberListDecorators";
|
import { addDecorator, removeDecorator } from "@api/MemberListDecorators";
|
||||||
import { addDecoration, removeDecoration } from "@api/MessageDecorations";
|
import { addDecoration, removeDecoration } from "@api/MessageDecorations";
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy, findStoreLazy } from "@webpack";
|
import { findByProps, findStore } from "@webpack";
|
||||||
import { PresenceStore, Tooltip, UserStore } from "@webpack/common";
|
import { PresenceStore, Tooltip, UserStore } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export interface Session {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const SessionsStore = findStoreLazy("SessionsStore") as {
|
const SessionsStore = findStore("SessionsStore") as {
|
||||||
getSessions(): Record<string, Session>;
|
getSessions(): Record<string, Session>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ const Icons = {
|
||||||
};
|
};
|
||||||
type Platform = keyof typeof Icons;
|
type Platform = keyof typeof Icons;
|
||||||
|
|
||||||
const StatusUtils = findByPropsLazy("useStatusFillColor", "StatusTypes");
|
const StatusUtils = findByProps("useStatusFillColor", "StatusTypes");
|
||||||
|
|
||||||
const PlatformIcon = ({ platform, status, small }: { platform: Platform, status: string; small: boolean; }) => {
|
const PlatformIcon = ({ platform, status, small }: { platform: Platform, status: string; small: boolean; }) => {
|
||||||
const tooltip = platform === "embedded"
|
const tooltip = platform === "embedded"
|
||||||
|
@ -195,29 +195,36 @@ const indicatorLocations = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
...Object.fromEntries(
|
||||||
|
Object.entries(indicatorLocations).map(([key, value]) => {
|
||||||
|
return [key, {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: `Show indicators ${value.description.toLowerCase()}`,
|
||||||
|
// onChange doesn't give any way to know which setting was changed, so restart required
|
||||||
|
restartNeeded: true,
|
||||||
|
default: true
|
||||||
|
}];
|
||||||
|
})
|
||||||
|
) as Record<"list" | "badges" | "messages", { type: OptionType.BOOLEAN; description: string; restartNeeded: boolean; default: boolean; }>,
|
||||||
|
colorMobileIndicator: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Whether to make the mobile indicator match the color of the user status.",
|
||||||
|
default: true,
|
||||||
|
restartNeeded: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "PlatformIndicators",
|
name: "PlatformIndicators",
|
||||||
description: "Adds platform indicators (Desktop, Mobile, Web...) to users",
|
description: "Adds platform indicators (Desktop, Mobile, Web...) to users",
|
||||||
authors: [Devs.kemo, Devs.TheSun, Devs.Nuckyz, Devs.Ven],
|
authors: [Devs.kemo, Devs.TheSun, Devs.Nuckyz, Devs.Ven],
|
||||||
dependencies: ["MessageDecorationsAPI", "MemberListDecoratorsAPI"],
|
dependencies: ["MessageDecorationsAPI", "MemberListDecoratorsAPI"],
|
||||||
|
settings,
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
const settings = Settings.plugins.PlatformIndicators;
|
|
||||||
const { displayMode } = settings;
|
|
||||||
|
|
||||||
// transfer settings from the old ones, which had a select menu instead of booleans
|
|
||||||
if (displayMode) {
|
|
||||||
if (displayMode !== "both") settings[displayMode] = true;
|
|
||||||
else {
|
|
||||||
settings.list = true;
|
|
||||||
settings.badges = true;
|
|
||||||
}
|
|
||||||
settings.messages = true;
|
|
||||||
delete settings.displayMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.entries(indicatorLocations).forEach(([key, value]) => {
|
Object.entries(indicatorLocations).forEach(([key, value]) => {
|
||||||
if (settings[key]) value.onEnable();
|
if (settings.store[key]) value.onEnable();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -230,7 +237,7 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Masks.STATUS_ONLINE_MOBILE",
|
find: ".Masks.STATUS_ONLINE_MOBILE",
|
||||||
predicate: () => Settings.plugins.PlatformIndicators.colorMobileIndicator,
|
predicate: () => settings.store.colorMobileIndicator,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Return the STATUS_ONLINE_MOBILE mask if the user is on mobile, no matter the status
|
// Return the STATUS_ONLINE_MOBILE mask if the user is on mobile, no matter the status
|
||||||
|
@ -246,7 +253,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".AVATAR_STATUS_MOBILE_16;",
|
find: ".AVATAR_STATUS_MOBILE_16;",
|
||||||
predicate: () => Settings.plugins.PlatformIndicators.colorMobileIndicator,
|
predicate: () => settings.store.colorMobileIndicator,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// Return the AVATAR_STATUS_MOBILE size mask if the user is on mobile, no matter the status
|
// Return the AVATAR_STATUS_MOBILE size mask if the user is on mobile, no matter the status
|
||||||
|
@ -267,32 +274,12 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "}isMobileOnline(",
|
find: "}isMobileOnline(",
|
||||||
predicate: () => Settings.plugins.PlatformIndicators.colorMobileIndicator,
|
predicate: () => settings.store.colorMobileIndicator,
|
||||||
replacement: {
|
replacement: {
|
||||||
// Make isMobileOnline return true no matter what is the user status
|
// Make isMobileOnline return true no matter what is the user status
|
||||||
match: /(?<=\i\[\i\.\i\.MOBILE\])===\i\.\i\.ONLINE/,
|
match: /(?<=\i\[\i\.\i\.MOBILE\])===\i\.\i\.ONLINE/,
|
||||||
replace: "!= null"
|
replace: "!= null"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
|
|
||||||
options: {
|
|
||||||
...Object.fromEntries(
|
|
||||||
Object.entries(indicatorLocations).map(([key, value]) => {
|
|
||||||
return [key, {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
description: `Show indicators ${value.description.toLowerCase()}`,
|
|
||||||
// onChange doesn't give any way to know which setting was changed, so restart required
|
|
||||||
restartNeeded: true,
|
|
||||||
default: true
|
|
||||||
}];
|
|
||||||
})
|
|
||||||
),
|
|
||||||
colorMobileIndicator: {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
description: "Whether to make the mobile indicator match the color of the user status.",
|
|
||||||
default: true,
|
|
||||||
restartNeeded: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,15 +20,14 @@ import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatB
|
||||||
import { generateId, sendBotMessage } from "@api/Commands";
|
import { generateId, sendBotMessage } from "@api/Commands";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { StartAt } from "@utils/types";
|
import definePlugin, { StartAt } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
|
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
|
||||||
import { MessageAttachment } from "discord-types/general";
|
import { MessageAttachment } from "discord-types/general";
|
||||||
|
|
||||||
const UploadStore = findByPropsLazy("getUploads");
|
const UploadAttachmentStore = findStore("UploadAttachmentStore");
|
||||||
|
|
||||||
const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);
|
const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);
|
||||||
|
|
||||||
|
|
||||||
const getImageBox = (url: string): Promise<{ width: number, height: number; } | null> =>
|
const getImageBox = (url: string): Promise<{ width: number, height: number; } | null> =>
|
||||||
new Promise(res => {
|
new Promise(res => {
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
|
@ -44,7 +43,7 @@ const getImageBox = (url: string): Promise<{ width: number, height: number; } |
|
||||||
|
|
||||||
const getAttachments = async (channelId: string) =>
|
const getAttachments = async (channelId: string) =>
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
UploadStore.getUploads(channelId, DraftType.ChannelMessage)
|
UploadAttachmentStore.getUploads(channelId, DraftType.ChannelMessage)
|
||||||
.map(async (upload: any) => {
|
.map(async (upload: any) => {
|
||||||
const { isImage, filename, spoiler, item: { file } } = upload;
|
const { isImage, filename, spoiler, item: { file } } = upload;
|
||||||
const url = URL.createObjectURL(file);
|
const url = URL.createObjectURL(file);
|
||||||
|
@ -79,7 +78,7 @@ const PreviewButton: ChatBarButton = ({ isMainChat, isEmpty, type: { attachments
|
||||||
|
|
||||||
if (!isMainChat) return null;
|
if (!isMainChat) return null;
|
||||||
|
|
||||||
const hasAttachments = attachments && UploadStore.getUploads(channelId, DraftType.ChannelMessage).length > 0;
|
const hasAttachments = attachments && UploadAttachmentStore.getUploads(channelId, DraftType.ChannelMessage).length > 0;
|
||||||
const hasContent = !isEmpty && draft?.length > 0;
|
const hasContent = !isEmpty && draft?.length > 0;
|
||||||
|
|
||||||
if (!hasContent && !hasAttachments) return null;
|
if (!hasContent && !hasAttachments) return null;
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { UserStore } from "@webpack/common";
|
import { UserStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
import { useFormattedPronouns } from "../pronoundbUtils";
|
import { useFormattedPronouns } from "../pronoundbUtils";
|
||||||
import { settings } from "../settings";
|
import { settings } from "../settings";
|
||||||
|
|
||||||
const styles: Record<string, string> = findByPropsLazy("timestampInline");
|
const styles: Record<string, string> = findByProps("timestampInline");
|
||||||
|
|
||||||
const AUTO_MODERATION_ACTION = 24;
|
const AUTO_MODERATION_ACTION = 24;
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,17 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
|
||||||
import { debounce } from "@shared/debounce";
|
import { debounce } from "@shared/debounce";
|
||||||
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
||||||
import { getCurrentChannel } from "@utils/discord";
|
import { getCurrentChannel } from "@utils/discord";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { UserProfileStore, UserStore } from "@webpack/common";
|
import { UserProfileStore, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
import { CachePronouns, PronounCode, PronounMapping, PronounsResponse } from "./types";
|
import { CachePronouns, PronounCode, PronounMapping, PronounsResponse } from "./types";
|
||||||
|
|
||||||
const UserSettingsAccountStore = findStoreLazy("UserSettingsAccountStore");
|
const UserSettingsAccountStore = findStore("UserSettingsAccountStore");
|
||||||
|
|
||||||
type PronounsWithSource = [pronouns: string | null, source: string, hasPendingPronouns: boolean];
|
type PronounsWithSource = [pronouns: string | null, source: string, hasPendingPronouns: boolean];
|
||||||
const EmptyPronouns: PronounsWithSource = [null, "", false];
|
const EmptyPronouns: PronounsWithSource = [null, "", false];
|
||||||
|
@ -156,7 +155,7 @@ export function extractPronouns(pronounSet?: { [locale: string]: PronounCode[];
|
||||||
if (!pronounSet || !pronounSet.en) return PronounMapping.unspecified;
|
if (!pronounSet || !pronounSet.en) return PronounMapping.unspecified;
|
||||||
// PronounDB returns an empty set instead of {sets: {en: ["unspecified"]}}.
|
// PronounDB returns an empty set instead of {sets: {en: ["unspecified"]}}.
|
||||||
const pronouns = pronounSet.en;
|
const pronouns = pronounSet.en;
|
||||||
const { pronounsFormat } = Settings.plugins.PronounDB as { pronounsFormat: PronounsFormat, enabled: boolean; };
|
const { pronounsFormat } = settings.store;
|
||||||
|
|
||||||
if (pronouns.length === 1) {
|
if (pronouns.length === 1) {
|
||||||
// For capitalized pronouns or special codes (any, ask, avoid), we always return the normal (capitalized) string
|
// For capitalized pronouns or special codes (any, ask, avoid), we always return the normal (capitalized) string
|
||||||
|
|
|
@ -19,12 +19,11 @@
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings, Settings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from "@webpack/common";
|
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, RelationshipStore, SelectedChannelStore, UserStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
const Kangaroo = findByPropsLazy("jumpToMessage");
|
const Kangaroo = findByProps("jumpToMessage");
|
||||||
const RelationshipStore = findByPropsLazy("getRelationships", "isBlocked");
|
|
||||||
|
|
||||||
const isMac = navigator.platform.includes("Mac"); // bruh
|
const isMac = navigator.platform.includes("Mac"); // bruh
|
||||||
let replyIdx = -1;
|
let replyIdx = -1;
|
||||||
|
|
|
@ -22,8 +22,8 @@ import { addServerListElement, removeServerListElement, ServerListRenderPosition
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { Button, FluxDispatcher, GuildChannelStore, GuildStore, React, ReadStateStore } from "@webpack/common";
|
import { Button, FluxDispatcher, GenericStore, GuildChannelStore, GuildStore, React, ReadStateStore } from "@webpack/common";
|
||||||
import { Channel } from "discord-types/general";
|
import { Channel } from "discord-types/general";
|
||||||
|
|
||||||
interface ThreadJoined {
|
interface ThreadJoined {
|
||||||
|
@ -34,11 +34,11 @@ interface ThreadJoined {
|
||||||
type ThreadsJoined = Record<string, ThreadJoined>;
|
type ThreadsJoined = Record<string, ThreadJoined>;
|
||||||
type ThreadsJoinedByParent = Record<string, ThreadsJoined>;
|
type ThreadsJoinedByParent = Record<string, ThreadsJoined>;
|
||||||
|
|
||||||
interface ActiveJoinedThreadsStore {
|
interface ActiveJoinedThreadsStore extends GenericStore {
|
||||||
getActiveJoinedThreadsForGuild(guildId: string): ThreadsJoinedByParent;
|
getActiveJoinedThreadsForGuild(guildId: string): ThreadsJoinedByParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActiveJoinedThreadsStore: ActiveJoinedThreadsStore = findStoreLazy("ActiveJoinedThreadsStore");
|
const ActiveJoinedThreadsStore = findStore<ActiveJoinedThreadsStore>("ActiveJoinedThreadsStore");
|
||||||
|
|
||||||
function onClick() {
|
function onClick() {
|
||||||
const channels: Array<any> = [];
|
const channels: Array<any> = [];
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
import { DataStore, Notices } from "@api/index";
|
import { DataStore, Notices } from "@api/index";
|
||||||
import { showNotification } from "@api/Notifications";
|
import { showNotification } from "@api/Notifications";
|
||||||
import { getUniqueUsername, openUserProfile } from "@utils/discord";
|
import { getUniqueUsername, openUserProfile } from "@utils/discord";
|
||||||
import { findStoreLazy } from "@webpack";
|
import { findStore } from "@webpack";
|
||||||
import { ChannelStore, GuildMemberStore, GuildStore, RelationshipStore, UserStore, UserUtils } from "@webpack/common";
|
import { ChannelStore, GuildMemberStore, GuildStore, RelationshipStore, UserStore, UserUtils } from "@webpack/common";
|
||||||
import { FluxStore } from "@webpack/types";
|
import { FluxStore } from "@webpack/types";
|
||||||
|
|
||||||
import settings from "./settings";
|
import settings from "./settings";
|
||||||
import { ChannelType, RelationshipType, SimpleGroupChannel, SimpleGuild } from "./types";
|
import { ChannelType, RelationshipType, SimpleGroupChannel, SimpleGuild } from "./types";
|
||||||
|
|
||||||
export const GuildAvailabilityStore = findStoreLazy("GuildAvailabilityStore") as FluxStore & {
|
export const GuildAvailabilityStore = findStore("GuildAvailabilityStore") as FluxStore & {
|
||||||
totalGuilds: number;
|
totalGuilds: number;
|
||||||
totalUnavailableGuilds: number;
|
totalUnavailableGuilds: number;
|
||||||
unavailableGuilds: string[];
|
unavailableGuilds: string[];
|
||||||
|
|
|
@ -9,17 +9,17 @@ import "./style.css";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { filters, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
|
import { filters, findByProps, mapMangledModule } from "@webpack";
|
||||||
import { Timestamp } from "@webpack/common";
|
import { Timestamp } from "@webpack/common";
|
||||||
import type { Message } from "discord-types/general";
|
import type { Message } from "discord-types/general";
|
||||||
import type { HTMLAttributes } from "react";
|
import type { HTMLAttributes } from "react";
|
||||||
|
|
||||||
const { calendarFormat, dateFormat, isSameDay } = mapMangledModuleLazy("millisecondsInUnit:", {
|
const { calendarFormat, dateFormat, isSameDay } = mapMangledModule("millisecondsInUnit:", {
|
||||||
calendarFormat: filters.byCode("sameElse"),
|
calendarFormat: filters.byCode("sameElse"),
|
||||||
dateFormat: filters.byCode('":'),
|
dateFormat: filters.byCode(':").concat'),
|
||||||
isSameDay: filters.byCode("Math.abs(+"),
|
isSameDay: filters.byCode("Math.abs(+"),
|
||||||
});
|
});
|
||||||
const MessageClasses = findByPropsLazy("separator", "latin24CompactTimeStamp");
|
const MessageClasses = findByProps("separator", "latin24CompactTimeStamp");
|
||||||
|
|
||||||
function Sep(props: HTMLAttributes<HTMLElement>) {
|
function Sep(props: HTMLAttributes<HTMLElement>) {
|
||||||
return <i className={MessageClasses.separator} aria-hidden={true} {...props} />;
|
return <i className={MessageClasses.separator} aria-hidden={true} {...props} />;
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
|
|
||||||
const SpoilerClasses = findByPropsLazy("spoilerContent");
|
const SpoilerClasses = findByProps("spoilerContent");
|
||||||
const MessagesClasses = findByPropsLazy("messagesWrapper");
|
const MessagesClasses = findByProps("messagesWrapper");
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "RevealAllSpoilers",
|
name: "RevealAllSpoilers",
|
||||||
|
|
|
@ -7,15 +7,12 @@
|
||||||
import { DataStore } from "@api/index";
|
import { DataStore } from "@api/index";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { openModal } from "@utils/modal";
|
import { openModal } from "@utils/modal";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { OAuth2AuthorizeModal, showToast, Toasts, UserStore } from "@webpack/common";
|
||||||
import { showToast, Toasts, UserStore } from "@webpack/common";
|
|
||||||
|
|
||||||
import { ReviewDBAuth } from "./entities";
|
import { ReviewDBAuth } from "./entities";
|
||||||
|
|
||||||
const DATA_STORE_KEY = "rdb-auth";
|
const DATA_STORE_KEY = "rdb-auth";
|
||||||
|
|
||||||
const { OAuth2AuthorizeModal } = findByPropsLazy("OAuth2AuthorizeModal");
|
|
||||||
|
|
||||||
export let Auth: ReviewDBAuth = {};
|
export let Auth: ReviewDBAuth = {};
|
||||||
|
|
||||||
export async function initAuth() {
|
export async function initAuth() {
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
import { DeleteIcon } from "@components/Icons";
|
import { DeleteIcon } from "@components/Icons";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Tooltip } from "@webpack/common";
|
import { Tooltip } from "@webpack/common";
|
||||||
|
|
||||||
const iconClasses = findByPropsLazy("button", "wrapper", "disabled", "separator");
|
const iconClasses = findByProps("button", "wrapper", "disabled", "separator");
|
||||||
|
|
||||||
export function DeleteButton({ onClick }: { onClick(): void; }) {
|
export function DeleteButton({ onClick }: { onClick(): void; }) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
|
|
||||||
import { openUserProfile } from "@utils/discord";
|
import { openUserProfile } from "@utils/discord";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { LazyComponent } from "@utils/react";
|
import { findByProps } from "@webpack";
|
||||||
import { filters, findBulk } from "@webpack";
|
|
||||||
import { Alerts, Parser, Timestamp, useState } from "@webpack/common";
|
import { Alerts, Parser, Timestamp, useState } from "@webpack/common";
|
||||||
|
|
||||||
import { Auth, getToken } from "../auth";
|
import { Auth, getToken } from "../auth";
|
||||||
|
@ -31,26 +30,15 @@ import { openBlockModal } from "./BlockedUserModal";
|
||||||
import { BlockButton, DeleteButton, ReportButton } from "./MessageButton";
|
import { BlockButton, DeleteButton, ReportButton } from "./MessageButton";
|
||||||
import ReviewBadge from "./ReviewBadge";
|
import ReviewBadge from "./ReviewBadge";
|
||||||
|
|
||||||
export default LazyComponent(() => {
|
const messageClasses = findByProps("cozyMessage");
|
||||||
// this is terrible, blame mantika
|
const containerClasses = findByProps("container", "isHeader");
|
||||||
const p = filters.byProps;
|
const avatarClasses = findByProps("avatar", "zalgo");
|
||||||
const [
|
const buttonClasses = findByProps("button", "wrapper", "selected");
|
||||||
{ cozyMessage, buttons, message, buttonsInner, groupStart },
|
const botTagClasses = findByProps("botTagRegular");
|
||||||
{ container, isHeader },
|
|
||||||
{ avatar, clickable, username, wrapper, cozy },
|
|
||||||
buttonClasses,
|
|
||||||
botTag
|
|
||||||
] = findBulk(
|
|
||||||
p("cozyMessage"),
|
|
||||||
p("container", "isHeader"),
|
|
||||||
p("avatar", "zalgo"),
|
|
||||||
p("button", "wrapper", "selected"),
|
|
||||||
p("botTagRegular")
|
|
||||||
);
|
|
||||||
|
|
||||||
const dateFormat = new Intl.DateTimeFormat();
|
const dateFormat = new Intl.DateTimeFormat();
|
||||||
|
|
||||||
return function ReviewComponent({ review, refetch, profileId }: { review: Review; refetch(): void; profileId: string; }) {
|
export default function ReviewComponent({ review, refetch, profileId }: { review: Review; refetch(): void; profileId: string; }) {
|
||||||
const [showAll, setShowAll] = useState(false);
|
const [showAll, setShowAll] = useState(false);
|
||||||
|
|
||||||
function openModal() {
|
function openModal() {
|
||||||
|
@ -117,7 +105,7 @@ export default LazyComponent(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes(cl("review"), cozyMessage, wrapper, message, groupStart, cozy)} style={
|
<div className={classes(cl("review"), messageClasses.cozyMessage, avatarClasses.wrapper, messageClasses.message, messageClasses.groupStart, avatarClasses.cozy)} style={
|
||||||
{
|
{
|
||||||
marginLeft: "0px",
|
marginLeft: "0px",
|
||||||
paddingLeft: "52px", // wth is this
|
paddingLeft: "52px", // wth is this
|
||||||
|
@ -126,14 +114,14 @@ export default LazyComponent(() => {
|
||||||
}>
|
}>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
className={classes(avatar, clickable)}
|
className={classes(avatarClasses.avatar, avatarClasses.clickable)}
|
||||||
onClick={openModal}
|
onClick={openModal}
|
||||||
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
|
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
|
||||||
style={{ left: "0px", zIndex: 0 }}
|
style={{ left: "0px", zIndex: 0 }}
|
||||||
/>
|
/>
|
||||||
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
|
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
|
||||||
<span
|
<span
|
||||||
className={classes(clickable, username)}
|
className={classes(avatarClasses.clickable, avatarClasses.username)}
|
||||||
style={{ color: "var(--channels-default)", fontSize: "14px" }}
|
style={{ color: "var(--channels-default)", fontSize: "14px" }}
|
||||||
onClick={() => openModal()}
|
onClick={() => openModal()}
|
||||||
>
|
>
|
||||||
|
@ -142,9 +130,9 @@ export default LazyComponent(() => {
|
||||||
|
|
||||||
{review.type === ReviewType.System && (
|
{review.type === ReviewType.System && (
|
||||||
<span
|
<span
|
||||||
className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.px, botTag.rem)}
|
className={classes(botTagClasses.botTagVerified, botTagClasses.botTagRegular, botTagClasses.px, botTagClasses.rem)}
|
||||||
style={{ marginLeft: "4px" }}>
|
style={{ marginLeft: "4px" }}>
|
||||||
<span className={botTag.botText}>
|
<span className={botTagClasses.botText}>
|
||||||
System
|
System
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -175,10 +163,10 @@ export default LazyComponent(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{review.id !== 0 && (
|
{review.id !== 0 && (
|
||||||
<div className={classes(container, isHeader, buttons)} style={{
|
<div className={classes(containerClasses.container, containerClasses.isHeader, messageClasses.buttons)} style={{
|
||||||
padding: "0px",
|
padding: "0px",
|
||||||
}}>
|
}}>
|
||||||
<div className={classes(buttonClasses.wrapper, buttonsInner)} >
|
<div className={classes(buttonClasses.wrapper, messageClasses.buttonsInner)} >
|
||||||
{canReportReview(review) && <ReportButton onClick={reportRev} />}
|
{canReportReview(review) && <ReportButton onClick={reportRev} />}
|
||||||
{canBlockReviewAuthor(profileId, review) && <BlockButton isBlocked={isAuthorBlocked} onClick={blockReviewSender} />}
|
{canBlockReviewAuthor(profileId, review) && <BlockButton isBlocked={isAuthorBlocked} onClick={blockReviewSender} />}
|
||||||
{canDeleteReview(profileId, review) && <DeleteButton onClick={delReview} />}
|
{canDeleteReview(profileId, review) && <DeleteButton onClick={delReview} />}
|
||||||
|
@ -187,5 +175,5 @@ export default LazyComponent(() => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useAwaiter, useForceUpdater } from "@utils/react";
|
import { useAwaiter, useForceUpdater } from "@utils/react";
|
||||||
import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByCode, findByProps, findComponentByCode } from "@webpack";
|
||||||
import { Forms, React, RelationshipStore, useRef, UserStore } from "@webpack/common";
|
import { Forms, React, RelationshipStore, useRef, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
import { Auth, authorize } from "../auth";
|
import { Auth, authorize } from "../auth";
|
||||||
|
@ -27,11 +27,11 @@ import { settings } from "../settings";
|
||||||
import { cl, showToast } from "../utils";
|
import { cl, showToast } from "../utils";
|
||||||
import ReviewComponent from "./ReviewComponent";
|
import ReviewComponent from "./ReviewComponent";
|
||||||
|
|
||||||
const Transforms = findByPropsLazy("insertNodes", "textToText");
|
const Transforms = findByProps("insertNodes", "textToText");
|
||||||
const Editor = findByPropsLazy("start", "end", "toSlateRange");
|
const Editor = findByProps("start", "end", "toSlateRange");
|
||||||
const ChatInputTypes = findByPropsLazy("FORM");
|
const ChatInputTypes = findByProps("FORM");
|
||||||
const InputComponent = findComponentByCodeLazy("disableThemedBackground", "CHANNEL_TEXT_AREA");
|
const InputComponent = findComponentByCode("disableThemedBackground", "CHANNEL_TEXT_AREA");
|
||||||
const createChannelRecordFromServer = findByCodeLazy(".GUILD_TEXT])", "fromServer)");
|
const createChannelRecordFromServer = findByCode(".GUILD_TEXT])", "fromServer)");
|
||||||
|
|
||||||
interface UserProps {
|
interface UserProps {
|
||||||
discordId: string;
|
discordId: string;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { NotesIcon, OpenExternalIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { Alerts, Button, Menu, Parser, TooltipContainer } from "@webpack/common";
|
import { Alerts, Button, Menu, Parser, TooltipContainer } from "@webpack/common";
|
||||||
import { Guild, User } from "discord-types/general";
|
import { Guild, User } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import { getCurrentUserInfo, readNotification } from "./reviewDbApi";
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
import { showToast } from "./utils";
|
import { showToast } from "./utils";
|
||||||
|
|
||||||
const RoleButtonClasses = findByPropsLazy("button", "buttonInner", "icon", "banner");
|
const RoleButtonClasses = findByProps("button", "buttonInner", "icon", "banner");
|
||||||
|
|
||||||
const guildPopoutPatch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild, onClose(): void; }) => {
|
const guildPopoutPatch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild, onClose(): void; }) => {
|
||||||
if (!guild) return;
|
if (!guild) return;
|
||||||
|
|
|
@ -20,12 +20,11 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/Co
|
||||||
import { ReplyIcon } from "@components/Icons";
|
import { ReplyIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCode } from "@webpack";
|
||||||
import { ChannelStore, i18n, Menu, PermissionsBits, PermissionStore, SelectedChannelStore } from "@webpack/common";
|
import { ChannelStore, i18n, Menu, PermissionsBits, PermissionStore, SelectedChannelStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
|
const replyToMessage = findByCode(".TEXTAREA_FOCUS)", "showMentionToggle:");
|
||||||
const replyToMessage = findByCodeLazy(".TEXTAREA_FOCUS)", "showMentionToggle:");
|
|
||||||
|
|
||||||
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => {
|
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => {
|
||||||
// make sure the message is in the selected channel
|
// make sure the message is in the selected channel
|
||||||
|
|
|
@ -8,11 +8,11 @@ import { DataStore } from "@api/index";
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
import { findByCode, findStore } from "@webpack";
|
||||||
import { ChannelStore, GuildStore } from "@webpack/common";
|
import { ChannelStore, GuildStore } from "@webpack/common";
|
||||||
|
|
||||||
const SummaryStore = findByPropsLazy("allSummaries", "findSummary");
|
const SummaryStore = findStore("SummaryStore");
|
||||||
const createSummaryFromServer = findByCodeLazy(".people)),startId:", ".type}");
|
const createSummaryFromServer = findByCode(".people)),startId:", ".type}");
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
summaryExpiryThresholdDays: {
|
summaryExpiryThresholdDays: {
|
||||||
|
|
|
@ -11,12 +11,12 @@ import { openImageModal, openUserProfile } from "@utils/discord";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { ModalRoot, ModalSize, openModal } from "@utils/modal";
|
import { ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByProps, findComponentByCode } from "@webpack";
|
||||||
import { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, GuildStore, IconUtils, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, Timestamp, useEffect, UserStore, UserUtils, useState, useStateFromStores } from "@webpack/common";
|
import { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, GuildStore, IconUtils, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, Timestamp, useEffect, UserStore, UserUtils, useState, useStateFromStores } from "@webpack/common";
|
||||||
import { Guild, User } from "discord-types/general";
|
import { Guild, User } from "discord-types/general";
|
||||||
|
|
||||||
const IconClasses = findByPropsLazy("icon", "acronym", "childWrapper");
|
const IconClasses = findByProps("icon", "acronym", "childWrapper");
|
||||||
const FriendRow = findComponentByCodeLazy(".listName,discriminatorClass");
|
const FriendRow = findComponentByCode(".listName,discriminatorClass");
|
||||||
|
|
||||||
const cl = classNameFactory("vc-gp-");
|
const cl = classNameFactory("vc-gp-");
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList";
|
import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList";
|
||||||
import { Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { useForceUpdater } from "@utils/react";
|
import { useForceUpdater } from "@utils/react";
|
||||||
|
@ -89,13 +89,7 @@ function handleGuildUpdate() {
|
||||||
forceUpdateGuildCount?.();
|
forceUpdateGuildCount?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
const settings = definePluginSettings({
|
||||||
name: "ServerListIndicators",
|
|
||||||
description: "Add online friend count or server count in the server list",
|
|
||||||
authors: [Devs.dzshn],
|
|
||||||
dependencies: ["ServerListAPI"],
|
|
||||||
|
|
||||||
options: {
|
|
||||||
mode: {
|
mode: {
|
||||||
description: "mode",
|
description: "mode",
|
||||||
type: OptionType.SELECT,
|
type: OptionType.SELECT,
|
||||||
|
@ -105,10 +99,17 @@ export default definePlugin({
|
||||||
{ label: "Both server and online friend counts", value: IndicatorType.BOTH },
|
{ label: "Both server and online friend counts", value: IndicatorType.BOTH },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "ServerListIndicators",
|
||||||
|
description: "Add online friend count or server count in the server list",
|
||||||
|
authors: [Devs.dzshn],
|
||||||
|
dependencies: ["ServerListAPI"],
|
||||||
|
settings,
|
||||||
|
|
||||||
renderIndicator: () => {
|
renderIndicator: () => {
|
||||||
const { mode } = Settings.plugins.ServerListIndicators;
|
const { mode } = settings.store;
|
||||||
return <ErrorBoundary noop>
|
return <ErrorBoundary noop>
|
||||||
<div style={{ marginBottom: "4px" }}>
|
<div style={{ marginBottom: "4px" }}>
|
||||||
{!!(mode & IndicatorType.FRIEND) && <FriendsIndicator />}
|
{!!(mode & IndicatorType.FRIEND) && <FriendsIndicator />}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import React from "react";
|
||||||
const handleClick = async () =>
|
const handleClick = async () =>
|
||||||
console.log((await import("@webpack/common")).Clipboard.copy("\u200b"));
|
console.log((await import("@webpack/common")).Clipboard.copy("\u200b"));
|
||||||
|
|
||||||
export const Example: React.FC<{
|
export const Example: React.ComponentType<{
|
||||||
real: boolean,
|
real: boolean,
|
||||||
shigged?: number,
|
shigged?: number,
|
||||||
}> = ({ real, shigged }) => <>
|
}> = ({ real, shigged }) => <>
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findComponentByCodeLazy, findLazy } from "@webpack";
|
import { find, findComponentByCode } from "@webpack";
|
||||||
import { i18n, useToken } from "@webpack/common";
|
import { i18n, useToken } from "@webpack/common";
|
||||||
|
|
||||||
const ColorMap = findLazy(m => m.colors?.INTERACTIVE_MUTED?.css);
|
const ColorMap = find(m => m.colors?.INTERACTIVE_MUTED?.css);
|
||||||
const VerifiedIconComponent = findComponentByCodeLazy(".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP");
|
const VerifiedIconComponent = findComponentByCode(".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP");
|
||||||
|
|
||||||
export function VerifiedIcon() {
|
export function VerifiedIcon() {
|
||||||
const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();
|
const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();
|
||||||
|
|
|
@ -25,15 +25,15 @@ import { CopyIcon, LinkIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { copyWithToast } from "@utils/misc";
|
import { copyWithToast } from "@utils/misc";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
import { findByCode, findByProps } from "@webpack";
|
||||||
import { Tooltip, UserProfileStore } from "@webpack/common";
|
import { Tooltip, UserProfileStore } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
|
||||||
import { VerifiedIcon } from "./VerifiedIcon";
|
import { VerifiedIcon } from "./VerifiedIcon";
|
||||||
|
|
||||||
const useLegacyPlatformType: (platform: string) => string = findByCodeLazy(".TWITTER_LEGACY:");
|
const useLegacyPlatformType: (platform: string) => string = findByCode(".TWITTER_LEGACY:");
|
||||||
const platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy("isSupported", "getByUrl");
|
const platforms: { get(type: string): ConnectionPlatform; } = findByProps("isSupported", "getByUrl");
|
||||||
const getProfileThemeProps = findByCodeLazy(".getPreviewThemeColors", "primaryColor:");
|
const getProfileThemeProps = findByCode(".getPreviewThemeColors", "primaryColor:");
|
||||||
|
|
||||||
const enum Spacing {
|
const enum Spacing {
|
||||||
COMPACT,
|
COMPACT,
|
||||||
|
|
|
@ -16,10 +16,9 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { formatDuration } from "@utils/text";
|
import { formatDuration } from "@utils/text";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy, findComponentLazy } from "@webpack";
|
import { findByProps, findComponentByCode } from "@webpack";
|
||||||
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
|
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
|
||||||
import type { Channel } from "discord-types/general";
|
import type { Channel } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -78,19 +77,13 @@ const enum ChannelFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ChatScrollClasses = findByPropsLazy("auto", "managedReactiveScroller");
|
const ChatScrollClasses = findByProps("auto", "managedReactiveScroller");
|
||||||
const ChatClasses = findByPropsLazy("chat", "content", "noChat", "chatContent");
|
const ChatClasses = findByProps("chat", "content", "noChat", "chatContent");
|
||||||
const ChannelBeginHeader = findComponentByCodeLazy(".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE");
|
const ChannelBeginHeader = findComponentByCode(".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE");
|
||||||
const TagComponent = findComponentLazy(m => {
|
const TagComponent = findComponentByCode(".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG");
|
||||||
if (typeof m !== "function") return false;
|
|
||||||
|
|
||||||
const code = Function.prototype.toString.call(m);
|
const EmojiParser = findByProps("convertSurrogateToName");
|
||||||
// Get the component which doesn't include increasedActivity
|
const EmojiUtils = findByProps("getURL", "getEmojiColors");
|
||||||
return code.includes(".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG") && !code.includes("increasedActivityPill");
|
|
||||||
});
|
|
||||||
|
|
||||||
const EmojiParser = findByPropsLazy("convertSurrogateToName");
|
|
||||||
const EmojiUtils = findByPropsLazy("getURL", "getEmojiColors");
|
|
||||||
|
|
||||||
const ChannelTypesToChannelNames = {
|
const ChannelTypesToChannelNames = {
|
||||||
[ChannelTypes.GUILD_TEXT]: "text",
|
[ChannelTypes.GUILD_TEXT]: "text",
|
||||||
|
@ -163,7 +156,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.plugins.PermissionsViewer.enabled) {
|
if (Vencord.Plugins.isPluginEnabled("PermissionsViewer")) {
|
||||||
setPermissions(sortPermissionOverwrites(Object.values(permissionOverwrites).map(overwrite => ({
|
setPermissions(sortPermissionOverwrites(Object.values(permissionOverwrites).map(overwrite => ({
|
||||||
type: overwrite.type as PermissionType,
|
type: overwrite.type as PermissionType,
|
||||||
id: overwrite.id,
|
id: overwrite.id,
|
||||||
|
@ -280,7 +273,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
}
|
}
|
||||||
<div className="shc-lock-screen-allowed-users-and-roles-container">
|
<div className="shc-lock-screen-allowed-users-and-roles-container">
|
||||||
<div className="shc-lock-screen-allowed-users-and-roles-container-title">
|
<div className="shc-lock-screen-allowed-users-and-roles-container-title">
|
||||||
{Settings.plugins.PermissionsViewer.enabled && (
|
{Vencord.Plugins.isPluginEnabled("PermissionsViewer") && (
|
||||||
<Tooltip text="Permission Details">
|
<Tooltip text="Permission Details">
|
||||||
{({ onMouseLeave, onMouseEnter }) => (
|
{({ onMouseLeave, onMouseEnter }) => (
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -23,13 +23,13 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByProps } from "@webpack";
|
||||||
import { ChannelStore, PermissionsBits, PermissionStore, Tooltip } from "@webpack/common";
|
import { ChannelStore, PermissionsBits, PermissionStore, Tooltip } from "@webpack/common";
|
||||||
import type { Channel, Role } from "discord-types/general";
|
import type { Channel, Role } from "discord-types/general";
|
||||||
|
|
||||||
import HiddenChannelLockScreen from "./components/HiddenChannelLockScreen";
|
import HiddenChannelLockScreen from "./components/HiddenChannelLockScreen";
|
||||||
|
|
||||||
const ChannelListClasses = findByPropsLazy("modeMuted", "modeSelected", "unread", "icon");
|
const ChannelListClasses = findByProps("modeMuted", "modeSelected", "unread", "icon");
|
||||||
|
|
||||||
const enum ShowMode {
|
const enum ShowMode {
|
||||||
LockIcon,
|
LockIcon,
|
||||||
|
|
|
@ -10,12 +10,12 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findComponentLazy } from "@webpack";
|
import { findComponentByCode } from "@webpack";
|
||||||
import { ChannelStore, GuildMemberStore, i18n, Text, Tooltip } from "@webpack/common";
|
import { ChannelStore, GuildMemberStore, i18n, Text, Tooltip } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
import { FunctionComponent, ReactNode } from "react";
|
import { FunctionComponent, ReactNode } from "react";
|
||||||
|
|
||||||
const CountDown = findComponentLazy(m => m.prototype?.render?.toString().includes(".MAX_AGE_NEVER"));
|
const CountDown = findComponentByCode(".MAX_AGE_NEVER");
|
||||||
|
|
||||||
const enum DisplayStyle {
|
const enum DisplayStyle {
|
||||||
Tooltip = "tooltip",
|
Tooltip = "tooltip",
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue