Compare commits

..

744 commits

Author SHA1 Message Date
Nuckyz
7fcd9c3f06
why 2024-08-24 04:35:16 -03:00
Nuckyz
8bfacc139a
Clarify mapMangledModule can be used for primitive values 2024-08-24 02:34:50 -03:00
Nuckyz
a9a8c338a6
token not required anymore 2024-08-23 20:26:37 -03:00
Nuckyz
262319a97c
who cares about logging in :) 2024-08-23 20:26:03 -03:00
Nuckyz
0379beb0ba
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-23 20:11:44 -03:00
Nuckyz
13ada86934
Ignore another useless error 2024-08-23 19:10:06 -03:00
Nuckyz
fae5f9bfab
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-23 19:06:45 -03:00
Nuckyz
7d4fc5e8e1
more cleanie 2024-08-23 05:11:07 -03:00
Nuckyz
26a71caced
minor cleanup 2024-08-23 04:55:09 -03:00
Nuckyz
b1ad0a0d58
Clarify loading of chunksLeft 2024-08-23 03:35:06 -03:00
Nuckyz
4a9f258e34
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-23 03:09:04 -03:00
Nuckyz
301b0e7dfc
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-22 19:56:04 -03:00
Nuckyz
2f806dde95
of course I forgot this 2024-08-20 17:04:38 -03:00
Nuckyz
30ef53403b
Make findModuleFactory reporter testable 2024-08-20 16:58:10 -03:00
Nuckyz
ade9a523ac
Merge branch 'dev2' into immediate-finds-modules-proxy 2024-08-20 04:15:02 -03:00
Nuckyz
464dddff13
Only add ifs if IS_DEV 2024-08-20 04:09:39 -03:00
Nuckyz
e8965866e6
Restore with value instead of getter/setter 2024-08-20 04:06:47 -03:00
Nuckyz
e3d9b2001f
Fix persisting $$vencordPatchedSource when a module is loaded again 2024-08-20 03:56:59 -03:00
Nuckyz
e4bc7f2add
Merge branch 'dev' into immediate-finds 2024-08-18 17:16:31 -03:00
Nuckyz
edc87ac75e
fix for real now 2024-08-18 17:10:55 -03:00
Nuckyz
5c7773c7bb
apply suggestion and fix bug 2024-08-18 17:00:34 -03:00
Nuckyz
3546632bbf
Remove dead workaround 2024-08-18 01:19:34 -03:00
Nuckyz
9a48454a9f
better like this 2024-08-18 01:13:33 -03:00
Nuckyz
0e2c0b9bfb
Cleanup extractAndLoadChunksLazy error handling 2024-08-18 01:09:54 -03:00
Nuckyz
84c78a4262
Deprecate more unused apis 2024-08-18 01:02:58 -03:00
Nuckyz
cfbe4affc0
Merge branch 'dev2' into immediate-finds-modules-proxy 2024-08-18 00:52:31 -03:00
Nuckyz
e8f017b15e
bruh 2024-08-18 00:30:43 -03:00
Nuckyz
22a81ab142
Merge branch 'dev2' into immediate-finds-modules-proxy 2024-08-18 00:28:42 -03:00
Nuckyz
93d450a600
Make it dev only 2024-08-18 00:24:21 -03:00
Nuckyz
50bb6d867b
Add $$vencordPatchedSource 2024-08-18 00:22:02 -03:00
Nuckyz
6cc2f53501
Merge branch 'dev2' into immediate-finds-modules-proxy 2024-08-17 01:32:40 -03:00
Nuckyz
f9776ce1ae
NoTrack: Fix another issue related to proxies 2024-08-14 19:41:31 -03:00
Nuckyz
18c5ca216c
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-14 19:40:21 -03:00
Nuckyz
3f0d915c75
NoTrack: Fix on encoded assets 2024-08-14 19:25:59 -03:00
Nuckyz
a8f77a12df
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-13 01:53:44 -03:00
Nuckyz
44785d3498
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-11 18:57:47 -03:00
Nuckyz
473109b1d9
idk anymore 2024-08-05 13:25:25 -03:00
Nuckyz
f398a1c871
fix breaking settings 😭 2024-08-03 21:56:33 -03:00
Nuckyz
9871e16e28
fix error spam in non app discord websites 2024-08-03 17:11:03 -03:00
Nuckyz
b22d4622ed
for real now 2024-08-03 16:32:28 -03:00
Nuckyz
f05d462a73
last one 2024-08-03 16:23:42 -03:00
Nuckyz
c183018fb1
fix logged in dependant find 2024-08-03 15:28:18 -03:00
Nuckyz
f9c11a1149
unexplode console shortcuts 2024-08-03 15:13:27 -03:00
Nuckyz
45a876a0d5
more fixes 2024-08-03 15:02:19 -03:00
Nuckyz
4d88a13f5e
clean 2024-08-03 14:54:12 -03:00
Nuckyz
eeb4d26812
forgot this 2024-08-03 14:48:05 -03:00
Nuckyz
2429c283aa
this should be webpackDependantLazy 2024-08-03 14:43:21 -03:00
Nuckyz
1f1e3e8456
rename find 2024-08-03 14:42:05 -03:00
Nuckyz
64e1f294e6
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-03 14:34:31 -03:00
Nuckyz
e801c71fdf
Add back top level destructuring for backwards compabitlity 2024-08-03 14:33:03 -03:00
Nuckyz
4677ac779a
Add findComponentByFields and filters.componentByFilter 2024-08-03 14:01:52 -03:00
Nuckyz
ed32b7964d
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-03 13:29:02 -03:00
Nuckyz
76f8b0e38e
Make getUserSetting not return undefined 2024-08-03 13:27:46 -03:00
Nuckyz
e24bdc2b6f
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-02 21:32:11 -03:00
Nuckyz
4bcefb744d
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-02 21:19:25 -03:00
Nuckyz
4d03a695aa
Fix broken patches 2024-08-02 21:17:47 -03:00
Nuckyz
ca3768ca5d
🧹🧹🧹🧹🧹🧹 2024-08-02 20:48:44 -03:00
Nuckyz
6bdd0ba4a9
L overload react 2024-08-02 19:53:37 -03:00
Nuckyz
633a84581d
fix lint 2024-08-02 19:48:49 -03:00
Nuckyz
4a590d3d0a
Merge branch 'dev' into immediate-finds-modules-proxy 2024-08-02 19:46:57 -03:00
Nuckyz
1905aa0ae8
e 2024-07-25 21:37:37 -03:00
Nuckyz
026e716710
aaaaa 2024-07-24 18:03:21 -03:00
Nuckyz
9e6f24cc92
work 2024-07-24 18:02:02 -03:00
Nuckyz
75a8098590
I love not having a linter 2024-07-24 17:59:53 -03:00
Nuckyz
1f20074d4e
🧹🧹🧹 2024-07-24 17:55:35 -03:00
Nuckyz
fb394c6e1a
it didnt 2024-07-24 15:20:12 -03:00
Nuckyz
465dd15e2c
boop (please work I cant test) 2024-07-24 15:18:24 -03:00
Nuckyz
f676613173
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-20 19:37:54 -03:00
Nuckyz
be6209ee44
why is this still here 2024-07-20 19:37:45 -03:00
Nuckyz
15a3694533
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-20 19:33:45 -03:00
Nuckyz
9fd16825e2
oops 2024-07-20 19:32:41 -03:00
Nuckyz
129b770ffa
fixes 2024-07-20 19:30:24 -03:00
Nuckyz
42353373db
mapMangledModule: Properly support component finds 2024-07-20 19:17:05 -03:00
Nuckyz
5f7c44f478
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-19 01:01:48 -03:00
Nuckyz
2df13a2e17
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-19 01:01:32 -03:00
Nuckyz
dc116fc3b1
Merge branch 'dev' into modules-proxy-patches 2024-07-19 01:00:37 -03:00
Nuckyz
cd3534f6fc
Merge branch 'dev' into immediate-finds 2024-07-19 00:59:35 -03:00
Nuckyz
01bd41413d
FriendsSince: Fix broken patch 2024-07-19 00:57:03 -03:00
Nuckyz
654a271eae
eeee 2024-07-19 00:46:48 -03:00
Nuckyz
efd48e0364
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-17 17:03:53 -03:00
Nuckyz
09447d562e
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-17 17:03:48 -03:00
Nuckyz
e57c99399d
Merge branch 'dev' into modules-proxy-patches 2024-07-17 17:03:12 -03:00
Nuckyz
a3612dd4ee
Merge branch 'dev' into immediate-finds 2024-07-17 17:02:56 -03:00
Nuckyz
e9328cadea
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-17 16:08:06 -03:00
Nuckyz
8fa19656ae
fix grammar 2024-07-17 16:07:50 -03:00
Nuckyz
d58d8aea71
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-17 15:59:51 -03:00
Nuckyz
5462bb1438
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-17 15:59:48 -03:00
Nuckyz
9dadde6884
Merge branch 'dev' into modules-proxy-patches 2024-07-17 15:59:31 -03:00
Nuckyz
81a1822e70
Merge branch 'dev' into immediate-finds 2024-07-17 15:58:34 -03:00
Nuckyz
974953ba01
Fix mapMangledModule for primitives 2024-07-17 15:58:10 -03:00
Nuckyz
27fd143318
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-15 00:44:48 -03:00
Nuckyz
3bc71c688a
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-15 00:44:44 -03:00
Nuckyz
d869b2ddbb
Merge branch 'dev' into modules-proxy-patches 2024-07-15 00:44:21 -03:00
Nuckyz
fb3ae98419
Merge branch 'dev' into immediate-finds 2024-07-15 00:44:12 -03:00
Nuckyz
70df451e64
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-15 00:42:20 -03:00
Nuckyz
2fb616ebf1
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-15 00:42:16 -03:00
Nuckyz
bd25e0cd75
Merge branch 'dev' into modules-proxy-patches 2024-07-15 00:42:07 -03:00
Nuckyz
62d4add6c1
Merge branch 'dev' into immediate-finds 2024-07-15 00:41:44 -03:00
Nuckyz
3f5491d379
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-14 00:29:48 -03:00
Nuckyz
e35d0f680f
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-14 00:29:45 -03:00
Nuckyz
187ece1905
Merge branch 'dev' into modules-proxy-patches 2024-07-14 00:29:29 -03:00
Nuckyz
2b99f4ece3
Merge branch 'dev' into immediate-finds 2024-07-14 00:29:05 -03:00
Nuckyz
8bf98be472
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-12 16:43:20 -03:00
Nuckyz
0506505449
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-12 16:43:18 -03:00
Nuckyz
3edc36d5e0
Merge branch 'dev' into modules-proxy-patches 2024-07-12 16:43:06 -03:00
Nuckyz
6ffa969955
Merge branch 'dev' into immediate-finds 2024-07-12 16:42:46 -03:00
Nuckyz
6213fca9ed
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-11 17:36:22 -03:00
Nuckyz
56477d4e96
Fix testing factory filters on non factories 2024-07-11 17:32:36 -03:00
Nuckyz
104f193a76
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-11 17:17:37 -03:00
Nuckyz
293b90a6d2
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-11 17:17:34 -03:00
Nuckyz
8159937827
Merge branch 'dev' into modules-proxy-patches 2024-07-11 17:17:12 -03:00
Nuckyz
aa35602827
Merge branch 'dev' into immediate-finds 2024-07-11 17:16:15 -03:00
Nuckyz
42c4845261
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-10 04:36:22 -03:00
Nuckyz
710f627016
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-10 04:36:19 -03:00
Nuckyz
4389b78410
Merge branch 'dev' into modules-proxy-patches 2024-07-10 04:36:05 -03:00
Nuckyz
fde823fabf
Merge branch 'dev' into immediate-finds 2024-07-10 04:35:57 -03:00
Nuckyz
cce8f14d72
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-07 15:15:58 -03:00
Nuckyz
c8356570a3
crazy 2024-07-07 15:15:45 -03:00
Nuckyz
021baa54d3
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-07 15:11:00 -03:00
Nuckyz
ddd5d9e0c3
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-07 15:10:52 -03:00
Nuckyz
920fb20d8e
Merge branch 'dev' into modules-proxy-patches 2024-07-07 15:10:41 -03:00
Nuckyz
438b3e0598
Merge branch 'dev' into immediate-finds 2024-07-07 15:10:21 -03:00
Nuckyz
763b24aa92
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-05 04:06:04 -03:00
Nuckyz
65013f0149
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-05 04:06:01 -03:00
Nuckyz
24795ba9f8
Merge branch 'dev' into modules-proxy-patches 2024-07-05 04:05:52 -03:00
Nuckyz
aa29e479b9
Merge branch 'dev' into immediate-finds 2024-07-05 04:05:42 -03:00
Nuckyz
dd25044afd
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-05 04:05:02 -03:00
Nuckyz
8c1979481e
Add patch timings testing to reporter 2024-07-05 04:02:34 -03:00
Nuckyz
2a1684d902
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-03 04:50:32 -03:00
Nuckyz
b377cad1e6
fix reporter trying to JSON.stringify regex 2024-07-03 04:50:08 -03:00
Nuckyz
4e09e347e2
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-03 03:55:33 -03:00
Nuckyz
ea6fccb54e
fix setting parsed regex as filter logging props 2024-07-03 03:47:01 -03:00
Nuckyz
c784bc5dbd
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-03 00:12:49 -03:00
Nuckyz
edba931afe
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-03 00:12:45 -03:00
Nuckyz
208882e8ec
Merge branch 'dev' into modules-proxy-patches 2024-07-03 00:12:08 -03:00
Nuckyz
e0cb7242d6
Merge branch 'dev' into immediate-finds 2024-07-03 00:11:29 -03:00
Nuckyz
b3ab32180c
Merge branch 'dev' into immediate-finds 2024-07-03 00:07:01 -03:00
Nuckyz
2506ba1b2e
feat(plugins): ConsoleJanitor (#2659) 2024-07-03 00:06:12 -03:00
Nuckyz
0d0c63f596
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-02 21:53:20 -03:00
Nuckyz
8abb68c553
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-02 21:53:06 -03:00
Nuckyz
f6147c6c13
Merge branch 'dev' into modules-proxy-patches 2024-07-02 21:52:50 -03:00
Nuckyz
b5fdb43cbf
Merge branch 'dev' into immediate-finds 2024-07-02 21:51:41 -03:00
Nuckyz
30057985c4
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-02 20:21:41 -03:00
Nuckyz
a95037d80a
cleanup 2024-07-02 20:21:26 -03:00
Nuckyz
99e21ad284
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-02 20:17:34 -03:00
Nuckyz
d90bcdb063
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-02 20:17:16 -03:00
Nuckyz
771d51bcc3
Merge branch 'dev' into modules-proxy-patches 2024-07-02 20:12:21 -03:00
Nuckyz
c7e49672f5
Merge branch 'dev' into immediate-finds 2024-07-02 20:07:16 -03:00
Nuckyz
3331ed2155
forgot this 2024-07-02 20:01:15 -03:00
Nuckyz
bc34d72b57
Support regex in webpack finds 2024-07-02 20:00:05 -03:00
Vendicated
b333deb731
improve settings ui (again) 2024-07-02 18:51:51 +02:00
Nuckyz
614cbc1146
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-07-02 00:05:13 -03:00
Nuckyz
a985286c88
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-07-02 00:05:10 -03:00
Nuckyz
1297408171
Merge branch 'dev' into modules-proxy-patches 2024-07-02 00:05:03 -03:00
Nuckyz
cc536bdbf4
Merge branch 'dev' into immediate-finds 2024-07-02 00:04:54 -03:00
Nuckyz
ea859f59b0
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-29 19:18:06 -03:00
Nuckyz
a04ccd0d11
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-29 19:18:02 -03:00
Nuckyz
c1b4eb5b04
Merge branch 'dev' into modules-proxy-patches 2024-06-29 19:17:50 -03:00
Nuckyz
3f059e17be
Merge branch 'dev' into immediate-finds 2024-06-29 19:17:35 -03:00
Nuckyz
48442aee1d
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-29 04:45:09 -03:00
Nuckyz
9ca13d1250
boop 2024-06-29 04:45:00 -03:00
Nuckyz
2c3be4533e
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-29 02:24:53 -03:00
Nuckyz
7bf2152353
bleh 2024-06-29 02:24:45 -03:00
Nuckyz
a6f4622837
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-29 02:24:36 -03:00
Nuckyz
2f55c7b126
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-29 02:23:50 -03:00
Nuckyz
14d1a2d1ea
Merge branch 'dev' into immediate-finds 2024-06-29 02:23:23 -03:00
Nuckyz
332f3e532b
Dont depend on modules being an object again 2024-06-29 02:21:44 -03:00
Nuckyz
28a7fbb309
Merge branch 'dev' into modules-proxy-patches 2024-06-29 01:33:59 -03:00
Nuckyz
4caf86b60e
Merge branch 'dev' into modules-proxy-patches 2024-06-29 01:28:17 -03:00
Nuckyz
5a85d6e78e
Harder conditions for Sentry patching 2024-06-29 01:26:03 -03:00
Nuckyz
20cfa932a4
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-28 19:03:18 -03:00
Nuckyz
9e998db456
typings 2024-06-28 19:03:09 -03:00
Nuckyz
3d4a7638a4
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-28 18:56:02 -03:00
Nuckyz
ab8da19e23
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-28 18:55:58 -03:00
Nuckyz
b8335108e4
Merge branch 'dev' into modules-proxy-patches 2024-06-28 18:55:44 -03:00
Nuckyz
403276d307
Merge branch 'dev' into immediate-finds 2024-06-28 18:55:36 -03:00
Nuckyz
748a456cfb
Delete patching properties after used 2024-06-28 18:54:37 -03:00
Nuckyz
0cd0c813f2
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-28 18:43:31 -03:00
Nuckyz
f647ff0ee9
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-28 18:43:27 -03:00
Nuckyz
c2d708a621
Merge branch 'dev' into modules-proxy-patches 2024-06-28 18:43:03 -03:00
Nuckyz
35343bd790
Merge branch 'dev' into immediate-finds 2024-06-28 18:39:49 -03:00
Nuckyz
cc5d4a7b3a
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-28 00:58:26 -03:00
Nuckyz
ae655111de
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-28 00:58:19 -03:00
Nuckyz
b768c61ef8
Merge branch 'dev' into immediate-finds 2024-06-28 00:57:55 -03:00
Nuckyz
d95367b31d
Merge branch 'dev' into modules-proxy-patches 2024-06-28 00:57:36 -03:00
Nuckyz
1e4ad4db4c
Fix for latest webpack change 2024-06-28 00:42:36 -03:00
Nuckyz
d8ba959d1e
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-27 22:21:08 -03:00
Nuckyz
0742cecd41
clean commons 2024-06-27 22:20:58 -03:00
Nuckyz
ed4a797ad3
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-27 19:19:29 -03:00
Nuckyz
505246954b
why 2024-06-27 19:19:22 -03:00
Nuckyz
eecc21db91
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-27 19:00:23 -03:00
Nuckyz
962eaa9df7
this was too hacky and causing issues already 2024-06-27 18:57:57 -03:00
Nuckyz
0190ada1a1
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-27 18:47:52 -03:00
Nuckyz
b5a1b3a124
a little more 2024-06-27 18:47:29 -03:00
Nuckyz
1f3b8cdfd8
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-27 18:43:04 -03:00
Nuckyz
1f2c26cdba
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-27 18:42:57 -03:00
Nuckyz
3b6bef1cda
Merge branch 'dev' into modules-proxy-patches 2024-06-27 18:41:24 -03:00
Nuckyz
858b0e3dd7
oops 2024-06-27 18:40:58 -03:00
Nuckyz
718ebd56ac
Allow mapMangledModule to be destructured again 2024-06-27 18:39:57 -03:00
Nuckyz
1511260666
Merge branch 'dev' into immediate-finds 2024-06-27 17:50:41 -03:00
Nuckyz
4ff7c22505
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-27 06:42:40 -03:00
Nuckyz
057ccfde11
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-27 06:40:56 -03:00
Nuckyz
edf4e75ae2
Merge branch 'dev' into modules-proxy-patches 2024-06-27 06:38:08 -03:00
Nuckyz
62d9d1310d
Merge branch 'dev' into immediate-finds 2024-06-27 06:37:17 -03:00
Nuckyz
e592a50d7c
Fix broken patches 2024-06-27 06:35:01 -03:00
Nuckyz
c785053b86
Deprecate proxyLazy and proxyInner top level destructure 2024-06-27 06:01:13 -03:00
Nuckyz
e9081d2a52
No longer destructure at top level 2024-06-27 05:45:06 -03:00
Nuckyz
98c67e1165
add findByPropsAndExtract; allow other finds to parse result 2024-06-27 05:29:07 -03:00
Nuckyz
6c7d4259e1
Merge branch 'dev' into immediate-finds 2024-06-27 05:04:55 -03:00
Nuckyz
d8e3381fb3
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-23 19:48:34 -03:00
Nuckyz
bdb9c75c74
e 2024-06-23 19:48:15 -03:00
Nuckyz
a67b7847b1
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-23 16:48:26 -03:00
Nuckyz
bab081d4a9
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-23 16:48:23 -03:00
Nuckyz
0e5099416c
Merge branch 'dev' into modules-proxy-patches 2024-06-23 16:48:17 -03:00
Nuckyz
20efa661b0
Merge branch 'dev' into immediate-finds 2024-06-23 16:48:09 -03:00
Nuckyz
94ba593be9
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-23 16:29:03 -03:00
Nuckyz
c9295d3a85
of course... 2024-06-23 16:28:39 -03:00
Nuckyz
d55770797a
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-22 06:16:36 -03:00
Nuckyz
b4b67a98da
fix proxies not being constructable 2024-06-22 06:14:43 -03:00
Nuckyz
453c0b62f4
ff 2024-06-22 05:50:09 -03:00
Nuckyz
a3fa74735f
e 2024-06-22 05:40:34 -03:00
Nuckyz
a3cab94a68
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-22 02:57:46 -03:00
Nuckyz
c4e7233604
check for bundlePath value again 2024-06-22 02:57:36 -03:00
Nuckyz
889eb311f9
remove stuff I forgot 2024-06-22 02:50:34 -03:00
Nuckyz
03120d5a98
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-22 02:49:08 -03:00
Nuckyz
9446efadd5
a little more 2024-06-22 02:44:44 -03:00
Nuckyz
9c21c23364
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-22 02:39:26 -03:00
Nuckyz
ba6d3c7e60
organize 2024-06-22 02:37:40 -03:00
Nuckyz
cb1fff8d86
Merge branch 'dev' into immediate-finds-modules-proxy 2024-06-21 22:58:11 -03:00
Nuckyz
c400db41c3
Merge branch 'dev' into modules-proxy-patches 2024-06-21 22:58:02 -03:00
Nuckyz
de4743828a
Merge branch 'dev' into immediate-finds 2024-06-21 22:57:49 -03:00
Nuckyz
700a442ee4
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 22:55:20 -03:00
Nuckyz
dd3904badd
fix issues related to nested proxyInner 2024-06-21 22:54:18 -03:00
Nuckyz
0d360fb7e7
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 19:52:16 -03:00
Nuckyz
2429231965
Merge branch 'dev' into modules-proxy-patches 2024-06-21 19:51:36 -03:00
Nuckyz
570137040c
actually fix oops 2024-06-21 19:51:11 -03:00
Nuckyz
ad3bb91bc1
Merge branch 'dev' into immediate-finds 2024-06-21 19:50:09 -03:00
Nuckyz
161be30b2b
Fix dateFormat filter 2024-06-21 19:50:05 -03:00
Nuckyz
0a4bcd5ccd
fix cache find 2024-06-21 19:47:44 -03:00
Nuckyz
3a5859b815
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-21 18:57:31 -03:00
Nuckyz
1ea5f56549
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 18:57:28 -03:00
Nuckyz
a7b02f2f1f
Merge branch 'dev' into modules-proxy-patches 2024-06-21 18:57:16 -03:00
Nuckyz
32306cc6c3
Merge branch 'dev' into immediate-finds 2024-06-21 18:56:24 -03:00
Nuckyz
8cfb289dc7
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 18:32:58 -03:00
Nuckyz
220062acdb
fix broken find 2024-06-21 18:32:49 -03:00
Nuckyz
e5d5bc2d34
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 18:22:19 -03:00
Nuckyz
17cc81f15d
add findByFactoryCode to console shortcuts 2024-06-21 18:21:42 -03:00
Nuckyz
eba42489e9
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 18:14:54 -03:00
Nuckyz
51dee70ced
update error message 2024-06-21 18:14:41 -03:00
Nuckyz
11561e50f9
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 18:06:08 -03:00
Nuckyz
2095cc8d03
update flux events 2024-06-21 18:06:02 -03:00
Nuckyz
6e61ef297c
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 17:58:45 -03:00
Nuckyz
58e810dfbe
Merge branch 'dev' into immediate-finds 2024-06-21 17:57:45 -03:00
Nuckyz
b2497373f0
what is this doing here 2024-06-21 05:06:56 -03:00
Nuckyz
18841f4551
and also this 2024-06-21 05:06:11 -03:00
Nuckyz
da6ceb8479
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 05:05:56 -03:00
Nuckyz
6b811dce55
forgot to export this 2024-06-21 05:05:44 -03:00
Nuckyz
8982a53b47
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-21 05:01:44 -03:00
Nuckyz
3cf702a2ba
fixes 2024-06-21 05:01:35 -03:00
Nuckyz
cd79150a84
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-21 04:58:43 -03:00
Nuckyz
343e2802c3
boop 2024-06-21 04:52:08 -03:00
Nuckyz
dc8b579488
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-21 04:51:45 -03:00
Nuckyz
066001c57a
Add wreq.j 2024-06-21 04:45:16 -03:00
Nuckyz
24a0f62801
Merge branch 'dev' into modules-proxy-patches 2024-06-21 04:38:27 -03:00
Nuckyz
ef512e6ea1
forgot this 2024-06-21 04:30:12 -03:00
Nuckyz
c6b2eeb86d
Merge branch 'dev' into immediate-finds 2024-06-21 04:24:13 -03:00
Nuckyz
e457e58b49
Merge branch 'dev' into immediate-finds 2024-06-21 04:00:35 -03:00
Nuckyz
cac0398276
ReverseImageSearch: Fix duplicate find 2024-06-21 03:59:38 -03:00
Nuckyz
e93562b95b
Test mapMangledModule with new api 2024-06-21 03:53:39 -03:00
Nuckyz
f6dbcb7709
lazy extractAndLoadChunks result 2024-06-21 03:05:30 -03:00
Nuckyz
a82a0636cf
Merge branch 'dev' into immediate-finds 2024-06-21 03:03:07 -03:00
Nuckyz
2fc814124f
add new webpack apis 2024-06-21 02:23:04 -03:00
Vendicated
a43d5d595a
Plugin Page: add indicator for excluded plugins 2024-06-20 19:56:14 +02:00
Nuckyz
ceaaf9ab8a
Reporter: Test mapMangledModule 2024-06-20 01:00:07 -03:00
Nuckyz
a01ee40591
Clean-up related additions to mangled exports 2024-06-19 23:50:04 -03:00
Nuckyz
26c2674652
Merge branch 'dev' into immediate-finds-modules-proxy 2024-06-18 17:20:00 -03:00
Nuckyz
9595f75a9a
Merge branch 'dev' into modules-proxy-patches 2024-06-18 17:19:52 -03:00
Nuckyz
2189ce407b
Merge branch 'dev' into immediate-finds 2024-06-18 17:19:42 -03:00
Nuckyz
7b4f97fa08
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-16 20:07:59 -03:00
Nuckyz
f208472841
\n 2024-06-16 20:07:48 -03:00
Nuckyz
4e4a9f806f
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-16 19:57:31 -03:00
Nuckyz
afe6d9f7b3
Separate wrapFactory and patchFactory 2024-06-16 19:53:31 -03:00
Nuckyz
2dac66d7c6
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-14 18:15:32 -03:00
Nuckyz
83b09a8073
Merge branch 'dev' into modules-proxy-patches 2024-06-14 18:15:23 -03:00
Nuckyz
13d47d91bf
Merge branch 'dev' into immediate-finds 2024-06-14 18:15:14 -03:00
Nuckyz
004f764c2b
Merge branch 'dev' into immediate-finds-modules-proxy 2024-06-13 23:31:30 -03:00
Nuckyz
a815122e3c
Merge branch 'dev' into modules-proxy-patches 2024-06-13 23:31:20 -03:00
Nuckyz
b88e7faa72
Merge branch 'dev' into immediate-finds 2024-06-13 23:31:10 -03:00
Nuckyz
bb22355a57
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-13 00:03:39 -03:00
Nuckyz
591f433135
forgot the comment 2024-06-13 00:00:15 -03:00
Nuckyz
f726376ab8
avoid circular dependency 2024-06-12 23:59:42 -03:00
Nuckyz
74bd89b721
Make all plugins use new settings API 2024-06-12 23:56:02 -03:00
Nuckyz
aa4c6e5496
Update permissions 2024-06-12 22:50:25 -03:00
Nuckyz
e8d696c18c
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-12 22:32:52 -03:00
Nuckyz
d473d52047
update comment 2024-06-12 22:32:42 -03:00
Nuckyz
36c8058920
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-12 22:20:52 -03:00
Nuckyz
8d31f3cf62
Use $$vencordOriginal as fallback 2024-06-12 22:14:52 -03:00
Nuckyz
5021d2e344
Merge branch 'dev' into immediate-finds-modules-proxy 2024-06-12 19:16:04 -03:00
Nuckyz
92653eaf96
Merge branch 'dev' into modules-proxy-patches 2024-06-12 19:15:47 -03:00
Nuckyz
2f6e39c0bd
Merge branch 'dev' into immediate-finds 2024-06-12 19:15:40 -03:00
Nuckyz
5e52ecf42e
Merge branch 'dev' into immediate-finds-modules-proxy 2024-06-12 18:31:38 -03:00
Nuckyz
b2ae33344b
Merge branch 'dev' into modules-proxy-patches 2024-06-12 18:31:23 -03:00
Nuckyz
b24e8cb9e6
Merge branch 'dev' into immediate-finds 2024-06-12 18:31:14 -03:00
Nuckyz
73b1c7b811
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-12 17:50:28 -03:00
Nuckyz
210fada19a
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-12 17:49:52 -03:00
Nuckyz
002a1cfc16
grrr 2024-06-12 17:46:37 -03:00
Nuckyz
e9e25306eb
grrr 2024-06-12 17:45:54 -03:00
Nuckyz
5931a72de2
More re-ordering 2024-06-12 17:37:16 -03:00
Nuckyz
3d0ce5449d
move down 2024-06-12 17:37:15 -03:00
Nuckyz
31c39bc761
guh 2024-06-12 17:37:15 -03:00
Nuckyz
1d2b8a43c0
Decouple factoryListeners from patchFactory 2024-06-12 17:37:15 -03:00
Nuckyz
6d587e6530
More re-ordering 2024-06-12 17:36:43 -03:00
Nuckyz
853585c0bc
move down 2024-06-12 17:33:26 -03:00
Nuckyz
6826fe003c
guh 2024-06-12 17:31:05 -03:00
Nuckyz
c3bbc92fa2
Decouple factoryListeners from patchFactory 2024-06-12 17:30:26 -03:00
Nuckyz
ed35c496dc
Merge branch 'dev' into modules-proxy-patches 2024-06-12 17:13:21 -03:00
Nuckyz
dc8ac98a6e
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-12 17:11:04 -03:00
Nuckyz
337850c33a
Merge branch 'dev' into immediate-finds 2024-06-12 17:09:10 -03:00
Nuckyz
08f1b6a3c9
LazyComponents: Allow accessing inner; Improve typings 2024-06-12 17:06:20 -03:00
Nuckyz
c8ad68c80b
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-10 20:29:26 -03:00
Nuckyz
7b056364da
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-10 20:29:03 -03:00
Nuckyz
7f3cad2528
Merge branch 'dev' into modules-proxy-patches 2024-06-10 20:28:45 -03:00
Nuckyz
5d290ecd35
Merge branch 'dev' into immediate-finds 2024-06-10 20:28:31 -03:00
Nuckyz
b702b31744
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-07 23:29:21 -03:00
Nuckyz
3dbe621059
blehh 2024-06-07 23:29:13 -03:00
Nuckyz
55195676b8
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-07 23:25:28 -03:00
Nuckyz
76cb49c381
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-07 23:25:24 -03:00
Nuckyz
95c4cc09af
Merge branch 'dev' into modules-proxy-patches 2024-06-07 23:25:17 -03:00
Nuckyz
a5b30e762a
Merge branch 'dev' into immediate-finds 2024-06-07 23:24:57 -03:00
Nuckyz
5bbf467be0
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-06 00:50:57 -03:00
Nuckyz
46c771f351
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-06 00:50:44 -03:00
Nuckyz
94ea4f8e5c
Merge branch 'dev' into modules-proxy-patches 2024-06-06 00:50:09 -03:00
Nuckyz
fc8a0e4904
Merge branch 'dev' into immediate-finds 2024-06-06 00:49:36 -03:00
Nuckyz
9eb77cb7fd
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-05 23:58:09 -03:00
Nuckyz
e1bbd67a9a
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-05 23:57:59 -03:00
Nuckyz
625b248a95
Merge branch 'dev' into modules-proxy-patches 2024-06-05 23:57:32 -03:00
Nuckyz
94c365b1c3
Merge branch 'dev' into immediate-finds 2024-06-05 23:57:26 -03:00
Nuckyz
f70e9290ce
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-05 22:36:40 -03:00
Nuckyz
57b011aea7
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-05 22:36:36 -03:00
Nuckyz
c8097f0f1a
Merge branch 'dev' into modules-proxy-patches 2024-06-05 22:36:29 -03:00
Nuckyz
5999af76c6
Merge branch 'dev' into immediate-finds 2024-06-05 22:34:55 -03:00
Nuckyz
05717d6bc3
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-02 18:49:21 -03:00
Nuckyz
53dd86fa6e
Improve typings and other stuff 2024-06-02 18:46:03 -03:00
Nuckyz
363f2e84fb
Merge branch 'dev' into immediate-finds-modules-proxy 2024-06-01 23:42:20 -03:00
Nuckyz
066ce07512
Merge branch 'dev' into modules-proxy-patches 2024-06-01 23:41:58 -03:00
Nuckyz
f5b1b65db8
Merge branch 'dev' into immediate-finds 2024-06-01 23:41:49 -03:00
Nuckyz
6e6ee4db68
NoPendingCount: Fix for message requests 2024-06-01 23:40:05 -03:00
Nuckyz
ac1c417e1c
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 19:53:07 -03:00
Nuckyz
4e14232b5a
Fix patching pre-populated factories 2024-06-01 19:52:17 -03:00
Nuckyz
eddfca06ab
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 19:38:36 -03:00
Nuckyz
61e1eada01
Fix not restoring some original factories 2024-06-01 19:38:01 -03:00
Nuckyz
85322f9e90
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 18:42:44 -03:00
Nuckyz
d329d74fec
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-01 18:42:40 -03:00
Nuckyz
ac6a21374f
Merge branch 'dev' into modules-proxy-patches 2024-06-01 18:42:18 -03:00
Nuckyz
b385be51d6
Merge branch 'dev' into immediate-finds 2024-06-01 18:40:33 -03:00
Nuckyz
d8524b087c
Add shortcut for lazy loading chunks 2024-06-01 18:39:01 -03:00
Nuckyz
c491122937
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 18:18:24 -03:00
Nuckyz
13337950dc
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-01 18:16:40 -03:00
Nuckyz
281ab9194b
Merge branch 'dev' into modules-proxy-patches 2024-06-01 18:13:49 -03:00
Nuckyz
a1881bff3d
Merge branch 'dev' into immediate-finds 2024-06-01 18:12:22 -03:00
Nuckyz
c50208b019
Add shortcut for lazy loading chunks 2024-06-01 18:10:45 -03:00
Nuckyz
a8974f01eb
Merge branch 'dev' into immediate-finds 2024-06-01 18:09:19 -03:00
Nuckyz
b79a0dadcb
Merge branch 'dev' into modules-proxy-patches 2024-06-01 18:06:38 -03:00
Nuckyz
c4c92ed366
Add shortcut for lazy loading chunks 2024-06-01 17:51:50 -03:00
Vendicated
78fd37a4c6
fix(css): brand-experiment is now brand-500 2024-06-01 19:13:27 +02:00
Nuckyz
9de6e67cf1
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 05:03:56 -03:00
Nuckyz
33d5753ca7
fix grammar issues 2024-06-01 05:03:47 -03:00
Nuckyz
8d3feef9a1
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 01:45:03 -03:00
Nuckyz
8580332c82
cleanup 2024-06-01 01:44:18 -03:00
Nuckyz
4d8c56689c
Future proof against array modules 2024-06-01 01:40:44 -03:00
Nuckyz
5cbb816c1c
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 00:36:36 -03:00
Nuckyz
b6594051d9
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-01 00:36:33 -03:00
Nuckyz
50415a949d
Merge branch 'dev' into modules-proxy-patches 2024-06-01 00:35:34 -03:00
Nuckyz
4b03454bce
Merge branch 'dev' into immediate-finds 2024-06-01 00:35:24 -03:00
Nuckyz
f1b649e996
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 00:22:38 -03:00
Nuckyz
db5397f41a
sdfdsf 2024-06-01 00:22:17 -03:00
Nuckyz
c34f40e30d
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 00:17:26 -03:00
Nuckyz
dd4d80872e
fix reporter part 2 2024-06-01 00:17:15 -03:00
Nuckyz
eb381767cd
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 00:11:16 -03:00
Nuckyz
0aff3c29bc
Fix reporter 2024-06-01 00:11:00 -03:00
Nuckyz
e7fdb3881a
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 00:06:39 -03:00
Nuckyz
5977ff8f6b
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-06-01 00:06:34 -03:00
Nuckyz
dd13b96728
Revert "cya webpackChunkdiscord_app part 2"
This reverts commit a1e72e78d7.
2024-06-01 00:05:36 -03:00
Nuckyz
01fdeb7292
cya webpackChunkdiscord_app part 2 2024-06-01 00:05:15 -03:00
Nuckyz
6a3831c437
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-06-01 00:01:07 -03:00
Nuckyz
c485864ee8
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-31 23:58:20 -03:00
Nuckyz
2ab7d3209e
Merge branch 'dev' into modules-proxy-patches 2024-05-31 23:57:07 -03:00
Nuckyz
654b2e8398
Merge branch 'dev' into immediate-finds 2024-05-31 23:47:31 -03:00
Nuckyz
3f573c9af3
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 19:58:36 -03:00
Nuckyz
cbd9a9312c
don't depend in the value of bundlePath 2024-05-31 19:58:26 -03:00
Nuckyz
2656b60347
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 17:36:03 -03:00
Nuckyz
fbb7ee50dd
Revert indexOf change 2024-05-31 17:34:32 -03:00
Nuckyz
4187932aa7
\n 2024-05-31 06:27:02 -03:00
Nuckyz
a19fb71c70
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 06:20:17 -03:00
Nuckyz
e21a6be4b6
sfdsfdsfdsf 2024-05-31 06:19:57 -03:00
Nuckyz
b53c78c2ba
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 06:16:12 -03:00
Nuckyz
db63fffe18
I should still be defining this 2024-05-31 06:16:01 -03:00
Nuckyz
41ab8da5ad
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-31 05:55:51 -03:00
Nuckyz
f68effc7e2
more robust find 2024-05-31 05:50:34 -03:00
Nuckyz
f21bfb9d78
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 05:30:36 -03:00
Nuckyz
f4cc95da5a
Use indexOf in more places 2024-05-31 05:29:01 -03:00
Nuckyz
3a32490937
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 05:20:21 -03:00
Nuckyz
545d69aa6d
Use indexOf instead of includes; reset global find regex state 2024-05-31 05:19:34 -03:00
Nuckyz
aa5ca42676
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-31 00:21:32 -03:00
Nuckyz
5197170b3d
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-31 00:21:29 -03:00
Nuckyz
47eec049fc
Not needed anymore and breaks interpolated strings with newlines 2024-05-31 00:21:15 -03:00
Nuckyz
022a0497c3
Merge branch 'dev' into modules-proxy-patches 2024-05-31 00:20:22 -03:00
Nuckyz
e2f936538e
Merge branch 'dev' into immediate-finds 2024-05-31 00:20:06 -03:00
Nuckyz
b323fbb486
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-30 18:39:39 -03:00
Nuckyz
0c4e265530
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-30 18:39:32 -03:00
Nuckyz
111a4f2aa8
Merge branch 'dev' into modules-proxy-patches 2024-05-30 18:39:14 -03:00
Nuckyz
46710bf8cb
Merge branch 'dev' into immediate-finds 2024-05-30 18:38:41 -03:00
Nuckyz
1f938211a8
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-30 18:12:07 -03:00
Nuckyz
8d362fc394
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-30 18:11:51 -03:00
Nuckyz
79849fd37d
Merge branch 'dev' into modules-proxy-patches 2024-05-30 18:11:23 -03:00
Nuckyz
a838d587ae
Merge branch 'dev' into immediate-finds 2024-05-30 18:11:10 -03:00
Nuckyz
3a25da5f14
Fix wrong external files and clean up build script; Remove non used stuff 2024-05-30 18:03:00 -03:00
Nuckyz
a1e72e78d7
cya webpackChunkdiscord_app part 2 2024-05-30 17:32:54 -03:00
Nuckyz
48fb6ecd1a
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-30 13:38:39 -03:00
Nuckyz
3c62e393a3
edit another license header 2024-05-30 13:38:22 -03:00
Nuckyz
034ef554fb
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-30 05:24:05 -03:00
Nuckyz
2da9bf8f0e
fix typo 2024-05-30 05:23:53 -03:00
Nuckyz
eb5fb0df29
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-30 05:16:41 -03:00
Nuckyz
479a4069b2
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-30 05:16:27 -03:00
Nuckyz
e22575805b
Merge branch 'dev' into modules-proxy-patches 2024-05-30 05:15:44 -03:00
Nuckyz
c0984db612
Merge branch 'dev' into immediate-finds 2024-05-30 05:13:13 -03:00
Nuckyz
9a9c1b0487
Reporter: Properly implement reporter build of Vencord; Test more plugins; Fix running in wrong pages 2024-05-30 04:44:13 -03:00
Nuckyz
072619e539
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-30 01:10:48 -03:00
Nuckyz
9084459933
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-30 01:10:26 -03:00
Nuckyz
36f9eda3a8
Merge branch 'dev' into modules-proxy-patches 2024-05-30 01:09:11 -03:00
Nuckyz
99160638df
sdfgdsfdsds 2024-05-30 01:04:44 -03:00
Nuckyz
2574d5311d
Merge branch 'dev' into immediate-finds 2024-05-30 01:03:24 -03:00
Nuckyz
7816727e26
Merge branch 'dev' into immediate-finds 2024-05-30 01:02:25 -03:00
Nuckyz
892de53603
Fix extractAndLoadChunks issue with 2 match groups; Improve testing of lazy extractAndLoadChunks 2024-05-30 00:51:23 -03:00
Nuckyz
8de1ca86a9
I only understood today the reason for the Object.assign 2024-05-29 23:42:14 -03:00
Nuckyz
01ba87cd76
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-29 06:48:48 -03:00
Nuckyz
83222631ab
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-29 06:48:36 -03:00
Nuckyz
b74581908e
Merge branch 'dev' into modules-proxy-patches 2024-05-29 06:48:14 -03:00
Nuckyz
896b8970b6
Merge branch 'dev' into immediate-finds 2024-05-29 06:47:23 -03:00
Nuckyz
c8602ef52b
Fix reporter breaking because of ConsoleShortcuts 2024-05-29 06:45:44 -03:00
Nuckyz
ac1423f90c
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-29 06:07:02 -03:00
Nuckyz
d0e4ec0ad5
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-29 06:06:40 -03:00
Nuckyz
7509f203cc
Merge branch 'dev' into modules-proxy-patches 2024-05-29 06:05:44 -03:00
Nuckyz
17b575070f
Merge branch 'dev' into immediate-finds 2024-05-29 06:05:20 -03:00
Nuckyz
4a872236e1
Fix reporter breaking because of ConsoleShortcuts 2024-05-29 06:03:31 -03:00
Nuckyz
d5440349c9
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-29 05:12:14 -03:00
Nuckyz
0f9b5f2d09
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-29 05:11:52 -03:00
Nuckyz
4db6c4b88a
Merge branch 'dev' into modules-proxy-patches 2024-05-29 05:10:24 -03:00
Nuckyz
6e1094a5d1
Merge branch 'dev' into immediate-finds 2024-05-29 05:08:19 -03:00
Nuckyz
15df3485d1
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 18:11:40 -03:00
Nuckyz
ea86df7174
Merge branch 'dev' into modules-proxy-patches 2024-05-28 18:11:03 -03:00
Nuckyz
66c466c9f0
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 18:03:41 -03:00
Nuckyz
96d5e1b89b
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-28 18:03:35 -03:00
Nuckyz
4b4caa798a
onceReady -> onceDiscordLoaded 2024-05-28 18:02:57 -03:00
Nuckyz
73503945fb
Add WebpackInstances shortcut 2024-05-28 17:58:54 -03:00
Nuckyz
43b679d676
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-28 17:51:36 -03:00
Nuckyz
011b375d02
fix reporter 2024-05-28 17:49:20 -03:00
Nuckyz
9f1f2b15a4
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 17:46:58 -03:00
Nuckyz
a1309ea897
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-28 17:45:36 -03:00
Nuckyz
a4073703fd
explain UNCONFIGURABLE_PROPERTIES better 2024-05-28 17:44:36 -03:00
vee
84b9e3fec1
ConsoleShortcuts: Fix autocomplete on lazies, add more utils (#2519) 2024-05-28 17:44:36 -03:00
Nuckyz
6bbd91fafc
Merge branch 'dev' into immediate-finds 2024-05-28 17:41:34 -03:00
Nuckyz
d78f1c8000
where did this come from? 2024-05-28 17:15:25 -03:00
Nuckyz
64262001e8
boop 2024-05-28 17:14:35 -03:00
Nuckyz
6b648f3d38
oops! 2024-05-28 17:12:36 -03:00
Nuckyz
1eeadbcd97
export all webpack instances 2024-05-28 17:11:17 -03:00
Nuckyz
f016d277b7
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 04:27:52 -03:00
Nuckyz
9c2545ab16
undo explosion 2024-05-28 04:27:36 -03:00
Nuckyz
b36d3b4385
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 04:00:41 -03:00
Nuckyz
acbc932542
give name to PatchedFactory 2024-05-28 03:57:56 -03:00
Nuckyz
3590d5abff
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 03:35:52 -03:00
Nuckyz
c9c09b95a3
fix typo 2024-05-28 03:35:38 -03:00
Nuckyz
9128eb5760
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 03:34:51 -03:00
Nuckyz
513d9f4209
I knew I was forgetting something 2024-05-28 03:34:40 -03:00
Nuckyz
06393211b1
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-28 03:32:02 -03:00
Nuckyz
ac3130d37e
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-28 03:31:54 -03:00
Nuckyz
3e2952890f
Merge branch 'dev' into modules-proxy-patches 2024-05-28 03:31:37 -03:00
Nuckyz
a0751a0f84
Merge branch 'dev' into immediate-finds 2024-05-28 03:27:17 -03:00
Nuckyz
fa45beb8ca
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-27 23:33:43 -03:00
Nuckyz
539b70cd52
lmao oops 2024-05-27 23:32:40 -03:00
Nuckyz
e96458fafa
fixes for if we use prototype proxy in the future 2024-05-27 23:31:08 -03:00
Nuckyz
a1542bcec5
okay codium agent 2024-05-27 23:21:51 -03:00
Nuckyz
e00da485e8
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-27 18:28:22 -03:00
Nuckyz
513eea8d14
Prepare for in case modules object is accessed directly in the future 2024-05-27 18:27:21 -03:00
Nuckyz
490e9131b5
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 21:17:18 -03:00
Nuckyz
9ceb0ae7cb
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-26 21:17:15 -03:00
Nuckyz
6d59a943da
Merge branch 'dev' into modules-proxy-patches 2024-05-26 21:17:02 -03:00
Nuckyz
00d71fbeab
Merge branch 'dev' into immediate-finds 2024-05-26 21:16:46 -03:00
Nuckyz
4459d11a97
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 20:57:55 -03:00
Nuckyz
1eab0146dd
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-26 20:57:07 -03:00
Nuckyz
f345484e5b
Merge branch 'dev' into modules-proxy-patches 2024-05-26 20:56:31 -03:00
Nuckyz
65adaf335c
adjust size 2024-05-26 20:55:33 -03:00
Nuckyz
437e4eae44
Update flux events again 2024-05-26 20:53:08 -03:00
Nuckyz
f7d12d209c
Merge branch 'dev' into immediate-finds 2024-05-26 20:47:52 -03:00
Nuckyz
8a5678bec5
update more licenses 2024-05-26 20:41:28 -03:00
Nuckyz
1f99162b5a
update patchWebpack license 2024-05-26 20:38:57 -03:00
Nuckyz
8c5f2c897e
Document patchWebpack better 2024-05-26 20:22:03 -03:00
Nuckyz
9ada9bc1a9
e part 2 2024-05-26 19:51:34 -03:00
Nuckyz
8fd22f6deb
e 2024-05-26 19:50:47 -03:00
Nuckyz
c1e78b4397
hasOwn != in 2024-05-26 19:50:16 -03:00
Nuckyz
32a2c90761
fix typing of the global 2024-05-26 19:40:33 -03:00
Nuckyz
dae3841f10
ughh 2024-05-26 19:38:25 -03:00
Nuckyz
4d27643d39
type more 2024-05-26 19:37:47 -03:00
Nuckyz
c2047e5f3b
fix typos 2024-05-26 19:27:52 -03:00
Nuckyz
18142ecccb
fix doc 2024-05-26 19:26:26 -03:00
Nuckyz
440cb1f29c
Properly document wreq.a 2024-05-26 19:25:06 -03:00
Nuckyz
64b1ab1112
Properly document wreq.a 2024-05-26 19:24:59 -03:00
Nuckyz
3da88100df
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 07:00:21 -03:00
Nuckyz
3e3201ad0d
improve wreq docs 2024-05-26 07:00:03 -03:00
Nuckyz
a2bda05211
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 05:47:45 -03:00
Nuckyz
1ed956114f
fix logic 2024-05-26 05:46:53 -03:00
Nuckyz
2e27a513ac
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 05:30:32 -03:00
Nuckyz
a8fa685cfa
Add back running modules without patches 2024-05-26 05:29:05 -03:00
Nuckyz
b2036762b5
Add back running modules without patches 2024-05-26 05:28:34 -03:00
Nuckyz
067a16c9dc
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 05:24:55 -03:00
Nuckyz
265cf12d39
I love 2024-05-26 05:24:03 -03:00
Nuckyz
b580d6dcfb
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 05:20:39 -03:00
Nuckyz
affd527bc1
Make factory wrapper a little more future proof 2024-05-26 05:19:52 -03:00
Nuckyz
7d928e53aa
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 01:14:13 -03:00
Nuckyz
b10afebc98
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-26 01:14:01 -03:00
Nuckyz
1a8a901e0a
Merge branch 'dev' into modules-proxy-patches 2024-05-26 01:13:24 -03:00
Nuckyz
d936604f35
Merge branch 'dev' into immediate-finds 2024-05-26 01:12:22 -03:00
Nuckyz
4dcc265be0
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-26 00:30:58 -03:00
Nuckyz
3e6e399544
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-26 00:29:49 -03:00
Nuckyz
9af63b362d
more future proof 2024-05-26 00:27:13 -03:00
Nuckyz
090a3bc0a8
this formatter is stupid 2024-05-25 23:58:42 -03:00
Nuckyz
3331723496
fix the linting 2024-05-25 23:57:23 -03:00
Nuckyz
999d6c812f
better types? no ts-ignore, also filters.componentByCode is recursive now 2024-05-25 23:51:59 -03:00
Nuckyz
c9c1e0c6c5
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 18:46:52 -03:00
Nuckyz
1e55ae5327
this is more clean 2024-05-24 18:46:36 -03:00
Nuckyz
5b96881177
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 08:24:56 -03:00
Nuckyz
daa1a35fc3
Factories are called with a this 2024-05-24 08:23:41 -03:00
Nuckyz
ef895e787a
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 08:02:04 -03:00
Nuckyz
2f16cdf77b
Make toStringTag non enumerable 2024-05-24 07:59:56 -03:00
Nuckyz
e990795783
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 07:41:52 -03:00
Nuckyz
8dde496757
one more name cuz why not 2024-05-24 07:40:36 -03:00
Nuckyz
35f950c6e3
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 05:24:59 -03:00
Nuckyz
5fbabb0b70
sob 2024-05-24 05:24:37 -03:00
Nuckyz
ff9cc2e9e5
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 05:19:20 -03:00
Nuckyz
3793acd9bb
forgot the comment 2024-05-24 05:19:12 -03:00
Nuckyz
ebae259f5d
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 05:17:17 -03:00
Nuckyz
3296ee1c4b
Remove onChunksLoaded patch 2024-05-24 05:14:27 -03:00
Nuckyz
2f87363b89
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 03:58:15 -03:00
Nuckyz
bacf021a28
aaaaa 2024-05-24 03:57:54 -03:00
Nuckyz
1138e22f58
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 03:50:03 -03:00
Nuckyz
d6b5bc58ce
how many times 2024-05-24 03:49:14 -03:00
Nuckyz
bd2264c125
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 03:46:43 -03:00
Nuckyz
86f69e84c1
I'm stupid 2024-05-24 03:45:46 -03:00
Nuckyz
488f133a90
Handle if for some reason modules are set again 2024-05-24 03:44:40 -03:00
Nuckyz
77d8e70059
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 03:13:56 -03:00
Nuckyz
f64b228cb9
better log 2024-05-24 03:13:41 -03:00
Nuckyz
90f37471e5
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 03:13:09 -03:00
Nuckyz
b192c89146
I can never not forget something 2024-05-24 03:12:48 -03:00
Nuckyz
ae10d3667c
Take a different approach which requires less cursed code 2024-05-24 03:12:48 -03:00
Nuckyz
f727d101fc
I can never not forget something 2024-05-24 03:09:25 -03:00
Nuckyz
9bbec66ea5
Take a different approach which requires less cursed code 2024-05-24 03:08:35 -03:00
Nuckyz
0146789514
Preserve original modules prototype 2024-05-24 02:02:54 -03:00
Nuckyz
b38ab066d9
Preserve original modules prototype 2024-05-24 02:02:28 -03:00
Nuckyz
37514e0720
mod -> module 2024-05-24 00:14:07 -03:00
Nuckyz
aa9be97f83
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-24 00:00:36 -03:00
Nuckyz
d8c6559967
I forgot this 2024-05-23 23:56:29 -03:00
Nuckyz
72b014fe67
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-23 23:55:09 -03:00
Nuckyz
8eb4eab2b0
oops you were not meant to be here 2024-05-23 23:33:20 -03:00
Nuckyz
07361ff6fe
eww new line 2024-05-23 23:32:46 -03:00
Nuckyz
64212512ca
cya dummyObj 2024-05-23 23:20:46 -03:00
Nuckyz
5e762ddd04
Add names to Modules objects 2024-05-23 23:18:43 -03:00
Nuckyz
74f36a093b
Preserve ProxyDummy function name after minification 2024-05-23 23:14:00 -03:00
Nuckyz
c01a8c2f78
I changed my mind 2024-05-23 22:52:32 -03:00
Nuckyz
90c26432f5
Properly set receiver 2024-05-23 22:51:23 -03:00
Nuckyz
6f25005057
Monkey patch toString on proxyInner and proxyLazy 2024-05-23 22:20:24 -03:00
Nuckyz
23c8818ed2
Merge branch 'dev' into immediate-finds 2024-05-23 22:13:20 -03:00
Nuckyz
16d05c8935
Merge branch 'dev' into modules-proxy-patches 2024-05-23 21:58:54 -03:00
Nuckyz
c5541d297d
Optimize slowest patches 2024-05-23 21:58:06 -03:00
Vendicated
a120b35f4f
Bump to v1.8.6 2024-05-23 21:58:06 -03:00
Vendicated
9740d28530
discord why tf would u roll back to 10 days old build??? 2024-05-23 21:58:05 -03:00
Nuckyz
8e9434cdd5
Make reporter faster 2024-05-23 21:57:12 -03:00
Nuckyz
f5be78d101
Patching toString -> String 2024-05-23 20:02:41 -03:00
Nuckyz
bd95cc449f
Exit script if a chunk failed to load 2024-05-23 19:54:40 -03:00
Nuckyz
bdd4b0f143
Make eagerPatches an internal setting 2024-05-23 19:53:19 -03:00
Nuckyz
a60c8374ed
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-23 07:10:39 -03:00
Nuckyz
1013c34840
HORROR 2024-05-23 07:09:15 -03:00
Nuckyz
7b7b87316d
HORROR 2024-05-23 07:09:03 -03:00
Nuckyz
6567ff7435
any -> ModuleExports 2024-05-23 06:58:51 -03:00
Nuckyz
22a75c4589
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-23 06:51:07 -03:00
Nuckyz
67b5ecca51
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-23 06:42:53 -03:00
Nuckyz
cdbd9ad101
Merge branch 'dev' into immediate-finds 2024-05-23 06:42:07 -03:00
Nuckyz
1e96638219
oops! 2024-05-23 06:38:22 -03:00
Nuckyz
7371abbaec
lmao 2024-05-23 06:29:07 -03:00
Nuckyz
cfb493c593
make reporter use eagerPatches 2024-05-23 06:22:01 -03:00
Nuckyz
ac61a0377f
clean up 2024-05-23 06:09:47 -03:00
Nuckyz
bb3f629672
Merge branch 'dev' into modules-proxy-patches 2024-05-23 06:07:25 -03:00
Nuckyz
3ab68f9296
Option for eager patching 2024-05-23 06:07:13 -03:00
Nuckyz
01a4ac9c13
sometimes I'm stupid 2024-05-23 03:42:58 -03:00
Nuckyz
66e1db1fdb
more 2024-05-23 03:39:59 -03:00
Nuckyz
688449ed62
forgot this! 2024-05-23 03:38:06 -03:00
Nuckyz
5ca4e58fad
Clean up WebpackRequire typings 2024-05-23 03:36:53 -03:00
Nuckyz
deb0f7b9c6
Merge remote-tracking branch 'upstream/dev' into modules-proxy-patches 2024-05-23 03:12:46 -03:00
Nuckyz
40a1f48267
boops 2024-05-23 03:10:59 -03:00
Nuckyz
bc367b1d2a
and also a fix 2024-05-22 06:25:30 -03:00
Nuckyz
f6a7cdc430
more fix 2024-05-22 06:22:37 -03:00
Nuckyz
d5bcbf54f9
fix 2024-05-22 06:17:31 -03:00
Nuckyz
4b2734610f
Add WebpackRequire typings 2024-05-22 06:08:40 -03:00
Nuckyz
c4645f79c6
Make patchedBy a string set 2024-05-22 06:08:28 -03:00
Nuckyz
cf9bbfc78f
stop annoying me 2024-05-22 01:30:17 -03:00
Nuckyz
6cc40eb095
okay CodiumAI 2024-05-22 01:27:39 -03:00
Nuckyz
95acb147d1
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-22 01:11:45 -03:00
Nuckyz
21fea87551
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-22 01:11:26 -03:00
Nuckyz
2a2124c5a0
Merge branch 'dev' into modules-proxy-patches 2024-05-22 01:11:04 -03:00
Nuckyz
1a1e5c2e1d
Fix Flex component type 2024-05-22 01:07:58 -03:00
Nuckyz
c9d9d53fb1
Merge branch 'dev' into immediate-finds 2024-05-22 01:01:58 -03:00
Nuckyz
dc81d1c14c
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-19 23:22:58 -03:00
Nuckyz
b938bdf138
Clarify about sentry webpack 2024-05-19 23:22:48 -03:00
Nuckyz
e74aabb988
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-19 23:15:31 -03:00
Nuckyz
ab24ce08e3
Merge branch 'dev' into modules-proxy-patches 2024-05-19 23:14:05 -03:00
Nuckyz
c2435bb9dd
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-19 23:11:29 -03:00
Nuckyz
d678e68899
Merge branch 'immediate-finds' into immediate-finds-modules-proxy 2024-05-19 23:10:56 -03:00
Nuckyz
dbb6f4165b
Merge branch 'dev' into modules-proxy-patches 2024-05-19 23:10:11 -03:00
Nuckyz
9a1a7b374f
Merge branch 'dev' into immediate-finds 2024-05-19 23:09:43 -03:00
Nuckyz
ec373069b3
Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy 2024-05-19 23:01:08 -03:00
Nuckyz
329bc68bf5
Merge branch 'dev' into immediate-finds 2024-05-19 22:58:19 -03:00
Nuckyz
2a77941dff
Proxy modules object for patching 2024-05-19 22:49:58 -03:00
Nuckyz
d36c361b47
Merge branch 'dev' into immediate-finds 2024-05-19 04:23:51 -03:00
Nuckyz
b17963169f
Merge branch 'dev' into immediate-finds 2024-05-19 03:56:33 -03:00
Nuckyz
118361723c
Merge branch 'dev' into immediate-finds 2024-05-18 21:55:23 -03:00
Nuckyz
97e2e2c1c8
Merge branch 'dev' into immediate-finds 2024-05-18 21:46:13 -03:00
Nuckyz
dbee2d9ecc
Merge branch 'dev' into immediate-finds 2024-05-18 00:39:00 -03:00
Nuckyz
1283494b46
Merge branch 'dev' into immediate-finds 2024-05-17 23:05:04 -03:00
Nuckyz
e72c732d58
FriendsSince: Show in user profile modal 2024-05-17 23:03:44 -03:00
Nuckyz
d40dfc345f
Merge branch 'dev' into immediate-finds 2024-05-17 19:47:33 -03:00
vee
70f60193b0
explosion part 2 2024-05-17 23:10:21 +02:00
vee
9e60d4979d
explosion 2024-05-17 23:08:59 +02:00
vee
3562c8ae11
Merge branch 'dev' into immediate-finds 2024-05-17 23:08:07 +02:00
Nuckyz
093de43d54
Merge branch 'dev' into immediate-finds 2024-05-17 05:44:45 -03:00
Nuckyz
86ad3bd4fc
Merge branch 'dev' into immediate-finds 2024-05-17 05:22:05 -03:00
Nuckyz
8045d65e99
Merge branch 'dev' into immediate-finds 2024-05-17 05:09:35 -03:00
Nuckyz
63a1fe2c70
Merge branch 'dev' into immediate-finds 2024-05-16 02:39:41 -03:00
Nuckyz
55760bc42b
Merge branch 'dev' into immediate-finds 2024-05-16 01:10:41 -03:00
Nuckyz
983013446d
Merge branch 'dev' into immediate-finds 2024-05-16 00:23:30 -03:00
Nuckyz
569dace244
Merge branch 'dev' into immediate-finds 2024-05-15 23:40:23 -03:00
Nuckyz
8e5a2f6e59
Merge branch 'dev' into immediate-finds 2024-05-15 23:30:49 -03:00
Nuckyz
41a1732df2
MessageLatency: Fix wrong constant 2024-05-15 23:29:36 -03:00
Nuckyz
487af1c789
Merge branch 'dev' into immediate-finds 2024-05-15 23:25:48 -03:00
Nuckyz
5168f326a3
keep proper type 2024-05-15 23:07:35 -03:00
Nuckyz
4feaa40de7
Fix makeLazy not incrementing tries if factory errors 2024-05-15 23:06:21 -03:00
Nuckyz
7f5aaada88
Merge branch 'dev' into immediate-finds 2024-05-15 23:02:13 -03:00
Nuckyz
725103a77c
Merge branch 'dev' into immediate-finds 2024-05-15 00:39:02 -03:00
Nuckyz
a878ea0b39
Merge branch 'dev' into immediate-finds 2024-05-15 00:04:10 -03:00
Nuckyz
0cc89996c6
forgot this 2024-05-15 00:00:54 -03:00
Nuckyz
c72099fc39
feat: Allow finds to use regex (#2452) 2024-05-14 23:59:07 -03:00
Nuckyz
84c223d471
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-14 23:55:11 -03:00
Nuckyz
82f9e36e5a
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-14 23:53:41 -03:00
Nuckyz
7c8c2ff5b8
Merge branch 'dev' into immediate-finds 2024-05-14 22:54:51 -03:00
Ulysses Zhan
dc73b89b29
new plugin CtrlEnterSend (#1794)
Co-authored-by: vee <vendicated@riseup.net>
2024-05-14 20:52:55 -03:00
Ulysses Zhan
2596bf0990
new plugin NoServerEmoji ~ hides server emojis from autocomplete (#1787)
Co-authored-by: vee <vendicated@riseup.net>
2024-05-14 20:52:55 -03:00
Board
7169dfe61a
ThemeAttributes: add larger avatar url variables to avatars (#2449)
Co-authored-by: vee <vendicated@riseup.net>
2024-05-14 20:52:54 -03:00
Vendicated
5ba5eca1a1
fix Vencord Settings section being added multiple times 2024-05-14 20:52:54 -03:00
Vendicated
4209bfd3aa
bump to v1.8.4 2024-05-14 20:52:54 -03:00
Vendicated
c007fc7478
fix settings ui on canary 2024-05-14 20:52:54 -03:00
Nuckyz
903fa2cf11
Merge branch 'dev' into immediate-finds 2024-05-13 23:18:00 -03:00
Nuckyz
7d91dea822
Merge branch 'dev' into immediate-finds 2024-05-13 23:15:16 -03:00
Nuckyz
4fc4f1cb75
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-13 02:09:34 -03:00
Nuckyz
45d2cf49e0
Merge branch 'dev' into immediate-finds 2024-05-13 00:10:32 -03:00
Nuckyz
b798f31669
Merge branch 'dev' into immediate-finds 2024-05-12 21:33:34 -03:00
Nuckyz
7e1524362c
Merge branch 'dev' into immediate-finds 2024-05-12 20:46:39 -03:00
Nuckyz
e04dd85957
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-11 22:30:38 -03:00
Nuckyz
258e1efdce
Merge branch 'dev' into immediate-finds 2024-05-11 18:42:11 -03:00
Nuckyz
f6e484034c
more pog 2024-05-11 06:05:20 -03:00
Nuckyz
5676f45781
whatever 2024-05-11 05:56:26 -03:00
Nuckyz
e11d651e33
work 2024-05-11 05:51:18 -03:00
Nuckyz
09a6a9bf85
wtf? 2024-05-11 05:47:53 -03:00
Nuckyz
1b64419ef1
Make commons have proper ProxyInner typing 2024-05-11 05:44:52 -03:00
Nuckyz
5edff4a3c5
types 2024-05-11 05:19:12 -03:00
Nuckyz
b043d8abb7
Clarify more what the find methods return 2024-05-11 01:11:57 -03:00
Nuckyz
e15868d499
Merge branch 'dev' into immediate-finds 2024-05-09 03:17:08 -03:00
Nuckyz
a892a507be
Merge branch 'dev' into immediate-finds 2024-05-09 03:01:44 -03:00
Nuckyz
33a5f30ae4
ShowMeYourName: Fix regression caused by adding ErrorBoundary 2024-05-09 02:59:08 -03:00
Nuckyz
38b6c7fa6c
Merge branch 'dev' into immediate-finds 2024-05-09 00:46:24 -03:00
Nuckyz
bd88625d25
ErrorBoundary some more components 2024-05-09 00:44:04 -03:00
Nuckyz
5fca61f581
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-08 22:23:42 -03:00
Nuckyz
cc6cef02c1
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-08 22:17:04 -03:00
Vendicated
546c5105b2
im the dumbest dumdum 2024-05-09 03:12:11 +02:00
Nuckyz
f65749e2d4
Merge branch 'dev' into immediate-finds 2024-05-08 18:55:48 -03:00
Nuckyz
fb8f00137c
I'm dumb 2024-05-08 18:51:47 -03:00
Nuckyz
20b071aa2d
Merge branch 'dev' into immediate-finds 2024-05-08 18:47:22 -03:00
Nuckyz
b7c1b495af
CrashHandler: Increment timeout for trying to recover 2024-05-08 18:42:46 -03:00
Nuckyz
4d80c53dd0
Merge branch 'dev' into immediate-finds 2024-05-08 17:14:47 -03:00
Nuckyz
035e2add0b
Fix MoreUserTags freezing the client 2024-05-08 06:44:18 -03:00
Nuckyz
f70cc5205c
Reporter Bad Webpack Finds logs cleanups 2024-05-08 06:16:00 -03:00
Nuckyz
fa948e8639
Clean up all finds; Make common components NoopComponents by default
I went through every single find and made sure every component find is using the proper method
2024-05-08 04:48:48 -03:00
Nuckyz
4cc6789b5b
misc fixes 2024-05-08 00:25:34 -03:00
Nuckyz
4753efa33c
Merge branch 'dev' into immediate-finds 2024-05-08 00:19:49 -03:00
Nuckyz
283a4b23ba
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-07 22:29:33 -03:00
Nuckyz
3b7f1be9a2
i18nMessages: Keep language codes only 2024-05-07 22:23:44 -03:00
Nuckyz
c2e12e2827
why not 2024-05-07 22:10:05 -03:00
Nuckyz
8b6620ca2f
Update FluxEvents and Permissions 2024-05-07 22:06:45 -03:00
Nuckyz
f1e2d5572a
Update these license headers because I forgot in the other pr 2024-05-07 21:44:26 -03:00
Nuckyz
49fcfd74df
Merge branch 'dev' into immediate-finds 2024-05-07 21:40:02 -03:00
Nuckyz
511ec1b129
Add warn for using deprecated method 2024-05-07 21:33:05 -03:00
Nuckyz
94843a77ac
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-07 16:27:52 -03:00
Nuckyz
8873391496
Fix the lint :) 2024-05-07 06:33:07 -03:00
Nuckyz
b77b654df1
I should have done this in the dev branch but it's whatever now 2024-05-07 06:30:24 -03:00
Nuckyz
c65e1f88d2
Improve description of some finds 2024-05-07 06:28:43 -03:00
Nuckyz
9cd20e3cea
Merge branch 'dev' into immediate-finds 2024-05-07 06:23:36 -03:00
Nuckyz
f04bd8a7ad
useStateFromStores: Document 3rd param and fix JSDoc 2024-05-07 06:13:38 -03:00
Nuckyz
fa82939e62
Merge branch 'dev' into immediate-finds 2024-05-07 03:22:20 -03:00
Nuckyz
a1fefcf27a
Cant modify this array because we only clone 1 level deep 2024-05-07 03:07:03 -03:00
Nuckyz
65b6440024
Clean up 2024-05-07 03:01:45 -03:00
Nuckyz
6e0064c5fc
give a name to the proxy dummy function, for better logs in the console 2024-05-07 02:57:17 -03:00
Nuckyz
b047f9ce28
Merge branch 'dev' into immediate-finds 2024-05-07 02:49:24 -03:00
Nuckyz
d97596a16a
e 2024-05-07 02:38:12 -03:00
Nuckyz
5b6d0f42fd
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-07 01:14:45 -03:00
Nuckyz
4a89fadedd
Make Webpack finds not need to re-search 2024-05-07 01:13:46 -03:00
Nuckyz
886071af4d
Clean up Webpack ComponentWrapper 2024-05-06 23:22:36 -03:00
Nuckyz
12c9c324a1
Merge branch 'dev' into immediate-finds 2024-05-06 05:08:46 -03:00
Nuckyz
e311bd9f76
Merge branch 'dev' into immediate-finds 2024-05-05 17:56:21 -03:00
Nuckyz
707c23b188
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-05 05:15:35 -03:00
Sqaaakoi
49e78793c5
ImageLink: Fix embed showing in gifs (#2417) 2024-05-05 05:15:01 -03:00
Nuckyz
8d31330d3e
Fix wrongfully logging LazyComponent factory failed 2024-05-05 02:52:41 -03:00
Nuckyz
17397dbe08
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-05 02:49:58 -03:00
Fafa
b98544ed1f
ReviewDB: Fix context menus being added to folders (#2416) 2024-05-05 01:42:15 -03:00
Nuckyz
043675f3f8
Forgot to change this 2024-05-04 23:56:02 -03:00
Nuckyz
3b1cb02663
Merge branch 'dev' into immediate-finds 2024-05-04 23:18:31 -03:00
Nuckyz
bc68bc0312
ImplicitRelationships: Properly test find 2024-05-04 23:15:55 -03:00
Nuckyz
b3819228ed
Resolve PluginSettings circular deps better 2024-05-04 23:15:55 -03:00
Nuckyz
c23c65733b
Merge branch 'dev' into immediate-finds 2024-05-04 21:17:02 -03:00
Nuckyz
cfefdbc7a7
Improve proxyLazy 2024-05-04 20:56:32 -03:00
Nuckyz
70103e8111
Add better explanation for destructuring primitives 2024-05-04 17:49:20 -03:00
Nuckyz
240705652c
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-03 20:46:10 -03:00
Nuckyz
d42c9547ab
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-03 20:18:05 -03:00
Nuckyz
ac85b3508b
Comment proxyInner better 2024-05-03 20:11:52 -03:00
Nuckyz
9ece4dddd3
Better deprecation comments 2024-05-03 19:39:21 -03:00
Nuckyz
36f5d9acc6
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-03 19:23:48 -03:00
Nuckyz
d4956f3ec7
Merge branch 'dev' into immediate-finds 2024-05-03 19:09:49 -03:00
Nuckyz
8279c8d0ba
Merge branch 'dev' into immediate-finds 2024-05-03 18:47:56 -03:00
Nuckyz
74e3ba42e0
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-03 17:56:42 -03:00
Nuckyz
784ae0a02d
Merge remote-tracking branch 'upstream/dev' into immediate-finds 2024-05-03 17:35:20 -03:00
Nuckyz
901d803ba9
Make it less breaking: Add old methods back but mark as deprecated 2024-05-03 05:35:53 -03:00
Nuckyz
bdb693302a
Copy Array -> Use for loop with len 2024-05-03 05:19:35 -03:00
Nuckyz
f8a7d1d634
Merge branch 'dev' into immediate-finds 2024-05-03 04:55:19 -03:00
Nuckyz
770078f236
More things 2024-05-03 04:49:14 -03:00
Nuckyz
f1dd39885b
Clean up commons 2024-05-03 01:50:50 -03:00
Nuckyz
a29115ba78
Fix ReviewDB 2024-05-03 01:21:52 -03:00
Nuckyz
cd5e0aeec1
throw a rock at ben shapiro 2024-05-02 23:42:42 -03:00
Nuckyz
75fa0ff708
Immediate finds 2024-05-02 23:18:12 -03:00
384 changed files with 9506 additions and 10718 deletions

View file

@ -2,24 +2,30 @@ name: Blank Issue
description: Create a blank issue. ALWAYS FIRST USE OUR SUPPORT CHANNEL! ONLY USE THIS FORM IF YOU ARE A CONTRIBUTOR OR WERE TOLD TO DO SO IN THE SUPPORT CHANNEL.
body:
- type: markdown
attributes:
value: |
![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true)
- type: markdown
attributes:
value: |
# READ THIS BEFORE OPENING AN ISSUE
GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer.
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
- type: textarea
id: content
attributes:
label: Content
validations:
- type: textarea
id: content
attributes:
label: Content
validations:
required: true
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
options:
- label: I have read the requirements for opening an issue above
required: true
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
options:
- label: I have read the requirements for opening an issue above
required: true

View file

@ -4,63 +4,78 @@ labels: [bug]
title: "[Bug] <title>"
body:
- type: markdown
attributes:
value: |
![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true)
- type: markdown
attributes:
value: |
# READ THIS BEFORE OPENING AN ISSUE
GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer.
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
- type: input
id: discord
attributes:
label: Discord Account
description: Who on Discord is making this request? Not required but encouraged for easier follow-up
placeholder: username#0000
validations:
required: false
- type: textarea
id: bug-description
attributes:
label: What happens when the bug or crash occurs?
description: Where does this bug or crash occur, when does it occur, etc.
placeholder: The bug/crash happens sometimes when I do ..., causing this to not work/the app to crash. I think it happens because of ...
validations:
- type: textarea
id: bug-description
attributes:
label: What happens when the bug or crash occurs?
description: Where does this bug or crash occur, when does it occur, etc.
placeholder: The bug/crash happens sometimes when I do ..., causing this to not work/the app to crash. I think it happens because of ...
validations:
required: true
- type: textarea
id: expected-behaviour
attributes:
label: What is the expected behaviour?
description: Simply detail what the expected behaviour is.
placeholder: I expect Vencord/Discord to open the ... page instead of ..., it prevents me from doing ...
validations:
required: true
- type: textarea
id: steps-to-take
attributes:
label: How do you recreate this bug or crash?
description: Give us a list of steps in order to recreate the bug or crash.
placeholder: |
1. Do ...
2. Then ...
3. Do this ..., ... and then ...
4. Observe "the bug" or "the crash"
validations:
required: true
- type: textarea
id: crash-log
attributes:
label: Errors
description: Open the Developer Console with Ctrl/Cmd + Shift + i. Then look for any red errors (Ignore network errors like Failed to load resource) and paste them between the "```".
value: |
```
Replace this text with your crash-log.
```
validations:
required: false
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
description: We only accept reports for bugs that happen on Discord Stable. Canary and PTB are Development branches and may be unstable
options:
- label: I am using Discord Stable or tried on Stable and this bug happens there as well
required: true
- type: textarea
id: expected-behaviour
attributes:
label: What is the expected behaviour?
description: Simply detail what the expected behaviour is.
placeholder: I expect Vencord/Discord to open the ... page instead of ..., it prevents me from doing ...
validations:
- label: I have read the requirements for opening an issue above
required: true
- type: textarea
id: steps-to-take
attributes:
label: How do you recreate this bug or crash?
description: Give us a list of steps in order to recreate the bug or crash.
placeholder: |
1. Do ...
2. Then ...
3. Do this ..., ... and then ...
4. Observe "the bug" or "the crash"
validations:
required: true
- type: textarea
id: crash-log
attributes:
label: Errors
description: Open the Developer Console with Ctrl/Cmd + Shift + i. Then look for any red errors (Ignore network errors like Failed to load resource) and paste them between the "```".
value: |
```
Replace this text with your crash-log.
```
validations:
required: false
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
description: We only accept reports for bugs that happen on Discord Stable. Canary and PTB are Development branches and may be unstable
options:
- label: I am using Discord Stable or tried on Stable and this bug happens there as well
required: true
- label: I am a Vencord Developer
required: true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

View file

@ -42,7 +42,7 @@ jobs:
- name: Clean up obsolete files
run: |
rm -rf dist/*-unpacked dist/vendor Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map
rm -rf dist/*-unpacked dist/monaco Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map
- name: Get some values needed for the release
id: release_values

View file

@ -1,22 +1,9 @@
name: Test Patches
on:
workflow_dispatch:
inputs:
discord_branch:
type: choice
description: "Discord Branch to test patches on"
options:
- both
- stable
- canary
default: both
webhook_url:
type: string
description: "Webhook URL that the report will be posted to. This will be visible for everyone, so DO NOT pass sensitive webhooks like discord webhook. This is meant to be used by Venbot."
required: false
# schedule:
# # Every day at midnight
# - cron: 0 0 * * *
schedule:
# Every day at midnight
- cron: 0 0 * * *
jobs:
TestPlugins:
@ -53,43 +40,28 @@ jobs:
- name: Build Vencord Reporter Version
run: pnpm buildReporter
- name: Run Reporter
- name: Create Report
timeout-minutes: 10
run: |
export PATH="$PWD/node_modules/.bin:$PATH"
export CHROMIUM_BIN=${{ steps.setup-chrome.outputs.chrome-path }}
esbuild scripts/generateReport.ts > dist/report.mjs
stable_output_file=$(mktemp)
canary_output_file=$(mktemp)
pids=""
branch="${{ inputs.discord_branch }}"
if [[ "${{ github.event_name }}" = "schedule" ]]; then
branch="both"
fi
if [[ "$branch" = "both" || "$branch" = "stable" ]]; then
node dist/report.mjs > "$stable_output_file" &
pids+=" $!"
fi
if [[ "$branch" = "both" || "$branch" = "canary" ]]; then
USE_CANARY=true node dist/report.mjs > "$canary_output_file" &
pids+=" $!"
fi
exit_code=0
for pid in $pids; do
if ! wait "$pid"; then
exit_code=1
fi
done
cat "$stable_output_file" "$canary_output_file" >> $GITHUB_STEP_SUMMARY
exit $exit_code
node dist/report.mjs >> $GITHUB_STEP_SUMMARY
env:
WEBHOOK_URL: ${{ inputs.webhook_url || secrets.DISCORD_WEBHOOK }}
WEBHOOK_SECRET: ${{ secrets.WEBHOOK_SECRET }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
- name: Create Report (Canary)
timeout-minutes: 10
if: success() || failure() # even run if previous one failed
run: |
export PATH="$PWD/node_modules/.bin:$PATH"
export CHROMIUM_BIN=${{ steps.setup-chrome.outputs.chrome-path }}
export USE_CANARY=true
esbuild scripts/generateReport.ts > dist/report.mjs
node dist/report.mjs >> $GITHUB_STEP_SUMMARY
env:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}

3
.gitignore vendored
View file

@ -8,7 +8,6 @@ vencord_installer
.DS_Store
yarn.lock
bun.lock
package-lock.json
*.log
@ -19,5 +18,7 @@ lerna-debug.log*
.pnpm-debug.log*
*.tsbuildinfo
src/userplugins
ExtensionCache/
settings/

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "src/userplugins/vc-message-logger-enhanced"]
path = src/userplugins/vc-message-logger-enhanced
url = https://github.com/Syncxv/vc-message-logger-enhanced.git

View file

@ -31,7 +31,6 @@ Before starting your plugin:
- No FakeDeafen or FakeMute
- No StereoMic
- No plugins that simply hide or redesign ui elements. This can be done with CSS
- No plugins that interact with specific Discord bots (official Discord apps like Youtube WatchTogether are okay)
- No selfbots or API spam (animated status, message pruner, auto reply, nitro snipers, etc)
- No untrusted third party APIs. Popular services like Google or GitHub are fine, but absolutely no self hosted ones
- No plugins that require the user to enter their own API key

View file

@ -36,7 +36,7 @@
"web_accessible_resources": [
{
"resources": ["dist/*", "vendor/*"],
"resources": ["dist/*", "third-party/*"],
"matches": ["*://*.discord.com/*"]
}
],

View file

@ -15,7 +15,7 @@ declare global {
const getTheme: () => string;
}
const BASE = "/vendor/monaco/vs";
const BASE = "/dist/monaco/vs";
self.MonacoEnvironment = {
getWorkerUrl(_moduleId: unknown, label: string) {

View file

@ -24,12 +24,12 @@
<script>
const script = document.createElement("script");
script.src = new URL("/vendor/monaco/index.js", baseUrl);
script.src = new URL("/dist/monaco/index.js", baseUrl);
const style = document.createElement("link");
style.type = "text/css";
style.rel = "stylesheet";
style.href = new URL("/vendor/monaco/index.css", baseUrl);
style.href = new URL("/dist/monaco/index.css", baseUrl);
document.body.append(style, script);
</script>

View file

@ -5,7 +5,6 @@
// @author Vendicated (https://github.com/Vendicated)
// @namespace https://github.com/Vendicated/Vencord
// @supportURL https://github.com/Vendicated/Vencord
// @icon https://raw.githubusercontent.com/Vendicated/Vencord/refs/heads/main/browser/icon.png
// @license GPL-3.0
// @match *://*.discord.com/*
// @grant GM_xmlhttpRequest

View file

@ -4,9 +4,10 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
// @ts-check
import stylistic from "@stylistic/eslint-plugin";
import pathAlias from "eslint-plugin-path-alias";
import react from "eslint-plugin-react";
import header from "eslint-plugin-simple-header";
import simpleImportSort from "eslint-plugin-simple-import-sort";
import unusedImports from "eslint-plugin-unused-imports";
@ -14,22 +15,6 @@ import tseslint from "typescript-eslint";
export default tseslint.config(
{ ignores: ["dist", "browser", "packages/vencord-types"] },
{
files: ["src/**/*.{tsx,ts,mts,mjs,js,jsx}", "eslint.config.mjs"],
settings: {
react: {
version: "18"
}
},
...react.configs.flat.recommended,
rules: {
...react.configs.flat.recommended.rules,
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"react/display-name": "off",
"react/no-unescaped-entities": "off",
}
},
{
files: ["src/**/*.{tsx,ts,mts,mjs,js,jsx}", "eslint.config.mjs"],
plugins: {
@ -38,7 +23,7 @@ export default tseslint.config(
"@typescript-eslint": tseslint.plugin,
"simple-import-sort": simpleImportSort,
"unused-imports": unusedImports,
"path-alias": pathAlias
"path-alias": pathAlias,
},
settings: {
"import/resolver": {
@ -134,7 +119,7 @@ export default tseslint.config(
"no-unsafe-optional-chaining": "error",
"no-useless-backreference": "error",
"use-isnan": "error",
"prefer-const": ["error", { destructuring: "all" }],
"prefer-const": "error",
"prefer-spread": "error",
// Plugin Rules

View file

@ -1,7 +1,7 @@
{
"name": "vencord",
"private": "true",
"version": "1.11.5",
"version": "1.9.8",
"description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": {
@ -24,65 +24,63 @@
"dev": "pnpm watch",
"watchWeb": "pnpm buildWeb --watch",
"generatePluginJson": "tsx scripts/generatePluginList.ts",
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types --allowJs false",
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types",
"inject": "node scripts/runInstaller.mjs",
"uninject": "node scripts/runInstaller.mjs",
"lint": "eslint",
"lint-styles": "stylelint \"src/**/*.css\" --ignore-pattern src/userplugins",
"lint:fix": "pnpm lint --fix",
"test": "pnpm buildStandalone && pnpm testTsc && pnpm lint && pnpm lint-styles && pnpm generatePluginJson",
"test": "pnpm buildStandalone && pnpm lint && pnpm lint-styles && pnpm testTsc && pnpm generatePluginJson",
"testWeb": "pnpm lint && pnpm buildWeb && pnpm testTsc",
"testTsc": "tsc --noEmit"
},
"dependencies": {
"@intrnl/xxhash64": "^0.1.2",
"@sapphi-red/web-noise-suppressor": "0.3.5",
"@vap/core": "0.0.12",
"@vap/shiki": "0.10.5",
"fflate": "^0.8.2",
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
"monaco-editor": "^0.52.2",
"nanoid": "^5.0.9",
"monaco-editor": "^0.50.0",
"nanoid": "^5.0.7",
"virtual-merge": "^1.0.1"
},
"devDependencies": {
"@stylistic/eslint-plugin": "^4.0.0",
"@types/chrome": "^0.0.304",
"@types/diff": "^7.0.1",
"@types/lodash": "^4.17.14",
"@types/node": "^22.10.5",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@stylistic/eslint-plugin": "^2.6.1",
"@types/chrome": "^0.0.269",
"@types/diff": "^5.2.1",
"@types/lodash": "^4.17.7",
"@types/node": "^22.0.3",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/yazl": "^2.4.5",
"diff": "^7.0.0",
"diff": "^5.2.0",
"discord-types": "^1.3.26",
"esbuild": "^0.25.0",
"eslint": "^9.20.1",
"esbuild": "^0.15.18",
"eslint": "^9.8.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-path-alias": "2.1.0",
"eslint-plugin-react": "^7.37.3",
"eslint-plugin-simple-header": "^1.2.1",
"eslint-plugin-simple-header": "^1.1.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unused-imports": "^4.1.4",
"highlight.js": "11.11.1",
"eslint-plugin-unused-imports": "^4.0.1",
"highlight.js": "10.7.3",
"html-minifier-terser": "^7.2.0",
"moment": "^2.22.2",
"puppeteer-core": "^24.2.1",
"standalone-electron-types": "^34.2.0",
"stylelint": "^16.12.0",
"stylelint-config-standard": "^37.0.0",
"ts-patch": "^3.3.0",
"ts-pattern": "^5.6.0",
"tsx": "^4.19.2",
"type-fest": "^4.31.0",
"typescript": "^5.7.2",
"typescript-eslint": "^8.19.0",
"typescript-transform-paths": "^3.5.3",
"moment": "^2.30.1",
"puppeteer-core": "^22.15.0",
"standalone-electron-types": "^1.0.0",
"stylelint": "^16.8.1",
"stylelint-config-standard": "^36.0.1",
"ts-patch": "^3.2.1",
"tsx": "^4.16.5",
"type-fest": "^4.23.0",
"typescript": "^5.5.4",
"typescript-eslint": "^8.0.0",
"typescript-transform-paths": "^3.4.7",
"zip-local": "^0.3.5"
},
"packageManager": "pnpm@10.4.1",
"packageManager": "pnpm@9.1.0",
"pnpm": {
"patchedDependencies": {
"eslint@9.20.1": "patches/eslint@9.20.1.patch",
"eslint@9.8.0": "patches/eslint@9.8.0.patch",
"eslint-plugin-path-alias@2.1.0": "patches/eslint-plugin-path-alias@2.1.0.patch"
},
"peerDependencyRules": {
@ -95,14 +93,18 @@
"source-map-resolve": "*",
"resolve-url": "*",
"source-map-url": "*",
"urix": "*",
"q": "*"
"urix": "*"
}
},
"webExt": {
"artifactsDir": "./dist",
"build": {
"overwriteDest": true
},
"onlyBuiltDependencies": [
"esbuild"
]
"sourceDir": "./dist/firefox-unpacked"
},
"engines": {
"node": ">=18"
"node": ">=18",
"pnpm": ">=9"
}
}

View file

@ -1,7 +1,7 @@
{
"name": "@vencord/types",
"private": false,
"version": "1.11.5",
"version": "0.1.3",
"description": "",
"types": "index.d.ts",
"scripts": {
@ -13,16 +13,16 @@
"license": "GPL-3.0",
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"fs-extra": "^11.3.0",
"tsx": "^4.19.2"
"fs-extra": "^11.2.0",
"tsx": "^3.12.6"
},
"dependencies": {
"@types/lodash": "4.17.15",
"@types/node": "^22.13.4",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.1",
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.18",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.0.10",
"discord-types": "^1.3.26",
"standalone-electron-types": "^34.2.0",
"type-fest": "^4.35.0"
"standalone-electron-types": "^1.0.0",
"type-fest": "^3.5.3"
}
}

File diff suppressed because it is too large Load diff

View file

@ -17,41 +17,38 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// @ts-check
import esbuild from "esbuild";
import { readdir } from "fs/promises";
import { join } from "path";
import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, commonRendererPlugins, watch, buildOrWatchAll, stringifyValues } from "./common.mjs";
import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, commonRendererPlugins, watch } from "./common.mjs";
const defines = stringifyValues({
const defines = {
IS_STANDALONE,
IS_DEV,
IS_REPORTER,
IS_UPDATER_DISABLED,
IS_WEB: false,
IS_EXTENSION: false,
VERSION,
VERSION: JSON.stringify(VERSION),
BUILD_TIMESTAMP
});
};
if (defines.IS_STANDALONE === "false") {
if (defines.IS_STANDALONE === false)
// If this is a local build (not standalone), optimize
// for the specific platform we're on
defines["process.platform"] = JSON.stringify(process.platform);
}
/**
* @type {import("esbuild").BuildOptions}
* @type {esbuild.BuildOptions}
*/
const nodeCommonOpts = {
...commonOpts,
define: defines,
format: "cjs",
platform: "node",
target: ["esnext"],
// @ts-ignore this is never undefined
external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external]
external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external],
define: defines
};
const sourceMapFooter = s => watch ? "" : `//# sourceMappingURL=vencord://${s}.js.map`;
@ -105,27 +102,25 @@ const globNativesPlugin = {
}
};
/** @type {import("esbuild").BuildOptions[]} */
const buildConfigs = ([
await Promise.all([
// Discord Desktop main & renderer & preload
{
esbuild.build({
...nodeCommonOpts,
entryPoints: ["src/main/index.ts"],
outfile: "dist/patcher.js",
footer: { js: "//# sourceURL=VencordPatcher\n" + sourceMapFooter("patcher") },
sourcemap,
plugins: [
// @ts-ignore this is never undefined
...nodeCommonOpts.plugins,
globNativesPlugin
],
define: {
...defines,
IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: "false"
}
},
{
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
},
plugins: [
...nodeCommonOpts.plugins,
globNativesPlugin
]
}),
esbuild.build({
...commonOpts,
entryPoints: ["src/Vencord.ts"],
outfile: "dist/renderer.js",
@ -140,11 +135,11 @@ const buildConfigs = ([
],
define: {
...defines,
IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: "false"
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
}
},
{
}),
esbuild.build({
...nodeCommonOpts,
entryPoints: ["src/preload.ts"],
outfile: "dist/preload.js",
@ -152,29 +147,29 @@ const buildConfigs = ([
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: "true",
IS_VESKTOP: "false"
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
}
},
}),
// Vencord Desktop main & renderer & preload
{
esbuild.build({
...nodeCommonOpts,
entryPoints: ["src/main/index.ts"],
outfile: "dist/vencordDesktopMain.js",
footer: { js: "//# sourceURL=VencordDesktopMain\n" + sourceMapFooter("vencordDesktopMain") },
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
},
plugins: [
...nodeCommonOpts.plugins,
globNativesPlugin
],
define: {
...defines,
IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: "true"
}
},
{
]
}),
esbuild.build({
...commonOpts,
entryPoints: ["src/Vencord.ts"],
outfile: "dist/vencordDesktopRenderer.js",
@ -189,11 +184,11 @@ const buildConfigs = ([
],
define: {
...defines,
IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: "true"
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
}
},
{
}),
esbuild.build({
...nodeCommonOpts,
entryPoints: ["src/preload.ts"],
outfile: "dist/vencordDesktopPreload.js",
@ -201,10 +196,14 @@ const buildConfigs = ([
sourcemap,
define: {
...defines,
IS_DISCORD_DESKTOP: "false",
IS_VESKTOP: "true"
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
}
}
]);
await buildOrWatchAll(buildConfigs);
}),
]).catch(err => {
console.error("Build failed");
console.error(err.message);
// make ci fail
if (!commonOpts.watch)
process.exitCode = 1;
});

View file

@ -17,30 +17,29 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// @ts-check
import esbuild from "esbuild";
import { readFileSync } from "fs";
import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises";
import { join } from "path";
import Zip from "zip-local";
import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION, commonRendererPlugins, buildOrWatchAll, stringifyValues } from "./common.mjs";
import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION, commonRendererPlugins } from "./common.mjs";
/**
* @type {import("esbuild").BuildOptions}
* @type {esbuild.BuildOptions}
*/
const commonOptions = {
...commonOpts,
entryPoints: ["browser/Vencord.ts"],
format: "iife",
globalName: "Vencord",
format: "iife",
external: ["~plugins", "~git-hash", "/assets/*"],
target: ["esnext"],
plugins: [
globPlugins("web"),
...commonRendererPlugins
],
define: stringifyValues({
target: ["esnext"],
define: {
IS_WEB: true,
IS_EXTENSION: false,
IS_STANDALONE: true,
@ -49,9 +48,9 @@ const commonOptions = {
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: false,
IS_UPDATER_DISABLED: true,
VERSION,
VERSION: JSON.stringify(VERSION),
BUILD_TIMESTAMP
})
}
};
const MonacoWorkerEntryPoints = [
@ -59,59 +58,70 @@ const MonacoWorkerEntryPoints = [
"vs/editor/editor.worker.js"
];
/** @type {import("esbuild").BuildOptions[]} */
const buildConfigs = [
{
entryPoints: MonacoWorkerEntryPoints.map(entry => `node_modules/monaco-editor/esm/${entry}`),
bundle: true,
minify: true,
format: "iife",
outbase: "node_modules/monaco-editor/esm/",
outdir: "dist/vendor/monaco"
},
{
entryPoints: ["browser/monaco.ts"],
bundle: true,
minify: true,
format: "iife",
outfile: "dist/vendor/monaco/index.js",
loader: {
".ttf": "file"
}
},
{
...commonOptions,
outfile: "dist/browser.js",
footer: { js: "//# sourceURL=VencordWeb" }
},
{
...commonOptions,
outfile: "dist/extension.js",
define: {
...commonOptions.define,
IS_EXTENSION: "true"
},
footer: { js: "//# sourceURL=VencordWeb" }
},
{
...commonOptions,
inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])],
define: {
...commonOptions.define,
window: "unsafeWindow",
},
outfile: "dist/Vencord.user.js",
banner: {
js: readFileSync("browser/userscript.meta.js", "utf-8").replace("%version%", `${VERSION}.${new Date().getTime()}`)
},
footer: {
// UserScripts get wrapped in an iife, so define Vencord prop on window that returns our local
js: "Object.defineProperty(unsafeWindow,'Vencord',{get:()=>Vencord});"
}
}
const RnNoiseFiles = [
"dist/rnnoise.wasm",
"dist/rnnoise_simd.wasm",
"dist/rnnoise/workletProcessor.js",
"LICENSE"
];
await buildOrWatchAll(buildConfigs);
await Promise.all(
[
esbuild.build({
entryPoints: MonacoWorkerEntryPoints.map(entry => `node_modules/monaco-editor/esm/${entry}`),
bundle: true,
minify: true,
format: "iife",
outbase: "node_modules/monaco-editor/esm/",
outdir: "dist/monaco"
}),
esbuild.build({
entryPoints: ["browser/monaco.ts"],
bundle: true,
minify: true,
format: "iife",
outfile: "dist/monaco/index.js",
loader: {
".ttf": "file"
}
}),
esbuild.build({
...commonOptions,
outfile: "dist/browser.js",
footer: { js: "//# sourceURL=VencordWeb" }
}),
esbuild.build({
...commonOptions,
outfile: "dist/extension.js",
define: {
...commonOptions?.define,
IS_EXTENSION: true,
},
footer: { js: "//# sourceURL=VencordWeb" }
}),
esbuild.build({
...commonOptions,
inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])],
define: {
...(commonOptions?.define),
window: "unsafeWindow",
},
outfile: "dist/Vencord.user.js",
banner: {
js: readFileSync("browser/userscript.meta.js", "utf-8").replace("%version%", `${VERSION}.${new Date().getTime()}`)
},
footer: {
// UserScripts get wrapped in an iife, so define Vencord prop on window that returns our local
js: "Object.defineProperty(unsafeWindow,'Vencord',{get:()=>Vencord});"
}
})
]
).catch(err => {
console.error("Build failed");
console.error(err.message);
if (!commonOpts.watch)
process.exit(1);
});;
/**
* @type {(dir: string) => Promise<string[]>}
@ -145,13 +155,16 @@ async function buildExtension(target, files) {
const entries = {
"dist/Vencord.js": await readFile("dist/extension.js"),
"dist/Vencord.css": await readFile("dist/extension.css"),
...await loadDir("dist/vendor/monaco", "dist/"),
...await loadDir("dist/monaco"),
...Object.fromEntries(await Promise.all(RnNoiseFiles.map(async file =>
[`third-party/rnnoise/${file.replace(/^dist\//, "")}`, await readFile(`node_modules/@sapphi-red/web-noise-suppressor/${file}`)]
))),
...Object.fromEntries(await Promise.all(files.map(async f => {
let content = await readFile(join("browser", f));
if (f.startsWith("manifest")) {
const json = JSON.parse(content.toString("utf-8"));
json.version = VERSION;
content = Buffer.from(new TextEncoder().encode(JSON.stringify(json)));
content = new TextEncoder().encode(JSON.stringify(json));
}
return [
@ -197,6 +210,7 @@ if (!process.argv.includes("--skip-extension")) {
Zip.sync.zip("dist/firefox-unpacked").compress().save("dist/extension-firefox.zip");
console.info("Packed Firefox Extension written to dist/extension-firefox.zip");
} else {
await appendCssRuntime;
}

View file

@ -16,13 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// @ts-check
import "../suppressExperimentalWarnings.js";
import "../checkNodeVersion.js";
import { exec, execSync } from "child_process";
import esbuild, { build, context } from "esbuild";
import esbuild from "esbuild";
import { constants as FsConstants, readFileSync } from "fs";
import { access, readdir, readFile } from "fs/promises";
import { minify as minifyHtml } from "html-minifier-terser";
@ -33,7 +31,7 @@ import { getPluginTarget } from "../utils.mjs";
import { builtinModules } from "module";
/** @type {import("../../package.json")} */
const PackageJSON = JSON.parse(readFileSync("package.json", "utf-8"));
const PackageJSON = JSON.parse(readFileSync("package.json"));
export const VERSION = PackageJSON.version;
// https://reproducible-builds.org/docs/source-date-epoch/
@ -56,34 +54,6 @@ export const banner = {
`.trim()
};
/**
* JSON.stringify all values in an object
* @type {(obj: Record<string, any>) => Record<string, string>}
*/
export function stringifyValues(obj) {
for (const key in obj) {
obj[key] = JSON.stringify(obj[key]);
}
return obj;
}
/**
* @param {import("esbuild").BuildOptions[]} buildConfigs
*/
export async function buildOrWatchAll(buildConfigs) {
if (watch) {
await Promise.all(buildConfigs.map(cfg =>
context(cfg).then(ctx => ctx.watch())
));
} else {
await Promise.all(buildConfigs.map(cfg => build(cfg)))
.catch(error => {
console.error(error.message);
process.exit(1); // exit immediately to skip the rest of the builds
});
}
}
const PluginDefinitionNameMatcher = /definePlugin\(\{\s*(["'])?name\1:\s*(["'`])(.+?)\2/;
/**
* @param {string} base
@ -341,16 +311,18 @@ export const banImportPlugin = (filter, message) => ({
export const commonOpts = {
logLevel: "info",
bundle: true,
watch,
minify: !watch && !IS_REPORTER,
sourcemap: watch ? "inline" : "external",
sourcemap: watch ? "inline" : "",
legalComments: "linked",
banner,
plugins: [fileUrlPlugin, gitHashPlugin, gitRemotePlugin, stylePlugin],
external: ["~plugins", "~git-hash", "~git-remote", "/assets/*"],
inject: ["./scripts/build/inject/react.mjs"],
jsx: "transform",
jsxFactory: "VencordCreateElement",
jsxFragment: "VencordFragment"
jsxFragment: "VencordFragment",
// Work around https://github.com/evanw/esbuild/issues/2460
tsconfig: "./scripts/build/tsconfig.esbuild.json"
};
const escapedBuiltinModules = builtinModules
@ -362,7 +334,5 @@ export const commonRendererPlugins = [
banImportPlugin(builtinModuleRegex, "Cannot import node inbuilt modules in browser code. You need to use a native.ts file"),
banImportPlugin(/^react$/, "Cannot import from react. React and hooks should be imported from @webpack/common"),
banImportPlugin(/^electron(\/.*)?$/, "Cannot import electron in browser code. You need to use a native.ts file"),
banImportPlugin(/^ts-pattern$/, "Cannot import from ts-pattern. match and P should be imported from @webpack/common"),
// @ts-ignore this is never undefined
...commonOpts.plugins
];

View file

@ -0,0 +1,7 @@
// Work around https://github.com/evanw/esbuild/issues/2460
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}

View file

@ -16,32 +16,28 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* eslint-disable no-fallthrough */
// eslint-disable-next-line spaced-comment
/// <reference types="../src/globals" />
// eslint-disable-next-line spaced-comment
/// <reference types="../src/modules" />
import { createHmac } from "crypto";
import { readFileSync } from "fs";
import pup, { JSHandle } from "puppeteer-core";
const logStderr = (...data: any[]) => console.error(`${CANARY ? "CANARY" : "STABLE"} ---`, ...data);
for (const variable of ["CHROMIUM_BIN"]) {
if (!process.env[variable]) {
logStderr(`Missing environment variable ${variable}`);
console.error(`Missing environment variable ${variable}`);
process.exit(1);
}
}
const CANARY = process.env.USE_CANARY === "true";
let metaData = {
buildNumber: "Unknown Build Number",
buildHash: "Unknown Build Hash"
};
const browser = await pup.launch({
headless: true,
executablePath: process.env.CHROMIUM_BIN,
args: ["--no-sandbox"]
executablePath: process.env.CHROMIUM_BIN
});
const page = await browser.newPage();
@ -54,17 +50,14 @@ async function maybeGetError(handle: JSHandle): Promise<string | undefined> {
.catch(() => undefined);
}
interface PatchInfo {
plugin: string;
type: string;
id: string;
match: string;
error?: string;
};
const report = {
badPatches: [] as PatchInfo[],
slowPatches: [] as PatchInfo[],
badPatches: [] as {
plugin: string;
type: string;
id: string;
match: string;
error?: string;
}[],
badStarts: [] as {
plugin: string;
error: string;
@ -134,88 +127,56 @@ async function printReport() {
console.log();
if (process.env.WEBHOOK_URL) {
const patchesToEmbed = (title: string, patches: PatchInfo[], color: number) => ({
title,
color,
description: patches.map(p => {
const lines = [
`**__${p.plugin} (${p.type}):__**`,
`ID: \`${p.id}\``,
`Match: ${toCodeBlock(p.match, "Match: ".length, true)}`
];
if (p.error) lines.push(`Error: ${toCodeBlock(p.error, "Error: ".length, true)}`);
return lines.join("\n");
}).join("\n\n"),
});
const embeds = [
{
author: {
name: `Discord ${CANARY ? "Canary" : "Stable"} (${metaData.buildNumber})`,
url: `https://nelly.tools/builds/app/${metaData.buildHash}`,
icon_url: CANARY ? "https://cdn.discordapp.com/emojis/1252721945699549327.png?size=128" : "https://cdn.discordapp.com/emojis/1252721943463985272.png?size=128"
},
color: CANARY ? 0xfbb642 : 0x5865f2
},
report.badPatches.length > 0 && patchesToEmbed("Bad Patches", report.badPatches, 0xff0000),
report.slowPatches.length > 0 && patchesToEmbed("Slow Patches", report.slowPatches, 0xf0b232),
report.badWebpackFinds.length > 0 && {
title: "Bad Webpack Finds",
description: report.badWebpackFinds.map(f => toCodeBlock(f, 0, true)).join("\n") || "None",
color: 0xff0000
},
report.badStarts.length > 0 && {
title: "Bad Starts",
description: report.badStarts.map(p => {
const lines = [
`**__${p.plugin}:__**`,
toCodeBlock(p.error, 0, true)
];
return lines.join("\n");
}
).join("\n\n") || "None",
color: 0xff0000
},
report.otherErrors.length > 0 && {
title: "Discord Errors",
description: report.otherErrors.length ? toCodeBlock(report.otherErrors.join("\n"), 0, true) : "None",
color: 0xff0000
}
].filter(Boolean);
if (embeds.length === 1) {
embeds.push({
title: "No issues found",
description: "Seems like everything is working fine (for now) <:shipit:1330992641466433556>",
color: 0x00ff00
});
}
const body = JSON.stringify({
username: "Vencord Reporter" + (CANARY ? " (Canary)" : ""),
embeds
});
const headers = {
"Content-Type": "application/json"
};
// functions similar to https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries
// used by venbot to ensure webhook invocations are genuine (since we will pass the webhook url as a workflow input which is publicly visible)
// generate a secret with something like `openssl rand -hex 128`
if (process.env.WEBHOOK_SECRET) {
headers["X-Signature"] = "sha256=" + createHmac("sha256", process.env.WEBHOOK_SECRET).update(body).digest("hex");
}
await fetch(process.env.WEBHOOK_URL, {
if (process.env.DISCORD_WEBHOOK) {
await fetch(process.env.DISCORD_WEBHOOK, {
method: "POST",
headers,
body
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
description: "Here's the latest Vencord Report!",
username: "Vencord Reporter" + (CANARY ? " (Canary)" : ""),
embeds: [
{
title: "Bad Patches",
description: report.badPatches.map(p => {
const lines = [
`**__${p.plugin} (${p.type}):__**`,
`ID: \`${p.id}\``,
`Match: ${toCodeBlock(p.match, "Match: ".length, true)}`
];
if (p.error) lines.push(`Error: ${toCodeBlock(p.error, "Error: ".length, true)}`);
return lines.join("\n");
}).join("\n\n") || "None",
color: report.badPatches.length ? 0xff0000 : 0x00ff00
},
{
title: "Bad Webpack Finds",
description: report.badWebpackFinds.map(f => toCodeBlock(f, 0, true)).join("\n") || "None",
color: report.badWebpackFinds.length ? 0xff0000 : 0x00ff00
},
{
title: "Bad Starts",
description: report.badStarts.map(p => {
const lines = [
`**__${p.plugin}:__**`,
toCodeBlock(p.error, 0, true)
];
return lines.join("\n");
}
).join("\n\n") || "None",
color: report.badStarts.length ? 0xff0000 : 0x00ff00
},
{
title: "Discord Errors",
description: report.otherErrors.length ? toCodeBlock(report.otherErrors.join("\n"), 0, true) : "None",
color: report.otherErrors.length ? 0xff0000 : 0x00ff00
}
]
})
}).then(res => {
if (!res.ok) logStderr(`Webhook failed with status ${res.status}`);
else logStderr("Posted to Webhook successfully");
if (!res.ok) console.error(`Webhook failed with status ${res.status}`);
else console.error("Posted to Discord Webhook successfully");
});
}
}
@ -224,13 +185,10 @@ page.on("console", async e => {
const level = e.type();
const rawArgs = e.args();
async function getText(skipFirst = true) {
let args = e.args();
if (skipFirst) args = args.slice(1);
async function getText() {
try {
return await Promise.all(
args.map(async a => {
e.args().map(async a => {
return await maybeGetError(a) || await a.jsonValue();
})
).then(a => a.join(" ").trim());
@ -243,12 +201,6 @@ page.on("console", async e => {
const isVencord = firstArg === "[Vencord]";
const isDebug = firstArg === "[PUP_DEBUG]";
const isReporterMeta = firstArg === "[REPORTER_META]";
if (isReporterMeta) {
metaData = await rawArgs[1].jsonValue() as any;
return;
}
outer:
if (isVencord) {
@ -262,21 +214,18 @@ page.on("console", async e => {
switch (tag) {
case "WebpackInterceptor:":
const patchFailMatch = message.match(/Patch by (.+?) (had no effect|errored|found no module) \(Module id is (.+?)\): (.+)/);
const patchSlowMatch = message.match(/Patch by (.+?) (took [\d.]+?ms) \(Module id is (.+?)\): (.+)/);
const match = patchFailMatch ?? patchSlowMatch;
if (!match) break;
const patchFailMatch = message.match(/Patch by (.+?) (had no effect|errored|found no module|took [\d.]+?ms) \(Module id is (.+?)\): (.+)/)!;
if (!patchFailMatch) break;
logStderr(await getText());
console.error(await getText());
process.exitCode = 1;
const [, plugin, type, id, regex] = match;
const list = patchFailMatch ? report.badPatches : report.slowPatches;
list.push({
const [, plugin, type, id, regex] = patchFailMatch;
report.badPatches.push({
plugin,
type,
id,
match: regex,
match: regex.replace(/\[A-Za-z_\$\]\[\\w\$\]\*/g, "\\i"),
error: await maybeGetError(e.args()[3])
});
@ -285,7 +234,7 @@ page.on("console", async e => {
const failedToStartMatch = message.match(/Failed to start (.+)/);
if (!failedToStartMatch) break;
logStderr(await getText());
console.error(await getText());
process.exitCode = 1;
const [, name] = failedToStartMatch;
@ -296,7 +245,7 @@ page.on("console", async e => {
break;
case "LazyChunkLoader:":
logStderr(await getText());
console.error(await getText());
switch (message) {
case "A fatal error occurred:":
@ -305,7 +254,7 @@ page.on("console", async e => {
break;
case "Reporter:":
logStderr(await getText());
console.error(await getText());
switch (message) {
case "A fatal error occurred:":
@ -323,27 +272,27 @@ page.on("console", async e => {
}
if (isDebug) {
logStderr(await getText());
console.error(await getText());
} else if (level === "error") {
const text = await getText(false);
const text = await getText();
if (text.length && !text.startsWith("Failed to load resource: the server responded with a status of") && !text.includes("Webpack")) {
if (IGNORED_DISCORD_ERRORS.some(regex => text.match(regex))) {
report.ignoredErrors.push(text);
} else {
logStderr("[Unexpected Error]", text);
console.error("[Unexpected Error]", text);
report.otherErrors.push(text);
}
}
}
});
page.on("error", e => logStderr("[Error]", e.message));
page.on("error", e => console.error("[Error]", e.message));
page.on("pageerror", e => {
if (e.message.includes("Sentry successfully disabled")) return;
if (!e.message.startsWith("Object") && !e.message.includes("Cannot find module") && !/^.{1,2}$/.test(e.message)) {
logStderr("[Page Error]", e.message);
console.error("[Page Error]", e.message);
report.otherErrors.push(e.message);
} else {
report.ignoredErrors.push(e.message);

View file

@ -1,20 +0,0 @@
@echo off
:: Check if 'upstream' remote exists
git remote | findstr upstream >nul
if errorlevel 1 (
:: Add upstream remote
git remote add upstream https://github.com/Vendicated/Vencord.git
echo Added upstream remote
)
:: Disable push to upstream by setting push URL to 'no_push'
git remote set-url --push upstream no_push
echo Disabled push to upstream remote
:: Add alias for sync: fetch, merge, and push to origin
git config alias.sync "!git fetch upstream && git merge upstream/main && git push origin main"
echo Configured sync alias
echo Setup completed!

View file

@ -1,18 +0,0 @@
#!/bin/bash
# Add upstream remote if it doesn't exist
if ! git remote | grep -q 'upstream'; then
git remote add upstream https://github.com/Vendicated/Vencord.git
echo "Added upstream remote"
fi
# Disable push to upstream by removing its push URL
git remote set-url --push upstream no_push
echo "Disabled push to upstream remote"
# Add alias for sync: fetch, merge, and push to origin
git config alias.sync '!git fetch upstream && git merge upstream/main && git push origin main'
echo "Configured sync alias"
echo "Setup completed!"

View file

@ -27,7 +27,6 @@ export * as WebpackPatcher from "./webpack/patchWebpack";
export { PlainSettings, Settings };
import "./utils/quickCss";
import "./webpack/patchWebpack";
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
import { StartAt } from "@utils/types";
@ -40,7 +39,7 @@ import { localStorage } from "./utils/localStorage";
import { relaunch } from "./utils/native";
import { getCloudSettings, putCloudSettings } from "./utils/settingsSync";
import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
import { onceReady } from "./webpack";
import { onceDiscordLoaded } from "./webpack";
import { SettingsRouter } from "./webpack/common";
if (IS_REPORTER) {
@ -87,7 +86,7 @@ async function syncSettings() {
}
async function init() {
await onceReady;
await onceDiscordLoaded;
startAllPlugins(StartAt.WebpackReady);
syncSettings();
@ -126,7 +125,7 @@ async function init() {
const pendingPatches = patches.filter(p => !p.all && p.predicate?.() !== false);
if (pendingPatches.length)
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",
"that all plugins are working as intended.",
"You are seeing this warning because this is a Development build of Vencord.",

View file

@ -4,11 +4,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import type { Settings } from "@api/Settings";
import { PluginIpcMappings } from "@main/ipcPlugins";
import type { UserThemeHeader } from "@main/themes";
import { IpcEvents } from "@shared/IpcEvents";
import { IpcRes } from "@utils/types";
import type { Settings } from "api/Settings";
import { ipcRenderer } from "electron";
function invoke<T = any>(event: IpcEvents, ...args: any[]) {

View file

@ -57,7 +57,7 @@ const Badges = new Set<ProfileBadge>();
* Register a new badge with the Badges API
* @param badge The badge to register
*/
export function addProfileBadge(badge: ProfileBadge) {
export function addBadge(badge: ProfileBadge) {
badge.component &&= ErrorBoundary.wrap(badge.component, { noop: true });
Badges.add(badge);
}
@ -66,7 +66,7 @@ export function addProfileBadge(badge: ProfileBadge) {
* Unregister a badge from the Badges API
* @param badge The badge to remove
*/
export function removeProfileBadge(badge: ProfileBadge) {
export function removeBadge(badge: ProfileBadge) {
return Badges.delete(badge);
}
@ -100,3 +100,20 @@ export interface BadgeUserArgs {
userId: string;
guildId: string;
}
interface ConnectedAccount {
type: string;
id: string;
name: string;
verified: boolean;
}
interface Profile {
connectedAccounts: ConnectedAccount[];
premiumType: number;
premiumSince: string;
premiumGuildSince?: any;
lastFetched: number;
profileFetchFailed: boolean;
application?: any;
}

View file

@ -8,13 +8,12 @@ import "./ChatButton.css";
import ErrorBoundary from "@components/ErrorBoundary";
import { Logger } from "@utils/Logger";
import { waitFor } from "@webpack";
import { Button, ButtonWrapperClasses, Tooltip } from "@webpack/common";
import { findByProps } from "@webpack";
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
import { Channel } from "discord-types/general";
import { HTMLProps, JSX, MouseEventHandler, ReactNode } from "react";
import { HTMLProps, MouseEventHandler, ReactNode } from "react";
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;
waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
const ChannelTextAreaClasses = findByProps<Record<"button" | "buttonContainer", string>>("buttonContainer", "channelTextArea");
export interface ChatBarProps {
channel: Channel;
@ -74,9 +73,9 @@ export interface ChatBarProps {
};
}
export type ChatBarButtonFactory = (props: ChatBarProps & { isMainChat: boolean; }) => JSX.Element | null;
export type ChatBarButton = (props: ChatBarProps & { isMainChat: boolean; }) => JSX.Element | null;
const buttonFactories = new Map<string, ChatBarButtonFactory>();
const buttonFactories = new Map<string, ChatBarButton>();
const logger = new Logger("ChatButtons");
export function _injectButtons(buttons: ReactNode[], props: ChatBarProps) {
@ -91,7 +90,7 @@ export function _injectButtons(buttons: ReactNode[], props: ChatBarProps) {
}
}
export const addChatBarButton = (id: string, button: ChatBarButtonFactory) => buttonFactories.set(id, button);
export const addChatBarButton = (id: string, button: ChatBarButton) => buttonFactories.set(id, button);
export const removeChatBarButton = (id: string) => buttonFactories.delete(id);
export interface ChatBarButtonProps {
@ -99,8 +98,7 @@ export interface ChatBarButtonProps {
tooltip: string;
onClick: MouseEventHandler<HTMLButtonElement>;
onContextMenu?: MouseEventHandler<HTMLButtonElement>;
onAuxClick?: MouseEventHandler<HTMLButtonElement>;
buttonProps?: Omit<HTMLProps<HTMLButtonElement>, "size" | "onClick" | "onContextMenu" | "onAuxClick">;
buttonProps?: Omit<HTMLProps<HTMLButtonElement>, "size" | "onClick" | "onContextMenu">;
}
export const ChatBarButton = ErrorBoundary.wrap((props: ChatBarButtonProps) => {
return (
@ -110,13 +108,12 @@ export const ChatBarButton = ErrorBoundary.wrap((props: ChatBarButtonProps) => {
<Button
aria-label={props.tooltip}
size=""
look={Button.Looks.BLANK}
look={ButtonLooks.BLANK}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
innerClassName={`${ButtonWrapperClasses.button} ${ChannelTextAreaClasses?.button}`}
onClick={props.onClick}
onContextMenu={props.onContextMenu}
onAuxClick={props.onAuxClick}
{...props.buttonProps}
>
<div className={ButtonWrapperClasses.buttonWrapper}>

View file

@ -17,14 +17,14 @@
*/
import { mergeDefaults } from "@utils/mergeDefaults";
import { findByCodeLazy } from "@webpack";
import { findByCode } from "@webpack";
import { MessageActions, SnowflakeUtils } from "@webpack/common";
import { Message } from "discord-types/general";
import type { PartialDeep } from "type-fest";
import { Argument } from "./types";
const createBotMessage = findByCodeLazy('username:"Clyde"');
const createBotMessage = findByCode('username:"Clyde"');
export function generateId() {
return `-${SnowflakeUtils.fromTimestamp(Date.now())}`;
@ -54,5 +54,5 @@ export function sendBotMessage(channelId: string, message: PartialDeep<Message>)
export function findOption<T>(args: Argument[], name: string): T & {} | undefined;
export function findOption<T>(args: Argument[], name: string, fallbackValue: T): T & {};
export function findOption(args: Argument[], name: string, fallbackValue?: any) {
return (args.find(a => a.name === name)?.value ?? fallbackValue) as any;
return (args.find(a => a.name === name)?.value || fallbackValue) as any;
}

View file

@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Logger } from "@utils/Logger";
import { makeCodeblock } from "@utils/text";
import { sendBotMessage } from "./commandHelpers";
@ -47,10 +46,10 @@ export let RequiredMessageOption: Option = ReqPlaceholder;
export const _init = function (cmds: Command[]) {
try {
BUILT_IN = cmds;
OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0];
RequiredMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "me")!.options![0];
OptionalMessageOption = cmds.find(c => c.name === "shrug")!.options![0];
RequiredMessageOption = cmds.find(c => c.name === "me")!.options![0];
} catch (e) {
new Logger("CommandsAPI").error("Failed to load CommandsApi", e, " - cmds is", cmds);
console.error("Failed to load CommandsApi");
}
return cmds;
} as never;
@ -110,7 +109,6 @@ function registerSubCommands(cmd: Command, plugin: string) {
const subCmd = {
...cmd,
...o,
options: o.options !== undefined ? o.options : undefined,
type: ApplicationCommandType.CHAT_INPUT,
name: `${cmd.name} ${o.name}`,
id: `${o.name}-${cmd.id}`,
@ -140,8 +138,6 @@ export function registerCommand<C extends Command>(command: C, plugin: string) {
throw new Error(`Command '${command.name}' already exists.`);
command.isVencordCommand = true;
command.untranslatedName ??= command.name;
command.untranslatedDescription ??= command.description;
command.id ??= `-${BUILT_IN.length + 1}`;
command.applicationId ??= "-1"; // BUILT_IN;
command.type ??= ApplicationCommandType.CHAT_INPUT;

View file

@ -93,10 +93,8 @@ export interface Command {
isVencordCommand?: boolean;
name: string;
untranslatedName?: string;
displayName?: string;
description: string;
untranslatedDescription?: string;
displayDescription?: string;
options?: Option[];

View file

@ -24,13 +24,13 @@ import type { ReactElement } from "react";
* @param children The rendered context menu elements
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
*/
export type NavContextMenuPatchCallback = (children: Array<ReactElement<any> | null>, ...args: Array<any>) => void;
export type NavContextMenuPatchCallback = (children: Array<ReactElement | null>, ...args: Array<any>) => void;
/**
* @param navId The navId of the context menu being patched
* @param children The rendered context menu elements
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
*/
export type GlobalContextMenuPatchCallback = (navId: string, children: Array<ReactElement<any> | null>, ...args: Array<any>) => void;
export type GlobalContextMenuPatchCallback = (navId: string, children: Array<ReactElement | null>, ...args: Array<any>) => void;
const ContextMenuLogger = new Logger("ContextMenu");
@ -70,7 +70,7 @@ export function addGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallback)
* @returns Whether the patch was successfully removed from the context menu(s)
*/
export function removeContextMenuPatch<T extends string | Array<string>>(navId: T, patch: NavContextMenuPatchCallback): T extends string ? boolean : Array<boolean> {
const navIds: string[] = Array.isArray(navId) ? navId : [navId];
const navIds = Array.isArray(navId) ? navId : [navId as string];
const results = navIds.map(id => navPatches.get(id)?.delete(patch) ?? false);
@ -90,20 +90,19 @@ export function removeGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallba
* A helper function for finding the children array of a group nested inside a context menu based on the id(s) of its children
* @param id The id of the child. If an array is specified, all ids will be tried
* @param children The context menu children
* @param matchSubstring Whether to check if the id is a substring of the child id
*/
export function findGroupChildrenByChildId(id: string | string[], children: Array<ReactElement<any> | null | undefined>, matchSubstring = false): Array<ReactElement<any> | null | undefined> | null {
export function findGroupChildrenByChildId(id: string | string[], children: Array<ReactElement | null>): Array<ReactElement | null> | null {
for (const child of children) {
if (child == null) continue;
if (Array.isArray(child)) {
const found = findGroupChildrenByChildId(id, child, matchSubstring);
const found = findGroupChildrenByChildId(id, child);
if (found !== null) return found;
}
if (
(Array.isArray(id) && id.some(id => matchSubstring ? child.props?.id?.includes(id) : child.props?.id === id))
|| (matchSubstring ? child.props?.id?.includes(id) : child.props?.id === id)
(Array.isArray(id) && id.some(id => child.props?.id === id))
|| child.props?.id === id
) return children;
let nextChildren = child.props?.children;
@ -113,7 +112,7 @@ export function findGroupChildrenByChildId(id: string | string[], children: Arra
child.props.children = nextChildren;
}
const found = findGroupChildrenByChildId(id, nextChildren, matchSubstring);
const found = findGroupChildrenByChildId(id, nextChildren);
if (found !== null) return found;
}
}
@ -122,9 +121,9 @@ export function findGroupChildrenByChildId(id: string | string[], children: Arra
}
interface ContextMenuProps {
contextMenuAPIArguments?: Array<any>;
contextMenuApiArguments?: Array<any>;
navId: string;
children: Array<ReactElement<any> | null>;
children: Array<ReactElement | null>;
"aria-label": string;
onSelect: (() => void) | undefined;
onClose: (callback: (...args: Array<any>) => any) => void;
@ -136,7 +135,7 @@ export function _usePatchContextMenu(props: ContextMenuProps) {
children: cloneMenuChildren(props.children),
};
props.contextMenuAPIArguments ??= [];
props.contextMenuApiArguments ??= [];
const contextMenuPatches = navPatches.get(props.navId);
if (!Array.isArray(props.children)) props.children = [props.children];
@ -144,7 +143,7 @@ export function _usePatchContextMenu(props: ContextMenuProps) {
if (contextMenuPatches) {
for (const patch of contextMenuPatches) {
try {
patch(props.children, ...props.contextMenuAPIArguments);
patch(props.children, ...props.contextMenuApiArguments);
} catch (err) {
ContextMenuLogger.error(`Patch for ${props.navId} errored,`, err);
}
@ -153,7 +152,7 @@ export function _usePatchContextMenu(props: ContextMenuProps) {
for (const patch of globalPatches) {
try {
patch(props.navId, props.children, ...props.contextMenuAPIArguments);
patch(props.navId, props.children, ...props.contextMenuApiArguments);
} catch (err) {
ContextMenuLogger.error("Global patch errored,", err);
}
@ -162,7 +161,7 @@ export function _usePatchContextMenu(props: ContextMenuProps) {
return props;
}
function cloneMenuChildren(obj: ReactElement<any> | Array<ReactElement<any> | null> | null) {
function cloneMenuChildren(obj: ReactElement | Array<ReactElement | null> | null) {
if (Array.isArray(obj)) {
return obj.map(cloneMenuChildren);
}

View file

@ -16,9 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { Channel, User } from "discord-types/general/index.js";
import { JSX } from "react";
interface DecoratorProps {
activities: any[];
@ -40,39 +38,27 @@ interface DecoratorProps {
user: User;
[key: string]: any;
}
export type MemberListDecoratorFactory = (props: DecoratorProps) => JSX.Element | null;
export type Decorator = (props: DecoratorProps) => JSX.Element | null;
type OnlyIn = "guilds" | "dms";
export const decoratorsFactories = new Map<string, { render: MemberListDecoratorFactory, onlyIn?: OnlyIn; }>();
export const decorators = new Map<string, { decorator: Decorator, onlyIn?: OnlyIn; }>();
export function addMemberListDecorator(identifier: string, render: MemberListDecoratorFactory, onlyIn?: OnlyIn) {
decoratorsFactories.set(identifier, { render, onlyIn });
export function addDecorator(identifier: string, decorator: Decorator, onlyIn?: OnlyIn) {
decorators.set(identifier, { decorator, onlyIn });
}
export function removeMemberListDecorator(identifier: string) {
decoratorsFactories.delete(identifier);
export function removeDecorator(identifier: string) {
decorators.delete(identifier);
}
export function __getDecorators(props: DecoratorProps): JSX.Element {
export function __getDecorators(props: DecoratorProps): (JSX.Element | null)[] {
const isInGuild = !!(props.guildId);
const decorators = Array.from(
decoratorsFactories.entries(),
([key, { render: Decorator, onlyIn }]) => {
if ((onlyIn === "guilds" && !isInGuild) || (onlyIn === "dms" && isInGuild))
return null;
return (
<ErrorBoundary noop key={key} message={`Failed to render ${key} Member List Decorator`}>
<Decorator {...props} />
</ErrorBoundary>
);
return Array.from(decorators.values(), decoratorObj => {
const { decorator, onlyIn } = decoratorObj;
// this can most likely be done cleaner
if (!onlyIn || (onlyIn === "guilds" && isInGuild) || (onlyIn === "dms" && !isInGuild)) {
return decorator(props);
}
);
return (
<div className="vc-member-list-decorators-wrapper">
{decorators}
</div>
);
return null;
});
}

View file

@ -16,29 +16,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { JSX, ReactNode } from "react";
export type MessageAccessoryFactory = (props: Record<string, any>) => ReactNode;
export type MessageAccessory = {
render: MessageAccessoryFactory;
export type AccessoryCallback = (props: Record<string, any>) => JSX.Element | null | Array<JSX.Element | null>;
export type Accessory = {
callback: AccessoryCallback;
position?: number;
};
export const accessories = new Map<string, MessageAccessory>();
export const accessories = new Map<String, Accessory>();
export function addMessageAccessory(
export function addAccessory(
identifier: string,
render: MessageAccessoryFactory,
callback: AccessoryCallback,
position?: number
) {
accessories.set(identifier, {
render,
callback,
position,
});
}
export function removeMessageAccessory(identifier: string) {
export function removeAccessory(identifier: string) {
accessories.delete(identifier);
}
@ -46,12 +43,15 @@ export function _modifyAccessories(
elements: JSX.Element[],
props: Record<string, any>
) {
for (const [key, accessory] of accessories.entries()) {
const res = (
<ErrorBoundary message={`Failed to render ${key} Message Accessory`} key={key}>
<accessory.render {...props} />
</ErrorBoundary>
);
for (const accessory of accessories.values()) {
let accessories = accessory.callback(props);
if (accessories == null)
continue;
if (!Array.isArray(accessories))
accessories = [accessories];
else if (accessories.length === 0)
continue;
elements.splice(
accessory.position != null
@ -60,7 +60,7 @@ export function _modifyAccessories(
: accessory.position
: elements.length,
0,
res
...accessories.filter(e => e != null) as JSX.Element[]
);
}

View file

@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { Channel, Message } from "discord-types/general/index.js";
import { JSX } from "react";
export interface MessageDecorationProps {
interface DecorationProps {
author: {
/**
* Will be username if the user has no nickname
@ -46,31 +44,20 @@ export interface MessageDecorationProps {
message: Message;
[key: string]: any;
}
export type MessageDecorationFactory = (props: MessageDecorationProps) => JSX.Element | null;
export type Decoration = (props: DecorationProps) => JSX.Element | null;
export const decorationsFactories = new Map<string, MessageDecorationFactory>();
export const decorations = new Map<string, Decoration>();
export function addMessageDecoration(identifier: string, decoration: MessageDecorationFactory) {
decorationsFactories.set(identifier, decoration);
export function addDecoration(identifier: string, decoration: Decoration) {
decorations.set(identifier, decoration);
}
export function removeMessageDecoration(identifier: string) {
decorationsFactories.delete(identifier);
export function removeDecoration(identifier: string) {
decorations.delete(identifier);
}
export function __addDecorationsToMessage(props: MessageDecorationProps): JSX.Element {
const decorations = Array.from(
decorationsFactories.entries(),
([key, Decoration]) => (
<ErrorBoundary noop message={`Failed to render ${key} Message Decoration`} key={key}>
<Decoration {...props} />
</ErrorBoundary>
)
);
return (
<div className="vc-message-decorations-wrapper">
{decorations}
</div>
);
export function __addDecorationsToMessage(props: DecorationProps): (JSX.Element | null)[] {
return [...decorations.values()].map(decoration => {
return decoration(props);
});
}

View file

@ -73,11 +73,11 @@ export interface MessageExtra {
openWarningPopout: (props: any) => any;
}
export type MessageSendListener = (channelId: string, messageObj: MessageObject, extra: MessageExtra) => Promisable<void | { cancel: boolean; }>;
export type MessageEditListener = (channelId: string, messageId: string, messageObj: MessageObject) => Promisable<void | { cancel: boolean; }>;
export type SendListener = (channelId: string, messageObj: MessageObject, extra: MessageExtra) => Promisable<void | { cancel: boolean; }>;
export type EditListener = (channelId: string, messageId: string, messageObj: MessageObject) => Promisable<void | { cancel: boolean; }>;
const sendListeners = new Set<MessageSendListener>();
const editListeners = new Set<MessageEditListener>();
const sendListeners = new Set<SendListener>();
const editListeners = new Set<EditListener>();
export async function _handlePreSend(channelId: string, messageObj: MessageObject, extra: MessageExtra, replyOptions: MessageReplyOptions) {
extra.replyOptions = replyOptions;
@ -111,29 +111,29 @@ export async function _handlePreEdit(channelId: string, messageId: string, messa
/**
* Note: This event fires off before a message is sent, allowing you to edit the message.
*/
export function addMessagePreSendListener(listener: MessageSendListener) {
export function addPreSendListener(listener: SendListener) {
sendListeners.add(listener);
return listener;
}
/**
* Note: This event fires off before a message's edit is applied, allowing you to further edit the message.
*/
export function addMessagePreEditListener(listener: MessageEditListener) {
export function addPreEditListener(listener: EditListener) {
editListeners.add(listener);
return listener;
}
export function removeMessagePreSendListener(listener: MessageSendListener) {
export function removePreSendListener(listener: SendListener) {
return sendListeners.delete(listener);
}
export function removeMessagePreEditListener(listener: MessageEditListener) {
export function removePreEditListener(listener: EditListener) {
return editListeners.delete(listener);
}
// Message clicks
export type MessageClickListener = (message: Message, channel: Channel, event: MouseEvent) => void;
type ClickListener = (message: Message, channel: Channel, event: MouseEvent) => void;
const listeners = new Set<MessageClickListener>();
const listeners = new Set<ClickListener>();
export function _handleClick(message: Message, channel: Channel, event: MouseEvent) {
// message object may be outdated, so (try to) fetch latest one
@ -147,11 +147,11 @@ export function _handleClick(message: Message, channel: Channel, event: MouseEve
}
}
export function addMessageClickListener(listener: MessageClickListener) {
export function addClickListener(listener: ClickListener) {
listeners.add(listener);
return listener;
}
export function removeMessageClickListener(listener: MessageClickListener) {
export function removeClickListener(listener: ClickListener) {
return listeners.delete(listener);
}

View file

@ -23,7 +23,7 @@ import type { ComponentType, MouseEventHandler } from "react";
const logger = new Logger("MessagePopover");
export interface MessagePopoverButtonItem {
export interface ButtonItem {
key?: string,
label: string,
icon: ComponentType<any>,
@ -33,23 +33,23 @@ export interface MessagePopoverButtonItem {
onContextMenu?: MouseEventHandler<HTMLButtonElement>;
}
export type MessagePopoverButtonFactory = (message: Message) => MessagePopoverButtonItem | null;
export type getButtonItem = (message: Message) => ButtonItem | null;
export const buttons = new Map<string, MessagePopoverButtonFactory>();
export const buttons = new Map<string, getButtonItem>();
export function addMessagePopoverButton(
export function addButton(
identifier: string,
item: MessagePopoverButtonFactory,
item: getButtonItem,
) {
buttons.set(identifier, item);
}
export function removeMessagePopoverButton(identifier: string) {
export function removeButton(identifier: string) {
buttons.delete(identifier);
}
export function _buildPopoverElements(
Component: React.ComponentType<MessagePopoverButtonItem>,
Component: React.ComponentType<ButtonItem>,
message: Message
) {
const items: React.ReactNode[] = [];

View file

@ -16,23 +16,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { waitFor } from "@webpack";
import { find } from "@webpack";
let NoticesModule: any;
waitFor(m => m.show && m.dismiss && !m.suppressAll, m => NoticesModule = m);
const Notices = find(m => m.show && m.dismiss && !m.suppressAll);
export const noticesQueue = [] as any[];
export let currentNotice: any = null;
export function popNotice() {
NoticesModule.dismiss();
Notices.dismiss();
}
export function nextNotice() {
currentNotice = noticesQueue.shift();
if (currentNotice) {
NoticesModule.show(...currentNotice, "VencordNotice");
Notices.show(...currentNotice, "VencordNotice");
}
}

View file

@ -16,36 +16,40 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { ComponentType } from "react";
import { Logger } from "@utils/Logger";
const logger = new Logger("ServerListAPI");
export const enum ServerListRenderPosition {
Above,
In,
}
const componentsAbove = new Set<ComponentType>();
const componentsBelow = new Set<ComponentType>();
const renderFunctionsAbove = new Set<Function>();
const renderFunctionsIn = new Set<Function>();
function getRenderFunctions(position: ServerListRenderPosition) {
return position === ServerListRenderPosition.Above ? componentsAbove : componentsBelow;
return position === ServerListRenderPosition.Above ? renderFunctionsAbove : renderFunctionsIn;
}
export function addServerListElement(position: ServerListRenderPosition, renderFunction: ComponentType) {
export function addServerListElement(position: ServerListRenderPosition, renderFunction: Function) {
getRenderFunctions(position).add(renderFunction);
}
export function removeServerListElement(position: ServerListRenderPosition, renderFunction: ComponentType) {
export function removeServerListElement(position: ServerListRenderPosition, renderFunction: Function) {
getRenderFunctions(position).delete(renderFunction);
}
export const renderAll = (position: ServerListRenderPosition) => {
return Array.from(
getRenderFunctions(position),
(Component, i) => (
<ErrorBoundary noop key={i}>
<Component />
</ErrorBoundary>
)
);
const ret: Array<JSX.Element> = [];
for (const renderFunction of getRenderFunctions(position)) {
try {
ret.unshift(renderFunction());
} catch (e) {
logger.error("Failed to render server list element:", e);
}
}
return ret;
};

View file

@ -23,7 +23,7 @@ import { Logger } from "@utils/Logger";
import { mergeDefaults } from "@utils/mergeDefaults";
import { putCloudSettings } from "@utils/settingsSync";
import { DefinedSettings, OptionType, SettingsChecks, SettingsDefinition } from "@utils/types";
import { React, useEffect } from "@webpack/common";
import { React } from "@webpack/common";
import plugins from "~plugins";
@ -32,10 +32,10 @@ export interface Settings {
autoUpdate: boolean;
autoUpdateNotification: boolean,
useQuickCss: boolean;
themeLinks: string[];
eagerPatches: boolean;
enabledThemes: string[];
enableReactDevtools: boolean;
themeLinks: string[];
frameless: boolean;
transparent: boolean;
winCtrlQ: boolean;
@ -118,7 +118,6 @@ const saveSettingsOnFrequentAction = debounce(async () => {
}
}, 60_000);
export const SettingsStore = new SettingsStoreClass(settings, {
readOnly: true,
getDefaultValue({
@ -194,7 +193,7 @@ export const Settings = SettingsStore.store;
export function useSettings(paths?: UseSettings<Settings>[]) {
const [, forceUpdate] = React.useReducer(() => ({}), {});
useEffect(() => {
React.useEffect(() => {
if (paths) {
paths.forEach(p => SettingsStore.addChangeListener(p, forceUpdate));
return () => paths.forEach(p => SettingsStore.removeChangeListener(p, forceUpdate));
@ -202,7 +201,7 @@ export function useSettings(paths?: UseSettings<Settings>[]) {
SettingsStore.addGlobalChangeListener(forceUpdate);
return () => SettingsStore.removeGlobalChangeListener(forceUpdate);
}
}, [paths]);
}, []);
return SettingsStore.store;
}
@ -222,17 +221,6 @@ export function migratePluginSettings(name: string, ...oldNames: string[]) {
}
}
export function migratePluginSetting(pluginName: string, oldSetting: string, newSetting: string) {
const settings = SettingsStore.plain.plugins[pluginName];
if (!settings) return;
if (!Object.hasOwn(settings, oldSetting) || Object.hasOwn(settings, newSetting)) return;
settings[newSetting] = settings[oldSetting];
delete settings[oldSetting];
SettingsStore.markAsChanged();
}
export function definePluginSettings<
Def extends SettingsDefinition,
Checks extends SettingsChecks<Def>,

View file

@ -89,8 +89,8 @@ export const isStyleEnabled = (name: string) => requireStyle(name).dom?.isConnec
* // -- plugin.ts --
* import pluginStyle from "./plugin.css?managed";
* import { setStyleVars } from "@api/Styles";
* import { findByPropsLazy } from "@webpack";
* const classNames = findByPropsLazy("thin", "scrollerBase"); // { thin: "thin-31rlnD scrollerBase-_bVAAt", ... }
* import { findByProps } from "@webpack";
* const classNames = findByProps("thin", "scrollerBase"); // { thin: "thin-31rlnD scrollerBase-_bVAAt", ... }
*
* // Inside some plugin method like "start()"
* setStyleClassNames(pluginStyle, classNames);

View file

@ -17,8 +17,7 @@
*/
import { proxyLazy } from "@utils/lazy";
import { Logger } from "@utils/Logger";
import { findModuleId, proxyLazyWebpack, wreq } from "@webpack";
import { findByFactoryCode } from "@webpack";
interface UserSettingDefinition<T> {
/**
@ -43,12 +42,7 @@ interface UserSettingDefinition<T> {
userSettingsAPIName: string;
}
export const UserSettings: Record<PropertyKey, UserSettingDefinition<any>> | undefined = proxyLazyWebpack(() => {
const modId = findModuleId('"textAndImages","renderSpoilers"');
if (modId == null) return new Logger("UserSettingsAPI ").error("Didn't find settings module.");
return wreq(modId as any);
});
export const UserSettings = findByFactoryCode<Record<PropertyKey, UserSettingDefinition<any>>>('"textAndImages","renderSpoilers"');
/**
* 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 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.");
for (const key in UserSettings) {
@ -66,10 +60,12 @@ export function getUserSetting<T = any>(group: string, name: string): UserSettin
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.
*

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export function Badge({ text, color }) {
export function Badge({ text, color }): JSX.Element {
return (
<div className="vc-plugins-badge" style={{
backgroundColor: color,

View file

@ -4,10 +4,10 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Parser } from "@webpack/common";
const CodeContainerClasses = findByPropsLazy("markup", "codeContainer");
const CodeContainerClasses = findByProps("markup", "codeContainer");
/**
* Renders code in a Discord codeblock

View file

@ -17,22 +17,16 @@
*/
import { Button } from "@webpack/common";
import { ButtonProps } from "@webpack/types";
import { Heart } from "./Heart";
export default function DonateButton({
look = Button.Looks.LINK,
color = Button.Colors.TRANSPARENT,
...props
}: Partial<ButtonProps>) {
export default function DonateButton(props: any) {
return (
<Button
{...props}
look={look}
color={color}
look={Button.Looks.LINK}
color={Button.Colors.TRANSPARENT}
onClick={() => VencordNative.native.openExternal("https://github.com/sponsors/Vendicated")}
innerClassName="vc-donate-button"
>
<Heart />
Donate

View file

@ -27,7 +27,7 @@ interface Props<T = any> {
/** Render nothing if an error occurs */
noop?: boolean;
/** Fallback component to render if an error occurs */
fallback?: React.ComponentType<React.PropsWithChildren<{ error: any; message: string; stack: string; wrappedProps: T; }>>;
fallback?: React.ComponentType<React.PropsWithChildren<{ error: any; message: string; stack: string; }>>;
/** called when an error occurs. The props property is only available if using .wrap */
onError?(data: { error: Error, errorInfo: React.ErrorInfo, props: T; }): void;
/** Custom error message */
@ -70,7 +70,8 @@ const ErrorBoundary = LazyComponent(() => {
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
this.props.onError?.({ error, errorInfo, props: this.props.wrappedProps });
logger.error(`${this.props.message || "A component threw an Error"}\n`, error, errorInfo.componentStack);
logger.error("A component threw an Error\n", error);
logger.error("Component Stack", errorInfo.componentStack);
}
render() {
@ -79,14 +80,10 @@ const ErrorBoundary = LazyComponent(() => {
if (this.props.noop) return null;
if (this.props.fallback)
return (
<this.props.fallback
wrappedProps={this.props.wrappedProps}
{...this.state}
>
{this.props.children}
</this.props.fallback>
);
return <this.props.fallback
children={this.props.children}
{...this.state}
/>;
const msg = this.props.message || "An error occurred while rendering this Component. More info can be found below and in your console.";

View file

@ -0,0 +1,11 @@
.vc-expandableheader-center-flex {
display: flex;
place-items: center;
}
.vc-expandableheader-btn {
all: unset;
cursor: pointer;
width: 24px;
height: 24px;
}

View file

@ -0,0 +1,121 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import "./ExpandableHeader.css";
import { classNameFactory } from "@api/Styles";
import { Text, Tooltip, useState } from "@webpack/common";
const cl = classNameFactory("vc-expandableheader-");
export interface ExpandableHeaderProps {
onMoreClick?: () => void;
moreTooltipText?: string;
onDropDownClick?: (state: boolean) => void;
defaultState?: boolean;
headerText: string;
children: React.ReactNode;
buttons?: React.ReactNode[];
forceOpen?: boolean;
}
export function ExpandableHeader({
children,
onMoreClick,
buttons,
moreTooltipText,
onDropDownClick,
headerText,
defaultState = false,
forceOpen = false,
}: ExpandableHeaderProps) {
const [showContent, setShowContent] = useState(defaultState || forceOpen);
return (
<>
<div style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "8px"
}}>
<Text
tag="h2"
variant="eyebrow"
style={{
color: "var(--header-primary)",
display: "inline"
}}
>
{headerText}
</Text>
<div className={cl("center-flex")}>
{
buttons ?? null
}
{
onMoreClick && // only show more button if callback is provided
<Tooltip text={moreTooltipText}>
{tooltipProps => (
<button
{...tooltipProps}
className={cl("btn")}
onClick={onMoreClick}>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
>
<path fill="var(--text-normal)" d="M7 12.001C7 10.8964 6.10457 10.001 5 10.001C3.89543 10.001 3 10.8964 3 12.001C3 13.1055 3.89543 14.001 5 14.001C6.10457 14.001 7 13.1055 7 12.001ZM14 12.001C14 10.8964 13.1046 10.001 12 10.001C10.8954 10.001 10 10.8964 10 12.001C10 13.1055 10.8954 14.001 12 14.001C13.1046 14.001 14 13.1055 14 12.001ZM19 10.001C20.1046 10.001 21 10.8964 21 12.001C21 13.1055 20.1046 14.001 19 14.001C17.8954 14.001 17 13.1055 17 12.001C17 10.8964 17.8954 10.001 19 10.001Z" />
</svg>
</button>
)}
</Tooltip>
}
<Tooltip text={showContent ? "Hide " + headerText : "Show " + headerText}>
{tooltipProps => (
<button
{...tooltipProps}
className={cl("btn")}
onClick={() => {
setShowContent(v => !v);
onDropDownClick?.(showContent);
}}
disabled={forceOpen}
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
transform={showContent ? "scale(1 -1)" : "scale(1 1)"}
>
<path fill="var(--text-normal)" d="M16.59 8.59003L12 13.17L7.41 8.59003L6 10L12 16L18 10L16.59 8.59003Z" />
</svg>
</button>
)}
</Tooltip>
</div>
</div>
{showContent && children}
</>
);
}

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { CSSProperties, JSX } from "react";
import { CSSProperties } from "react";
interface Props {
columns: number;

View file

@ -16,22 +16,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { classes } from "@utils/misc";
import { SVGProps } from "react";
export function Heart(props: SVGProps<SVGSVGElement>) {
export function Heart() {
return (
<svg
aria-hidden="true"
viewBox="0 0 16 16"
height="16"
viewBox="0 0 16 16"
width="16"
{...props}
className={classes("vc-heart-icon", props.className)}
style={{ marginRight: "0.5em", transform: "translateY(2px)" }}
>
<path
fill="#db61a2"
fillRule="evenodd"
fill-rule="evenodd"
d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"
/>
</svg>

View file

@ -18,9 +18,10 @@
import "./iconStyles.css";
import { getIntlMessage } from "@utils/discord";
import { getTheme, Theme } from "@utils/discord";
import { classes } from "@utils/misc";
import type { JSX, PropsWithChildren } from "react";
import { i18n } from "@webpack/common";
import type { PropsWithChildren } from "react";
interface BaseIconProps extends IconProps {
viewBox: string;
@ -55,7 +56,7 @@ export function LinkIcon({ height = 24, width = 24, className }: IconProps) {
className={classes(className, "vc-link-icon")}
viewBox="0 0 24 24"
>
<g fill="none" fillRule="evenodd">
<g fill="none" fill-rule="evenodd">
<path fill="currentColor" d="M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24zm2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z" />
<rect width={width} height={height} />
</g>
@ -64,7 +65,8 @@ export function LinkIcon({ height = 24, width = 24, className }: IconProps) {
}
/**
* Discord's copy icon, as seen in the user panel popout on the right of the username and in large code blocks
* Discord's copy icon, as seen in the user popout right of the username when clicking
* your own username in the bottom left user panel
*/
export function CopyIcon(props: IconProps) {
return (
@ -74,9 +76,8 @@ export function CopyIcon(props: IconProps) {
viewBox="0 0 24 24"
>
<g fill="currentColor">
<path d="M3 16a1 1 0 0 1-1-1v-5a8 8 0 0 1 8-8h5a1 1 0 0 1 1 1v.5a.5.5 0 0 1-.5.5H10a6 6 0 0 0-6 6v5.5a.5.5 0 0 1-.5.5H3Z" />
<path d="M6 18a4 4 0 0 0 4 4h8a4 4 0 0 0 4-4v-4h-3a5 5 0 0 1-5-5V6h-4a4 4 0 0 0-4 4v8Z" />
<path d="M21.73 12a3 3 0 0 0-.6-.88l-4.25-4.24a3 3 0 0 0-.88-.61V9a3 3 0 0 0 3 3h2.73Z" />
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1z" />
<path d="M15 5H8c-1.1 0-1.99.9-1.99 2L6 21c0 1.1.89 2 1.99 2H19c1.1 0 2-.9 2-2V11l-6-6zM8 21V7h6v5h5v9H8z" />
</g>
</Icon>
);
@ -122,8 +123,8 @@ export function InfoIcon(props: IconProps) {
>
<path
fill="currentColor"
fillRule="evenodd"
d="M23 12a11 11 0 1 1-22 0 11 11 0 0 1 22 0Zm-9.5-4.75a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm-.77 3.96a1 1 0 1 0-1.96-.42l-1.04 4.86a2.77 2.77 0 0 0 4.31 2.83l.24-.17a1 1 0 1 0-1.16-1.62l-.24.17a.77.77 0 0 1-1.2-.79l1.05-4.86Z" clipRule="evenodd"
transform="translate(2 2)"
d="M9,7 L11,7 L11,5 L9,5 L9,7 Z M10,18 C5.59,18 2,14.41 2,10 C2,5.59 5.59,2 10,2 C14.41,2 18,5.59 18,10 C18,14.41 14.41,18 10,18 L10,18 Z M10,4.4408921e-16 C4.4771525,-1.77635684e-15 4.4408921e-16,4.4771525 0,10 C-1.33226763e-15,12.6521649 1.0535684,15.195704 2.92893219,17.0710678 C4.80429597,18.9464316 7.3478351,20 10,20 C12.6521649,20 15.195704,18.9464316 17.0710678,17.0710678 C18.9464316,15.195704 20,12.6521649 20,10 C20,7.3478351 18.9464316,4.80429597 17.0710678,2.92893219 C15.195704,1.0535684 12.6521649,2.22044605e-16 10,0 L10,4.4408921e-16 Z M9,15 L11,15 L11,9 L9,9 L9,15 L9,15 Z"
/>
</Icon>
);
@ -132,7 +133,7 @@ export function InfoIcon(props: IconProps) {
export function OwnerCrownIcon(props: IconProps) {
return (
<Icon
aria-label={getIntlMessage("GUILD_OWNER")}
aria-label={i18n.Messages.GUILD_OWNER}
{...props}
className={classes(props.className, "vc-owner-crown-icon")}
role="img"
@ -211,10 +212,9 @@ export function CogWheel(props: IconProps) {
viewBox="0 0 24 24"
>
<path
fill="currentColor"
fillRule="evenodd"
d="M10.56 1.1c-.46.05-.7.53-.64.98.18 1.16-.19 2.2-.98 2.53-.8.33-1.79-.15-2.49-1.1-.27-.36-.78-.52-1.14-.24-.77.59-1.45 1.27-2.04 2.04-.28.36-.12.87.24 1.14.96.7 1.43 1.7 1.1 2.49-.33.8-1.37 1.16-2.53.98-.45-.07-.93.18-.99.64a11.1 11.1 0 0 0 0 2.88c.06.46.54.7.99.64 1.16-.18 2.2.19 2.53.98.33.8-.14 1.79-1.1 2.49-.36.27-.52.78-.24 1.14.59.77 1.27 1.45 2.04 2.04.36.28.87.12 1.14-.24.7-.95 1.7-1.43 2.49-1.1.8.33 1.16 1.37.98 2.53-.07.45.18.93.64.99a11.1 11.1 0 0 0 2.88 0c.46-.06.7-.54.64-.99-.18-1.16.19-2.2.98-2.53.8-.33 1.79.14 2.49 1.1.27.36.78.52 1.14.24.77-.59 1.45-1.27 2.04-2.04.28-.36.12-.87-.24-1.14-.96-.7-1.43-1.7-1.1-2.49.33-.8 1.37-1.16 2.53-.98.45.07.93-.18.99-.64a11.1 11.1 0 0 0 0-2.88c-.06-.46-.54-.7-.99-.64-1.16.18-2.2-.19-2.53-.98-.33-.8.14-1.79 1.1-2.49.36-.27.52-.78.24-1.14a11.07 11.07 0 0 0-2.04-2.04c-.36-.28-.87-.12-1.14.24-.7.96-1.7 1.43-2.49 1.1-.8-.33-1.16-1.37-.98-2.53.07-.45-.18-.93-.64-.99a11.1 11.1 0 0 0-2.88 0ZM16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z"
clipRule="evenodd"
fill="currentColor"
d="M19.738 10H22V14H19.739C19.498 14.931 19.1 15.798 18.565 16.564L20 18L18 20L16.565 18.564C15.797 19.099 14.932 19.498 14 19.738V22H10V19.738C9.069 19.498 8.203 19.099 7.436 18.564L6 20L4 18L5.436 16.564C4.901 15.799 4.502 14.932 4.262 14H2V10H4.262C4.502 9.068 4.9 8.202 5.436 7.436L4 6L6 4L7.436 5.436C8.202 4.9 9.068 4.502 10 4.262V2H14V4.261C14.932 4.502 15.797 4.9 16.565 5.435L18 3.999L20 5.999L18.564 7.436C19.099 8.202 19.498 9.069 19.738 10ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16Z"
/>
</Icon>
);
@ -262,7 +262,7 @@ export function PlusIcon(props: IconProps) {
viewBox="0 0 18 18"
>
<polygon
fillRule="nonzero"
fill-rule="nonzero"
fill="currentColor"
points="15 10 10 10 10 15 8 15 8 10 3 10 3 8 8 8 8 3 10 3 10 8 15 8"
/>
@ -407,30 +407,23 @@ export function PencilIcon(props: IconProps) {
);
}
export function GithubIcon(props: IconProps) {
return (
<Icon
{...props}
viewBox="-3 -3 30 30"
>
<path
fill={props.fill || "currentColor"}
d="M12 0C5.37 0 0 5.37 0 12c0 5.3 3.438 9.8 8.205 11.385.6.11.82-.26.82-.577v-2.17c-3.338.726-4.042-1.61-4.042-1.61-.546-1.387-1.333-1.757-1.333-1.757-1.09-.745.083-.73.083-.73 1.205.084 1.84 1.237 1.84 1.237 1.07 1.835 2.807 1.305 3.492.998.108-.775.42-1.305.763-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.467-2.38 1.235-3.22-.123-.303-.535-1.523.117-3.176 0 0 1.008-.322 3.3 1.23.957-.266 1.98-.398 3-.403 1.02.005 2.043.137 3 .403 2.29-1.552 3.297-1.23 3.297-1.23.653 1.653.24 2.873.118 3.176.77.84 1.233 1.91 1.233 3.22 0 4.61-2.803 5.625-5.475 5.92.43.37.823 1.102.823 2.222v3.293c0 .32.218.694.825.577C20.565 21.797 24 17.298 24 12c0-6.63-5.37-12-12-12z"
/>
</Icon>
);
const WebsiteIconDark = "/assets/e1e96d89e192de1997f73730db26e94f.svg";
const WebsiteIconLight = "/assets/730f58bcfd5a57a5e22460c445a0c6cf.svg";
const GithubIconLight = "/assets/3ff98ad75ac94fa883af5ed62d17c459.svg";
const GithubIconDark = "/assets/6a853b4c87fce386cbfef4a2efbacb09.svg";
export function GithubIcon(props: ImageProps) {
const src = getTheme() === Theme.Light
? GithubIconLight
: GithubIconDark;
return <img {...props} src={src} />;
}
export function WebsiteIcon(props: IconProps) {
return (
<Icon
{...props}
viewBox="0 0 24 24"
>
<path
fill={props.fill || "currentColor"}
d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zM4 12c0-.899.156-1.762.431-2.569L6 11l2 2v2l2 2 1 1v1.931C7.061 19.436 4 16.072 4 12zm14.33 4.873C17.677 16.347 16.687 16 16 16v-1a2 2 0 0 0-2-2h-4v-3a2 2 0 0 0 2-2V7h1a2 2 0 0 0 2-2v-.411C17.928 5.778 20 8.65 20 12a7.947 7.947 0 0 1-1.67 4.873z"
/>
</Icon>
);
export function WebsiteIcon(props: ImageProps) {
const src = getTheme() === Theme.Light
? WebsiteIconLight
: WebsiteIconDark;
return <img {...props} src={src} />;
}

View file

@ -44,7 +44,7 @@ function ContributorModal({ user }: { user: User; }) {
useEffect(() => {
if (!profile && !user.bot && user.id)
fetchUserProfile(user.id);
}, [user.id, user.bot, profile]);
}, [user.id]);
const githubName = profile?.connectedAccounts?.find(a => a.type === "github")?.name;
const website = profile?.connectedAccounts?.find(a => a.type === "domain")?.name;

View file

@ -6,19 +6,16 @@
import "./LinkIconButton.css";
import { getTheme, Theme } from "@utils/discord";
import { MaskedLink, Tooltip } from "@webpack/common";
import { GithubIcon, WebsiteIcon } from "..";
export function GithubLinkIcon() {
const theme = getTheme() === Theme.Light ? "#000000" : "#FFFFFF";
return <GithubIcon aria-hidden fill={theme} className={"vc-settings-modal-link-icon"} />;
return <GithubIcon aria-hidden className={"vc-settings-modal-link-icon"} />;
}
export function WebsiteLinkIcon() {
const theme = getTheme() === Theme.Light ? "#000000" : "#FFFFFF";
return <WebsiteIcon aria-hidden fill={theme} className={"vc-settings-modal-link-icon"} />;
return <WebsiteIcon aria-hidden className={"vc-settings-modal-link-icon"} />;
}
interface Props {

View file

@ -24,20 +24,18 @@ import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
import { gitRemote } from "@shared/vencordUserAgent";
import { proxyLazy } from "@utils/lazy";
import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { OptionType, Plugin } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common";
import { find, findByProps, findComponentByCode } from "@webpack";
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserUtils } from "@webpack/common";
import { User } from "discord-types/general";
import { Constructor } from "type-fest";
import { PluginMeta } from "~plugins";
import {
ISettingCustomElementProps,
ISettingElementProps,
SettingBooleanComponent,
SettingCustomComponent,
@ -51,9 +49,9 @@ import { GithubButton, WebsiteButton } from "./LinkIconButton";
const cl = classNameFactory("vc-plugin-modal-");
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
const UserRecord: Constructor<Partial<User>> = proxyLazy(() => UserStore.getCurrentUser().constructor) as any;
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByProps("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
const UserRecord = find<Constructor<Partial<User>>>(m => m?.prototype?.getAvatarURL && m?.prototype?.hasHadPremium);
interface PluginModalProps extends ModalProps {
plugin: Plugin;
@ -75,15 +73,14 @@ function makeDummyUser(user: { username: string; id?: string; avatar?: string; }
return newUser;
}
const Components: Record<OptionType, React.ComponentType<ISettingElementProps<any> | ISettingCustomElementProps<any>>> = {
const Components: Record<OptionType, React.ComponentType<ISettingElementProps<any>>> = {
[OptionType.STRING]: SettingTextComponent,
[OptionType.NUMBER]: SettingNumericComponent,
[OptionType.BIGINT]: SettingNumericComponent,
[OptionType.BOOLEAN]: SettingBooleanComponent,
[OptionType.SELECT]: SettingSelectComponent,
[OptionType.SLIDER]: SettingSliderComponent,
[OptionType.COMPONENT]: SettingCustomComponent,
[OptionType.CUSTOM]: () => null,
[OptionType.COMPONENT]: SettingCustomComponent
};
export default function PluginModal({ plugin, onRestartNeeded, onClose, transitionState }: PluginModalProps) {
@ -111,7 +108,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
setAuthors(a => [...a, author]);
}
})();
}, [plugin.authors]);
}, []);
async function saveAndClose() {
if (!plugin.options) {
@ -131,8 +128,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
for (const [key, value] of Object.entries(tempSettings)) {
const option = plugin.options[key];
pluginSettings[key] = value;
if (option.type === OptionType.CUSTOM) continue;
option?.onChange?.(value);
if (option?.restartNeeded) restartNeeded = true;
}
if (restartNeeded) onRestartNeeded();
@ -144,7 +140,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
return <Forms.FormText>There are no settings for this plugin.</Forms.FormText>;
} else {
const options = Object.entries(plugin.options).map(([key, setting]) => {
if (setting.type === OptionType.CUSTOM || setting.hidden) return null;
if (setting.hidden) return null;
function onChange(newValue: any) {
setTempSettings(s => ({ ...s, [key]: newValue }));

View file

@ -18,8 +18,8 @@
import { PluginOptionComponent } from "@utils/types";
import { ISettingCustomElementProps } from ".";
import { ISettingElementProps } from ".";
export function SettingCustomComponent({ option, onChange, onError }: ISettingCustomElementProps<PluginOptionComponent>) {
export function SettingCustomComponent({ option, onChange, onError }: ISettingElementProps<PluginOptionComponent>) {
return option.component({ setValue: onChange, setError: onError, option });
}

View file

@ -16,8 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Margins } from "@utils/margins";
import { wordsFromCamel, wordsToTitle } from "@utils/text";
import { OptionType, PluginOptionNumber } from "@utils/types";
import { Forms, React, TextInput } from "@webpack/common";
@ -56,8 +54,7 @@ export function SettingNumericComponent({ option, pluginSettings, definedSetting
return (
<Forms.FormSection>
<Forms.FormTitle>{wordsToTitle(wordsFromCamel(id))}</Forms.FormTitle>
<Forms.FormText className={Margins.bottom20} type="description">{option.description}</Forms.FormText>
<Forms.FormTitle>{option.description}</Forms.FormTitle>
<TextInput
type="number"
pattern="-?[0-9]+"

View file

@ -16,8 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Margins } from "@utils/margins";
import { wordsFromCamel, wordsToTitle } from "@utils/text";
import { PluginOptionSelect } from "@utils/types";
import { Forms, React, Select } from "@webpack/common";
@ -46,8 +44,7 @@ export function SettingSelectComponent({ option, pluginSettings, definedSettings
return (
<Forms.FormSection>
<Forms.FormTitle>{wordsToTitle(wordsFromCamel(id))}</Forms.FormTitle>
<Forms.FormText className={Margins.bottom16} type="description">{option.description}</Forms.FormText>
<Forms.FormTitle>{option.description}</Forms.FormTitle>
<Select
isDisabled={option.disabled?.call(definedSettings) ?? false}
options={option.options}

View file

@ -16,8 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Margins } from "@utils/margins";
import { wordsFromCamel, wordsToTitle } from "@utils/text";
import { PluginOptionSlider } from "@utils/types";
import { Forms, React, Slider } from "@webpack/common";
@ -52,8 +50,7 @@ export function SettingSliderComponent({ option, pluginSettings, definedSettings
return (
<Forms.FormSection>
<Forms.FormTitle>{wordsToTitle(wordsFromCamel(id))}</Forms.FormTitle>
<Forms.FormText className={Margins.bottom20} type="description">{option.description}</Forms.FormText>
<Forms.FormTitle>{option.description}</Forms.FormTitle>
<Slider
disabled={option.disabled?.call(definedSettings) ?? false}
markers={option.markers}

View file

@ -16,8 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Margins } from "@utils/margins";
import { wordsFromCamel, wordsToTitle } from "@utils/text";
import { PluginOptionString } from "@utils/types";
import { Forms, React, TextInput } from "@webpack/common";
@ -43,8 +41,7 @@ export function SettingTextComponent({ option, pluginSettings, definedSettings,
return (
<Forms.FormSection>
<Forms.FormTitle>{wordsToTitle(wordsFromCamel(id))}</Forms.FormTitle>
<Forms.FormText className={Margins.bottom20} type="description">{option.description}</Forms.FormText>
<Forms.FormTitle>{option.description}</Forms.FormTitle>
<TextInput
type="text"
value={state}

View file

@ -18,7 +18,7 @@
import { DefinedSettings, PluginOptionBase } from "@utils/types";
interface ISettingElementPropsBase<T> {
export interface ISettingElementProps<T extends PluginOptionBase> {
option: T;
onChange(newValue: any): void;
pluginSettings: {
@ -30,9 +30,6 @@ interface ISettingElementPropsBase<T> {
definedSettings?: DefinedSettings;
}
export type ISettingElementProps<T extends PluginOptionBase> = ISettingElementPropsBase<T>;
export type ISettingCustomElementProps<T extends Omit<PluginOptionBase, "description" | "placeholder">> = ISettingElementPropsBase<T>;
export * from "../../Badge";
export * from "./SettingBooleanComponent";
export * from "./SettingCustomComponent";

View file

@ -33,20 +33,19 @@ import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc";
import { useAwaiter } from "@utils/react";
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 { JSX } from "react";
import Plugins, { ExcludedPlugins } from "~plugins";
// 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 logger = new Logger("PluginSettings", "#a6d189");
const InputStyles = findByPropsLazy("inputWrapper", "inputDefault", "error");
const ButtonClasses = findByPropsLazy("button", "disabled", "enabled");
const InputStyles = findByProps("inputWrapper", "inputDefault", "error");
const ButtonClasses = findByProps("button", "disabled", "enabled");
function showErrorToast(message: string) {
@ -69,7 +68,7 @@ function ReloadRequiredCard({ required }: { required: boolean; }) {
<Forms.FormText className={cl("dep-text")}>
Restart now to apply new plugins and their settings
</Forms.FormText>
<Button onClick={() => location.reload()} className={cl("restart-button")}>
<Button onClick={() => location.reload()}>
Restart
</Button>
</>
@ -94,14 +93,14 @@ interface PluginCardProps extends React.HTMLProps<HTMLDivElement> {
export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) {
const settings = Settings.plugins[plugin.name];
const isEnabled = () => Vencord.Plugins.isPluginEnabled(plugin.name);
const isEnabled = () => settings.enabled ?? false;
function toggleEnabled() {
const wasEnabled = isEnabled();
// If we're enabling a plugin, make sure all deps are enabled recursively.
if (!wasEnabled) {
const { restartNeeded, failures } = startDependenciesRecursive(plugin);
const { restartNeeded, failures } = PluginManager.startDependenciesRecursive(plugin);
if (failures.length) {
logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`);
showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null);
@ -127,7 +126,7 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
return;
}
const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin);
const result = wasEnabled ? PluginManager.stopPlugin(plugin) : PluginManager.startPlugin(plugin);
if (!result) {
settings.enabled = false;
@ -158,8 +157,8 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
className={classes(ButtonClasses.button, cl("info-button"))}
>
{plugin.options && !isObjectEmpty(plugin.options)
? <CogWheel className={cl("info-icon")} />
: <InfoIcon className={cl("info-icon")} />}
? <CogWheel />
: <InfoIcon />}
</button>
}
/>
@ -293,10 +292,10 @@ export default function PluginSettings() {
if (!pluginFilter(p)) continue;
const isRequired = p.required || p.isDependency || depMap[p.name]?.some(d => settings.plugins[d].enabled);
const isRequired = p.required || depMap[p.name]?.some(d => settings.plugins[d].enabled);
if (isRequired) {
const tooltipText = p.required || !depMap[p.name]
const tooltipText = p.required
? "This plugin is required for Vencord to function."
: makeDependencyList(depMap[p.name]?.filter(d => settings.plugins[d].enabled));
@ -388,7 +387,7 @@ function makeDependencyList(deps: string[]) {
return (
<React.Fragment>
<Forms.FormText>This plugin is required by:</Forms.FormText>
{deps.map((dep: string) => <Forms.FormText key={dep} className={cl("dep-text")}>{dep}</Forms.FormText>)}
{deps.map((dep: string) => <Forms.FormText className={cl("dep-text")}>{dep}</Forms.FormText>)}
</React.Fragment>
);
}

View file

@ -63,7 +63,10 @@
height: 8em;
display: flex;
flex-direction: column;
gap: 0.25em;
}
.vc-plugins-info-card div {
line-height: 32px;
}
.vc-plugins-restart-card {
@ -73,11 +76,11 @@
color: var(--info-warning-text);
}
.vc-plugins-restart-button {
.vc-plugins-restart-card button {
margin-top: 0.5em;
background: var(--info-warning-foreground) !important;
}
.vc-plugins-info-icon:not(:hover, :focus) {
.vc-plugins-info-button svg:not(:hover, :focus) {
color: var(--text-muted);
}

View file

@ -19,7 +19,7 @@
import "./Switch.css";
import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
interface SwitchProps {
checked: boolean;
@ -29,7 +29,7 @@ interface SwitchProps {
const SWITCH_ON = "var(--green-360)";
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) {
return (

View file

@ -22,7 +22,7 @@ import { Margins } from "@utils/margins";
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
import { makeCodeblock } from "@utils/text";
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 { SettingsTab, wrapTab } from "./shared";
@ -33,7 +33,7 @@ if (IS_DEV) {
}
const findCandidates = debounce(function ({ find, setModule, setError }) {
const candidates = search(find);
const candidates = searchFactories(find);
const keys = Object.keys(candidates);
const len = keys.length;
if (len === 0)
@ -56,7 +56,7 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
const [compileResult, setCompileResult] = React.useState<[boolean, string]>();
const [patchedCode, matchResult, diff] = React.useMemo(() => {
const src: string = fact.toString().replaceAll("\n", "");
const src = String(fact).replaceAll("\n", "");
try {
new RegExp(match);
@ -65,7 +65,7 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
}
const canonicalMatch = canonicalizeMatch(new RegExp(match));
try {
const canonicalReplace = canonicalizeReplace(replacement, 'Vencord.Plugins.plugins["YourPlugin"]');
const canonicalReplace = canonicalizeReplace(replacement, "YourPlugin");
var patched = src.replace(canonicalMatch, canonicalReplace as string);
setReplacementError(void 0);
} catch (e) {
@ -111,9 +111,9 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
}
function renderDiff() {
return diff?.map((p, idx) => {
return diff?.map(p => {
const color = p.added ? "lime" : p.removed ? "red" : "grey";
return <div key={idx} style={{ color, userSelect: "text", wordBreak: "break-all", lineBreak: "anywhere" }}>{p.value}</div>;
return <div style={{ color, userSelect: "text", wordBreak: "break-all", lineBreak: "anywhere" }}>{p.value}</div>;
});
}
@ -247,7 +247,7 @@ function FullPatchInput({ setFind, setParsedFind, setMatch, setReplacement }: Fu
}
try {
const parsed = (0, eval)(`([${fullPatch}][0])`) as Patch;
const parsed = (0, eval)(`(${fullPatch})`) as Patch;
if (!parsed.find) throw new Error("No 'find' field");
if (!parsed.replacement) throw new Error("No 'replacement' field");
@ -382,7 +382,6 @@ function PatchHelper() {
<Forms.FormTitle className={Margins.top20}>Code</Forms.FormTitle>
<CodeBlock lang="js" content={code} />
<Button onClick={() => Clipboard.copy(code)}>Copy to Clipboard</Button>
<Button className={Margins.top8} onClick={() => Clipboard.copy("```ts\n" + code + "\n```")}>Copy as Codeblock</Button>
</>
)}
</SettingsTab>

View file

@ -1,77 +0,0 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import "./specialCard.css";
import { classNameFactory } from "@api/Styles";
import { Card, Clickable, Forms, React } from "@webpack/common";
import type { PropsWithChildren } from "react";
const cl = classNameFactory("vc-special-");
interface StyledCardProps {
title: string;
subtitle?: string;
description: string;
cardImage?: string;
backgroundImage?: string;
backgroundColor?: string;
buttonTitle?: string;
buttonOnClick?: () => void;
}
export function SpecialCard({ title, subtitle, description, cardImage, backgroundImage, backgroundColor, buttonTitle, buttonOnClick: onClick, children }: PropsWithChildren<StyledCardProps>) {
const cardStyle: React.CSSProperties = {
backgroundColor: backgroundColor || "#9c85ef",
backgroundImage: `url(${backgroundImage || ""})`,
};
return (
<Card className={cl("card", "card-special")} style={cardStyle}>
<div className={cl("card-flex")}>
<div className={cl("card-flex-main")}>
<Forms.FormTitle className={cl("title")} tag="h5">{title}</Forms.FormTitle>
<Forms.FormText className={cl("subtitle")}>{subtitle}</Forms.FormText>
<Forms.FormText className={cl("text")}>{description}</Forms.FormText>
{children}
</div>
{cardImage && (
<div className={cl("image-container")}>
<img
role="presentation"
src={cardImage}
alt=""
className={cl("image")}
/>
</div>
)}
</div>
{buttonTitle && (
<>
<Forms.FormDivider className={cl("seperator")} />
<Clickable onClick={onClick} className={cl("hyperlink")}>
<Forms.FormText className={cl("hyperlink-text")}>
{buttonTitle}
</Forms.FormText>
</Clickable>
</>
)}
</Card>
);
}

View file

@ -16,7 +16,7 @@
* 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 { Flex } from "@components/Flex";
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 { showItemInFolder } from "@utils/native";
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 type { ComponentType, Ref, SyntheticEvent } from "react";
import type { Ref, SyntheticEvent } from "react";
import Plugins from "~plugins";
@ -37,14 +37,14 @@ import { AddonCard } from "./AddonCard";
import { QuickAction, QuickActionCard } from "./quickActions";
import { SettingsTab, wrapTab } from "./shared";
type FileInput = ComponentType<{
type FileInputProps = {
ref: Ref<HTMLInputElement>;
onChange: (e: SyntheticEvent<HTMLInputElement>) => void;
multiple?: boolean;
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-");
@ -77,16 +77,8 @@ function Validators({ themeLinks }: { themeLinks: string[]; }) {
<Forms.FormTitle className={Margins.top20} tag="h5">Validator</Forms.FormTitle>
<Forms.FormText>This section will tell you whether your themes can successfully be loaded</Forms.FormText>
<div>
{themeLinks.map(rawLink => {
const { label, link } = (() => {
const match = /^@(light|dark) (.*)/.exec(rawLink);
if (!match) return { label: rawLink, link: rawLink };
const [, mode, link] = match;
return { label: `[${mode} mode only] ${link}`, link };
})();
return <Card style={{
{themeLinks.map(link => (
<Card style={{
padding: ".5em",
marginBottom: ".5em",
marginTop: ".5em"
@ -94,11 +86,11 @@ function Validators({ themeLinks }: { themeLinks: string[]; }) {
<Forms.FormTitle tag="h5" style={{
overflowWrap: "break-word"
}}>
{label}
{link}
</Forms.FormTitle>
<Validator link={link} />
</Card>;
})}
</Card>
))}
</div>
</>
);
@ -257,7 +249,7 @@ function ThemesTab() {
Icon={PaintbrushIcon}
/>
{Settings.plugins.ClientTheme.enabled && (
{Vencord.Plugins.isPluginEnabled("ClientTheme") && (
<QuickAction
text="Edit ClientTheme"
action={() => openPluginModal(Plugins.ClientTheme)}
@ -304,7 +296,6 @@ function ThemesTab() {
<Card className="vc-settings-card vc-text-selectable">
<Forms.FormTitle tag="h5">Paste links to css files here</Forms.FormTitle>
<Forms.FormText>One link per line</Forms.FormText>
<Forms.FormText>You can prefix lines with @light or @dark to toggle them based on your Discord theme</Forms.FormText>
<Forms.FormText>Make sure to use direct links to files (raw or github.io)!</Forms.FormText>
</Card>

View file

@ -61,7 +61,7 @@ function withDispatcher(dispatcher: React.Dispatch<React.SetStateAction<boolean>
title: "Oops!",
body: (
<ErrorCard>
{err.split("\n").map((line, idx) => <div key={idx}>{Parser.parse(line)}</div>)}
{err.split("\n").map(line => <div>{Parser.parse(line)}</div>)}
</ErrorCard>
)
});
@ -87,7 +87,7 @@ function Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof
return (
<Card style={{ padding: "0 0.5em" }}>
{updates.map(({ hash, author, message }) => (
<div key={hash} style={{
<div style={{
marginTop: "0.5em",
marginBottom: "0.5em"
}}>

View file

@ -20,38 +20,29 @@ import { openNotificationLogModal } from "@api/Notifications/notificationLog";
import { useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import DonateButton from "@components/DonateButton";
import { openContributorModal } from "@components/PluginSettings/ContributorModal";
import { openPluginModal } from "@components/PluginSettings/PluginModal";
import { gitRemote } from "@shared/vencordUserAgent";
import { DONOR_ROLE_ID, VENCORD_GUILD_ID } from "@utils/constants";
import { Margins } from "@utils/margins";
import { identity, isPluginDev } from "@utils/misc";
import { identity } from "@utils/misc";
import { relaunch, showItemInFolder } from "@utils/native";
import { useAwaiter } from "@utils/react";
import { Button, Forms, GuildMemberStore, React, Select, Switch, UserStore } from "@webpack/common";
import { Button, Card, Forms, React, Select, Switch } from "@webpack/common";
import BadgeAPI from "../../plugins/_api/badges";
import { Flex, FolderIcon, GithubIcon, LogIcon, PaintbrushIcon, RestartIcon } from "..";
import { openNotificationSettingsModal } from "./NotificationSettings";
import { QuickAction, QuickActionCard } from "./quickActions";
import { SettingsTab, wrapTab } from "./shared";
import { SpecialCard } from "./SpecialCard";
const cl = classNameFactory("vc-settings-");
const DEFAULT_DONATE_IMAGE = "https://cdn.discordapp.com/emojis/1026533090627174460.png";
const SHIGGY_DONATE_IMAGE = "https://media.discordapp.net/stickers/1039992459209490513.png";
const VENNIE_DONATOR_IMAGE = "https://cdn.discordapp.com/emojis/1238120638020063377.png";
const COZY_CONTRIB_IMAGE = "https://cdn.discordapp.com/emojis/1026533070955872337.png";
const DONOR_BACKGROUND_IMAGE = "https://media.discordapp.net/stickers/1311070116305436712.png?size=2048";
const CONTRIB_BACKGROUND_IMAGE = "https://media.discordapp.net/stickers/1311070166481895484.png?size=2048";
type KeysOfType<Object, Type> = {
[K in keyof Object]: Object[K] extends Type ? K : never;
}[keyof Object];
function VencordSettings() {
const [settingsDir, , settingsDirPending] = useAwaiter(VencordNative.settings.getSettingsDir, {
fallbackValue: "Loading..."
@ -64,8 +55,6 @@ function VencordSettings() {
const isMac = navigator.platform.toLowerCase().startsWith("mac");
const needsVibrancySettings = IS_DISCORD_DESKTOP && isMac;
const user = UserStore.getCurrentUser();
const Switches: Array<false | {
key: KeysOfType<typeof settings, boolean>;
title: string;
@ -110,44 +99,7 @@ function VencordSettings() {
return (
<SettingsTab title="Vencord Settings">
{isDonor(user?.id)
? (
<SpecialCard
title="Donations"
subtitle="Thank you for donating!"
description="All Vencord users can see your badge! You can change it at any time by messaging @vending.machine."
cardImage={VENNIE_DONATOR_IMAGE}
backgroundImage={DONOR_BACKGROUND_IMAGE}
backgroundColor="#ED87A9"
>
<DonateButtonComponent />
</SpecialCard>
)
: (
<SpecialCard
title="Support the Project"
description="Please consider supporting the development of Vencord by donating!"
cardImage={donateImage}
backgroundImage={DONOR_BACKGROUND_IMAGE}
backgroundColor="#c3a3ce"
>
<DonateButtonComponent />
</SpecialCard>
)
}
{isPluginDev(user?.id) && (
<SpecialCard
title="Contributions"
subtitle="Thank you for contributing!"
description="Since you've contributed to Vencord you now have a cool new badge!"
cardImage={COZY_CONTRIB_IMAGE}
backgroundImage={CONTRIB_BACKGROUND_IMAGE}
backgroundColor="#EDCC87"
buttonTitle="See what you've contributed to"
buttonOnClick={() => openContributorModal(user)}
/>
)}
<DonateCard image={donateImage} />
<Forms.FormSection title="Quick Actions">
<QuickActionCard>
<QuickAction
@ -287,19 +239,31 @@ function VencordSettings() {
);
}
function DonateButtonComponent() {
interface DonateCardProps {
image: string;
}
function DonateCard({ image }: DonateCardProps) {
return (
<DonateButton
look={Button.Looks.FILLED}
color={Button.Colors.WHITE}
style={{ marginTop: "1em" }}
/>
<Card className={cl("card", "donate")}>
<div>
<Forms.FormTitle tag="h5">Support the Project</Forms.FormTitle>
<Forms.FormText>Please consider supporting the development of Vencord by donating!</Forms.FormText>
<DonateButton style={{ transform: "translateX(-1em)" }} />
</div>
<img
role="presentation"
src={image}
alt=""
height={128}
style={{
imageRendering: image === SHIGGY_DONATE_IMAGE ? "pixelated" : void 0,
marginLeft: "auto",
transform: image === DEFAULT_DONATE_IMAGE ? "rotate(10deg)" : void 0
}}
/>
</Card>
);
}
function isDonor(userId: string): boolean {
const donorBadges = BadgeAPI.getDonorBadges(userId);
return GuildMemberStore.getMember(VENCORD_GUILD_ID, userId)?.roles.includes(DONOR_ROLE_ID) || !!donorBadges;
}
export default wrapTab(VencordSettings, "Vencord Settings");

View file

@ -1,17 +1,12 @@
.vc-settings-quickActions-card {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(auto-fill, minmax(200px, max-content));
gap: 0.5em;
padding: 0.5em;
justify-content: center;
padding: 0.5em 0;
margin-bottom: 1em;
}
@media (width <=1040px) {
.vc-settings-quickActions-card {
grid-template-columns: repeat(2, 1fr);
}
}
.vc-settings-quickActions-pill {
all: unset;
background: var(--background-secondary);
@ -19,16 +14,12 @@
display: flex;
align-items: center;
gap: 0.5em;
padding: 8px 9px;
border-radius: 8px;
transition: 0.1s ease-out;
box-sizing: border-box;
padding: 8px 12px;
border-radius: 9999px;
}
.vc-settings-quickActions-pill:hover {
background: var(--background-secondary-alt);
transform: translateY(-1px);
box-shadow: var(--elevation-high);
}
.vc-settings-quickActions-pill:focus-visible {
@ -39,4 +30,4 @@
.vc-settings-quickActions-img {
width: 24px;
height: 24px;
}
}

View file

@ -1,92 +0,0 @@
.vc-donate-button {
overflow: visible !important;
}
.vc-donate-button .vc-heart-icon {
transition: transform 0.3s;
}
.vc-donate-button:hover .vc-heart-icon {
transform: scale(1.1);
z-index: 10;
position: relative;
}
.vc-settings-card {
padding: 1em;
margin-bottom: 1em;
}
.vc-special-card-special {
padding: 1em 1.5em;
margin-bottom: 1em;
background-size: cover;
background-position: center;
}
.vc-special-card-flex {
display: flex;
flex-direction: row;
}
.vc-special-card-flex-main {
width: 100%;
}
.vc-special-title {
color: black;
}
.vc-special-subtitle {
color: black;
font-size: 1.2em;
font-weight: bold;
margin-top: 0.5em;
}
.vc-special-text {
color: black;
font-size: 1em;
margin-top: .75em;
white-space: pre-line;
}
.vc-special-seperator {
margin-top: .75em;
border-top: 1px solid white;
opacity: 0.4;
}
.vc-special-hyperlink {
margin-top: 1em;
cursor: pointer;
.vc-special-hyperlink-text {
color: black;
font-size: 1em;
font-weight: bold;
text-align: center;
transition: text-decoration 0.5s;
cursor: pointer;
}
&:hover .vc-special-hyperlink-text {
text-decoration: underline;
}
}
.vc-special-image-container {
display: flex;
justify-content: center;
align-items: center;
margin-left: 1em;
flex-shrink: 0;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: white;
}
.vc-special-image {
width: 65%;
}

View file

@ -5,8 +5,3 @@
.vc-owner-crown-icon {
color: var(--text-warning);
}
.vc-heart-icon {
margin-right: 0.5em;
translate: 0 2px;
}

View file

@ -10,6 +10,7 @@ export * from "./CodeBlock";
export * from "./DonateButton";
export { default as ErrorBoundary } from "./ErrorBoundary";
export * from "./ErrorCard";
export * from "./ExpandableHeader";
export * from "./Flex";
export * from "./Heart";
export * from "./Icons";

View file

@ -8,7 +8,7 @@ import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches";
import * as Webpack from "@webpack";
import { wreq } from "@webpack";
import { AnyModuleFactory, ModuleFactory } from "@webpack/wreq.d";
import { AnyModuleFactory, ModuleFactory } from "webpack";
export async function loadLazyChunks() {
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
@ -16,36 +16,24 @@ export async function loadLazyChunks() {
try {
LazyChunkLoaderLogger.log("Loading all chunks...");
const validChunks = new Set<PropertyKey>();
const invalidChunks = new Set<PropertyKey>();
const deferredRequires = new Set<PropertyKey>();
const validChunks = new Set<number>();
const invalidChunks = new Set<number>();
const deferredRequires = new Set<number>();
const { promise: chunksSearchingDone, resolve: chunksSearchingResolve } = Promise.withResolvers<void>();
let chunksSearchingResolve: (value: void | PromiseLike<void>) => void;
const chunksSearchingDone = new Promise<void>(r => chunksSearchingResolve = r);
// True if resolved, false otherwise
const chunksSearchPromises = [] as Array<() => boolean>;
/* This regex loads all language packs which makes webpack finds testing extremely slow, so for now, lets use one which doesnt include those
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g);
*/
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
let foundCssDebuggingLoad = false;
async function searchAndLoadLazyChunks(factoryCode: string) {
// Workaround to avoid loading the CSS debugging chunk which turns the app pink
const hasCssDebuggingLoad = foundCssDebuggingLoad ? false : (foundCssDebuggingLoad = factoryCode.includes(".cssDebuggingEnabled&&"));
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
const validChunkGroups = new Set<[chunkIds: PropertyKey[], entryPoint: PropertyKey]>();
const shouldForceDefer = false;
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => {
const numChunkId = Number(m[1]);
return Number.isNaN(numChunkId) ? m[1] : numChunkId;
}) : [];
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : [];
if (chunkIds.length === 0) {
return;
@ -54,21 +42,11 @@ export async function loadLazyChunks() {
let invalidChunkGroup = false;
for (const id of chunkIds) {
if (hasCssDebuggingLoad) {
if (chunkIds.length > 1) {
throw new Error("Found multiple chunks in factory that loads the CSS debugging chunk");
}
invalidChunks.add(id);
invalidChunkGroup = true;
break;
}
if (wreq.u(id) == null || wreq.u(id) === "undefined.js") continue;
const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
.then(r => r.text())
.then(t => /importScripts\(|self\.postMessage/.test(t));
.then(t => t.includes("importScripts("));
if (isWorkerAsset) {
invalidChunks.add(id);
@ -80,8 +58,7 @@ export async function loadLazyChunks() {
}
if (!invalidChunkGroup) {
const numEntryPoint = Number(entryPoint);
validChunkGroups.add([chunkIds, Number.isNaN(numEntryPoint) ? entryPoint : numEntryPoint]);
validChunkGroups.add([chunkIds, Number(entryPoint)]);
}
}));
@ -96,11 +73,6 @@ export async function loadLazyChunks() {
// Requires the entry points for all valid chunk groups
for (const [, entryPoint] of validChunkGroups) {
try {
if (shouldForceDefer) {
deferredRequires.add(entryPoint);
continue;
}
if (wreq.m[entryPoint]) wreq(entryPoint);
} catch (err) {
console.error(err);
@ -139,8 +111,8 @@ export async function loadLazyChunks() {
}
Webpack.factoryListeners.add(factoryListener);
for (const moduleId in wreq.m) {
factoryListener(wreq.m[moduleId]);
for (const factoryId in wreq.m) {
factoryListener(wreq.m[factoryId]);
}
await chunksSearchingDone;
@ -152,15 +124,14 @@ export async function loadLazyChunks() {
}
// All chunks Discord has mapped to asset files, even if they are not used anymore
const allChunks = [] as PropertyKey[];
const allChunks = [] as number[];
// Matches "id" or id:
for (const currentMatch of String(wreq.u).matchAll(/(?:"([\deE]+?)"(?![,}]))|(?:([\deE]+?):)/g)) {
const id = currentMatch[1] ?? currentMatch[2];
if (id == null) continue;
const numId = Number(id);
allChunks.push(Number.isNaN(numId) ? id : numId);
allChunks.push(Number(id));
}
if (allChunks.length === 0) throw new Error("Failed to get all chunks");
@ -174,7 +145,7 @@ export async function loadLazyChunks() {
await Promise.all(chunksLeft.map(async id => {
const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
.then(r => r.text())
.then(t => /importScripts\(|self\.postMessage/.test(t));
.then(t => t.includes("importScripts("));
// Loads the chunk. Currently this only happens with the language packs which are loaded differently
if (!isWorkerAsset) {

View file

@ -4,11 +4,12 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact";
import { Logger } from "@utils/Logger";
import { SYM_PROXY_INNER_GET, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
import * as Webpack from "@webpack";
import { getBuildNumber, patchTimings } from "@webpack/patcher";
import { addPatch, patches } from "plugins";
import { addPatch, patches } from "../plugins";
import { loadLazyChunks } from "./loadLazyChunks";
async function runReporter() {
@ -17,7 +18,8 @@ async function runReporter() {
try {
ReporterLogger.log("Starting test...");
const { promise: loadLazyChunksDone, resolve: loadLazyChunksResolve } = Promise.withResolvers<void>();
let loadLazyChunksResolve: (value: void) => void;
const loadLazyChunksDone = new Promise<void>(r => loadLazyChunksResolve = r);
// The main patch for starting the reporter chunk loading
addPatch({
@ -37,78 +39,164 @@ async function runReporter() {
await loadLazyChunksDone;
if (IS_REPORTER && IS_WEB && !IS_VESKTOP) {
console.log("[REPORTER_META]", {
buildNumber: getBuildNumber(),
buildHash: window.GLOBAL_ENV.SENTRY_TAGS.buildId
});
}
for (const patch of patches) {
if (!patch.all) {
new Logger("WebpackInterceptor").warn(`Patch by ${patch.plugin} found no module (Module id is -): ${patch.find}`);
}
}
for (const [plugin, moduleId, match, totalTime] of patchTimings) {
if (totalTime > 5) {
new Logger("WebpackInterceptor").warn(`Patch by ${plugin} took ${Math.round(totalTime * 100) / 100}ms (Module id is ${String(moduleId)}): ${match}`);
for (const [plugin, moduleId, match, totalTime] of Vencord.WebpackPatcher.patchTimings) {
if (totalTime > 3) {
new Logger("WebpackInterceptor").warn(`Patch by ${plugin} took ${totalTime}ms (Module id is ${String(moduleId)}): ${match}`);
}
}
for (const [searchType, args] of Webpack.lazyWebpackSearchHistory) {
let method = searchType;
await Promise.all(Webpack.webpackSearchHistory.map(async ([searchType, args]) => {
args = [...args];
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;
let result = null as any;
try {
if (method === "proxyLazyWebpack" || method === "LazyComponentWebpack") {
const [factory] = args;
result = factory();
} else if (method === "extractAndLoadChunks") {
const [code, matcher] = args;
switch (searchType) {
case "webpackDependantLazy":
case "webpackDependantLazyComponent": {
const [factory] = args;
result = factory();
break;
}
case "extractAndLoadChunks": {
const extractAndLoadChunks = args.shift();
result = await Webpack.extractAndLoadChunks(code, matcher);
if (result === false) result = null;
} else if (method === "mapMangledModule") {
const [code, mapper, includeBlacklistedExports] = args;
result = await extractAndLoadChunks();
if (result === false) {
result = null;
}
result = Webpack.mapMangledModule(code, mapper, includeBlacklistedExports);
if (Object.keys(result).length !== Object.keys(mapper).length) throw new Error("Webpack Find Fail");
} else {
// @ts-ignore
result = Webpack[method](...args);
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 || (result.$$vencordInternal != null && result.$$vencordInternal() == null)) throw new Error("Webpack Find Fail");
if (result == null) {
throw new Error("Webpack Find Fail");
}
} catch (e) {
let logMessage = searchType;
if (method === "find" || method === "proxyLazyWebpack" || method === "LazyComponentWebpack") {
if (args[0].$$vencordProps != null) {
logMessage += `(${args[0].$$vencordProps.map(arg => `"${arg}"`).join(", ")})`;
} else {
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 += `(${args.map(arg => `"${arg}"`).join(", ")})`;
logMessage += `(${filterName.length ? `${filterName}(` : ""}${parsedArgs.map(stringifyFilter).join(", ")})${filterName.length ? ")" : ""}`;
}
ReporterLogger.log("Webpack Find Fail:", logMessage);
}
}
}));
ReporterLogger.log("Finished test");
} catch (e) {
@ -116,6 +204,5 @@ async function runReporter() {
}
}
// Run after the Vencord object has been created.
// We need to add extra properties to it, and it is only created after all of Vencord code has ran
// Run after the Vencord object has been created
setTimeout(runReporter, 0);

View file

@ -71,16 +71,13 @@ export async function installExt(id: string) {
// React Devtools v4.25
// v4.27 is broken in Electron, see https://github.com/facebook/react/issues/25843
// Unfortunately, Google does not serve old versions, so this is the only way
// This zip file is pinned to long commit hash so it cannot be changed remotely
? "https://raw.githubusercontent.com/Vendicated/random-files/f6f550e4c58ac5f2012095a130406c2ab25b984d/fmkadmapgofadopljbjfkapdkoienihi.zip"
: `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${id}%26uc&prodversion=${process.versions.chrome}`;
: `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${id}%26uc&prodversion=32`;
const buf = await get(url, {
headers: {
"User-Agent": `Electron ${process.versions.electron} ~ Vencord (https://github.com/Vendicated/Vencord)`
"User-Agent": "Vencord (https://github.com/Vendicated/Vencord)"
}
});
await extract(crxToZip(buf), extDir).catch(console.error);
}

View file

@ -0,0 +1,3 @@
[class*="profileBadges"] {
flex: none;
}

View file

@ -1,5 +0,0 @@
/* the profile popout badge container(s) */
[class*="biteSize_"] [class*="tags_"] [class*="container_"] {
/* Discord has padding set to 2px instead of 1px, which causes the 12th badge to wrap to a new line. */
padding: 0 1px;
}

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import "./fixDiscordBadgePadding.css";
import "./fixBadgeOverflow.css";
import { _getBadges, BadgePosition, BadgeUserArgs, ProfileBadge } from "@api/Badges";
import DonateButton from "@components/DonateButton";
@ -28,7 +28,7 @@ import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { isPluginDev } from "@utils/misc";
import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
import { closeModal, Modals, openModal } from "@utils/modal";
import definePlugin from "@utils/types";
import { Forms, Toasts, UserStore } from "@webpack/common";
import { User } from "discord-types/general";
@ -79,7 +79,7 @@ export default definePlugin({
replace: "...$1.props,$& $1.image??"
},
{
match: /(?<="aria-label":(\i)\.description,.{0,200})children:/,
match: /(?<=text:(\i)\.description,.{0,50})children:/,
replace: "children:$1.component ? $self.renderBadgeComponent({ ...$1 }) :"
},
// conditionally override their onClick with badge.onClick if it exists
@ -102,9 +102,8 @@ export default definePlugin({
}
},
userProfileBadge: ContributorBadge,
async start() {
Vencord.Api.Badges.addBadge(ContributorBadge);
await loadBadges();
},
@ -144,8 +143,8 @@ export default definePlugin({
closeModal(modalKey);
VencordNative.native.openExternal("https://github.com/sponsors/Vendicated");
}}>
<ModalRoot {...props}>
<ModalHeader>
<Modals.ModalRoot {...props}>
<Modals.ModalHeader>
<Flex style={{ width: "100%", justifyContent: "center" }}>
<Forms.FormTitle
tag="h2"
@ -159,8 +158,8 @@ export default definePlugin({
Vencord Donor
</Forms.FormTitle>
</Flex>
</ModalHeader>
<ModalContent>
</Modals.ModalHeader>
<Modals.ModalContent>
<Flex>
<img
role="presentation"
@ -183,13 +182,13 @@ export default definePlugin({
Please consider supporting the development of Vencord by becoming a donor. It would mean a lot!!
</Forms.FormText>
</div>
</ModalContent>
<ModalFooter>
</Modals.ModalContent>
<Modals.ModalFooter>
<Flex style={{ width: "100%", justifyContent: "center" }}>
<DonateButton />
</Flex>
</ModalFooter>
</ModalRoot>
</Modals.ModalFooter>
</Modals.ModalRoot>
</ErrorBoundary>
));
},

View file

@ -12,16 +12,11 @@ export default definePlugin({
description: "API to add buttons to the chat input",
authors: [Devs.Ven],
patches: [
{
find: '"sticker")',
replacement: {
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(\i\.isDM.+?(\i)\.push)/,
replace: (m, not, children) => not
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
: `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),false)||`
}
patches: [{
find: '"sticker")',
replacement: {
match: /return\(!\i\.\i&&(?=\(\i\.isDM.+?(\i)\.push\(.{0,50}"gift")/,
replace: "$&(Vencord.Api.ChatButtons._injectButtons($1,arguments[0]),true)&&"
}
]
}]
});

View file

@ -34,22 +34,12 @@ export default definePlugin({
}
},
{
find: "navId:",
find: ".Menu,{",
all: true,
noWarn: true,
replacement: [
{
match: /navId:(?=.+?([,}].*?\)))/g,
replace: (m, rest) => {
// Check if this navId: match is a destructuring statement, ignore it if it is
const destructuringMatch = rest.match(/}=.+/);
if (destructuringMatch == null) {
return `contextMenuAPIArguments:typeof arguments!=='undefined'?arguments:[],${m}`;
}
return m;
}
}
]
replacement: {
match: /Menu,{(?<=\.jsxs?\)\(\i\.Menu,{)/g,
replace: "$&contextMenuApiArguments:typeof arguments!=='undefined'?arguments:[],"
}
}
]
});

View file

@ -19,15 +19,10 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import managedStyle from "./style.css?managed";
export default definePlugin({
name: "MemberListDecoratorsAPI",
description: "API to add decorators to member list (both in servers and DMs)",
authors: [Devs.TheSun, Devs.Ven],
managedStyle,
patches: [
{
find: ".lostPermission)",
@ -36,8 +31,8 @@ export default definePlugin({
match: /let\{[^}]*lostPermissionTooltipText:\i[^}]*\}=(\i),/,
replace: "$&vencordProps=$1,"
}, {
match: /#{intl::GUILD_OWNER}(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
replace: "$&(typeof vencordProps=='undefined'?null:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
match: /\.Messages\.GUILD_OWNER(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
}
]
},
@ -45,8 +40,8 @@ export default definePlugin({
find: "PrivateChannel.renderAvatar",
replacement: {
match: /decorators:(\i\.isSystemDM\(\))\?(.+?):null/,
replace: "decorators:[Vencord.Api.MemberListDecorators.__getDecorators(arguments[0]),$1?$2:null]"
replace: "decorators:[...Vencord.Api.MemberListDecorators.__getDecorators(arguments[0]), $1?$2:null]"
}
}
]
],
});

View file

@ -1,11 +0,0 @@
.vc-member-list-decorators-wrapper {
display: flex;
align-items: center;
justify-content: center;
gap: 0.25em;
}
.vc-member-list-decorators-wrapper:not(:empty) {
/* Margin to match default Discord decorators */
margin-left: 0.25em;
}

View file

@ -1,68 +0,0 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Devs } from "@utils/constants";
import { canonicalizeMatch } from "@utils/patches";
import definePlugin from "@utils/types";
// duplicate values have multiple branches with different types. Just include all to be safe
const nameMap = {
radio: "MenuRadioItem",
separator: "MenuSeparator",
checkbox: "MenuCheckboxItem",
groupstart: "MenuGroup",
control: "MenuControlItem",
compositecontrol: "MenuControlItem",
item: "MenuItem",
customitem: "MenuItem",
};
export default definePlugin({
name: "MenuItemDemanglerAPI",
description: "Demangles Discord's Menu Item module",
authors: [Devs.Ven],
required: true,
patches: [
{
find: '"Menu API',
replacement: {
match: /function.{0,80}type===(\i\.\i)\).{0,50}navigable:.+?Menu API/s,
replace: (m, mod) => {
const nameAssignments = [] as string[];
// if (t.type === m.MenuItem)
const typeCheckRe = canonicalizeMatch(/\(\i\.type===(\i\.\i)\)/g);
// push({type:"item"})
const pushTypeRe = /type:"(\w+)"/g;
let typeMatch: RegExpExecArray | null;
// for each if (t.type === ...)
while ((typeMatch = typeCheckRe.exec(m)) !== null) {
// extract the current menu item
const item = typeMatch[1];
// Set the starting index of the second regex to that of the first to start
// matching from after the if
pushTypeRe.lastIndex = typeCheckRe.lastIndex;
// extract the first type: "..."
const type = pushTypeRe.exec(m)?.[1];
if (type && type in nameMap) {
const name = nameMap[type];
nameAssignments.push(`Object.defineProperty(${item},"name",{value:"${name}"})`);
}
}
if (nameAssignments.length < 6) {
console.warn("[MenuItemDemanglerAPI] Expected to at least remap 6 items, only remapped", nameAssignments.length);
}
// Merge all our redefines with the actual module
return `${nameAssignments.join(";")};${m}`;
},
},
},
],
});

View file

@ -25,7 +25,7 @@ export default definePlugin({
authors: [Devs.Cyn],
patches: [
{
find: "#{intl::REMOVE_ATTACHMENT_BODY}",
find: ".Messages.REMOVE_ATTACHMENT_BODY",
replacement: {
match: /(?<=.container\)?,children:)(\[.+?\])/,
replace: "Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)",

View file

@ -19,22 +19,17 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import managedStyle from "./style.css?managed";
export default definePlugin({
name: "MessageDecorationsAPI",
description: "API to add decorations to messages",
authors: [Devs.TheSun],
managedStyle,
patches: [
{
find: '"Message Username"',
replacement: {
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?}\),\i(?=\])/,
replace: "$&,Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
match: /\.Messages\.GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE.+?}\),\i(?=\])/,
replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
}
}
]
],
});

View file

@ -1,18 +0,0 @@
.vc-message-decorations-wrapper {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.25em;
}
.vc-message-decorations-wrapper:not(:empty) {
/* Margin to match default Discord decorators */
margin-left: 0.25em;
/* Align vertically */
position: relative;
vertical-align: top;
top: 0.1rem;
height: calc(1rem + 4px);
max-height: calc(1rem + 4px)
}

View file

@ -25,23 +25,26 @@ export default definePlugin({
authors: [Devs.Arjix, Devs.hunt, Devs.Ven],
patches: [
{
find: "#{intl::EDIT_TEXTAREA_HELP}",
find: ".Messages.EDIT_TEXTAREA_HELP",
replacement: {
match: /(?<=,channel:\i\}\)\.then\().+?(?=return \i\.content!==this\.props\.message\.content&&\i\((.+?)\))/,
replace: (match, args) => "" +
`async ${match}` +
`if(await Vencord.Api.MessageEvents._handlePreEdit(${args}))` +
"return Promise.resolve({shouldClear:false,shouldRefocus:true});"
"return Promise.resolve({shoudClear:true,shouldRefocus:true});"
}
},
{
find: ".handleSendMessage,onResize",
replacement: {
// https://regex101.com/r/hBlXpl/1
match: /let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);(?<=\)\(({.+?})\)\.then.+?)/,
replace: (m, parsedMessage, channel, replyOptions, extra) => m +
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply);
// Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid)
match: /(type:this\.props\.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptionsForReply\(\i\);)(?<=\)\(({.+?})\)\.then.+?)/,
// props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true };
replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
`${rest1}async ${rest2}` +
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
"return{shouldClear:false,shouldRefocus:true};"
"return{shoudClear:true,shouldRefocus:true};"
}
},
{
@ -49,7 +52,8 @@ export default definePlugin({
replacement: {
match: /let\{id:\i}=(\i),{id:\i}=(\i);return \i\.useCallback\((\i)=>\{/,
replace: (m, message, channel, event) =>
`const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg,vcChan,${event});`
// the message param is shadowed by the event param, so need to alias them
`const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg, vcChan, ${event});`
}
}
]

View file

@ -23,14 +23,11 @@ export default definePlugin({
name: "MessagePopoverAPI",
description: "API to add buttons to message popovers.",
authors: [Devs.KingFish, Devs.Ven, Devs.Nuckyz],
patches: [
{
find: "#{intl::MESSAGE_UTILITIES_A11Y_LABEL}",
replacement: {
match: /(?<=:null),(.{0,40}togglePopout:.+?}\)),(.+?)\]}\):null,(?<=\((\i\.\i),{label:.+?:null,(\i&&!\i)\?\(0,\i\.jsxs?\)\(\i\.Fragment.+?message:(\i).+?)/,
replace: (_, ReactButton, PotionButton, ButtonComponent, showReactButton, message) => "" +
`]}):null,Vencord.Api.MessagePopover._buildPopoverElements(${ButtonComponent},${message}),${showReactButton}?${ReactButton}:null,${showReactButton}&&${PotionButton},`
}
patches: [{
find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
replacement: {
match: /\.jsx\)\((\i\.\i),\{label:\i\.\i\.Messages\.MESSAGE_ACTION_REPLY.{0,200}?"reply-self".{0,50}?\}\):null(?=,.+?message:(\i))/,
replace: "$&,Vencord.Api.MessagePopover._buildPopoverElements($1,$2)"
}
]
}],
});

View file

@ -34,7 +34,7 @@ export default definePlugin({
},
{
match: /(?<=,NOTICE_DISMISS:function\(\i\){)return null!=(\i)/,
replace: "if($1?.id==\"VencordNotice\")return($1=null,Vencord.Api.Notices.nextNotice(),true);$&"
replace: "if($1.id==\"VencordNotice\")return($1=null,Vencord.Api.Notices.nextNotice(),true);$&"
}
]
}

View file

@ -25,16 +25,16 @@ export default definePlugin({
description: "Api required for plugins that modify the server list",
patches: [
{
find: "#{intl::DISCODO_DISABLED}",
find: "Messages.DISCODO_DISABLED",
replacement: {
match: /(?<=#{intl::DISCODO_DISABLED}.+?return)(\(.{0,75}?tutorialContainer.+?}\))(?=}function)/,
match: /(?<=Messages\.DISCODO_DISABLED.+?return)(\(.{0,75}?tutorialContainer.+?}\))(?=}function)/,
replace: "[$1].concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Above))"
}
},
{
find: "#{intl::SERVERS}),children",
find: "Messages.SERVERS,children",
replacement: {
match: /(?<=#{intl::SERVERS}\),children:)\i\.map\(\i\)/,
match: /(?<=Messages\.SERVERS,children:).+?default:return null\}\}\)/,
replace: "Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($&)"
}
}

View file

@ -20,7 +20,7 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { WebpackRequire } from "@webpack/wreq.d";
import { WebpackRequire } from "webpack";
const settings = definePluginSettings({
disableAnalytics: {
@ -49,7 +49,7 @@ export default definePlugin({
},
},
{
find: ".METRICS",
find: ".METRICS,",
replacement: [
{
match: /this\._intervalId=/,
@ -62,13 +62,13 @@ export default definePlugin({
]
},
{
find: ".BetterDiscord||null!=",
find: ".installedLogHooks)",
replacement: {
// Make hasClientMods return false
match: /(?=let \i=window;)/,
replace: "return false;"
// if getDebugLogging() returns false, the hooks don't get installed.
match: "getDebugLogging(){",
replace: "getDebugLogging(){return false;"
}
}
},
],
startAt: StartAt.Init,

View file

@ -16,7 +16,7 @@
* 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 CloudTab from "@components/VencordSettings/CloudTab";
import PatchHelperTab from "@components/VencordSettings/PatchHelperTab";
@ -25,20 +25,35 @@ import ThemesTab from "@components/VencordSettings/ThemesTab";
import UpdaterTab from "@components/VencordSettings/UpdaterTab";
import VencordTab from "@components/VencordSettings/VencordTab";
import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
import { React } from "@webpack/common";
import { i18n, React } from "@webpack/common";
import gitHash from "~git-hash";
type SectionType = "HEADER" | "DIVIDER" | "CUSTOM";
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({
name: "Settings",
description: "Adds Settings UI and debug info",
authors: [Devs.Ven, Devs.Megu],
required: true,
settings,
patches: [
{
@ -58,21 +73,20 @@ export default definePlugin({
]
},
{
find: ".SEARCH_NO_RESULTS&&0===",
find: "Messages.ACTIVITY_SETTINGS",
replacement: [
{
match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/,
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
},
{
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /({(?=.+?function (\i).{0,160}(\i)=\i\.useMemo.{0,140}return \i\.useMemo\(\(\)=>\i\(\3).+?(?:function\(\){return |\(\)=>))\2/,
match: /({(?=.+?function (\i).{0,120}(\i)=\i\.useMemo.{0,30}return \i\.useMemo\(\(\)=>\i\(\3).+?function\(\){return )\2(?=})/,
replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
}
]
},
{
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
replacement: {
match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.\i\).*?(\i\.\i)\.open\()/,
replace: "$2.open($1);return;"
@ -138,33 +152,25 @@ export default definePlugin({
].filter(Boolean);
},
isRightSpot({ header, settings }: { header?: string; settings?: string[]; }) {
const firstChild = settings?.[0];
isRightSpot({ header, settingsChilds }: { header?: string; settingsChilds?: string[]; }) {
const firstChild = settingsChilds?.[0];
// lowest two elements... sanity backup
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 === "belowActivity") return firstChild === "CHANGELOG";
if (!header) return;
try {
const names = {
top: getIntlMessage("USER_SETTINGS"),
aboveNitro: getIntlMessage("BILLING_SETTINGS"),
belowNitro: getIntlMessage("APP_SETTINGS"),
aboveActivity: getIntlMessage("ACTIVITY_SETTINGS")
};
if (!names[settingsLocation] || names[settingsLocation].endsWith("_SETTINGS"))
return firstChild === "PREMIUM";
return header === names[settingsLocation];
} catch {
return firstChild === "PREMIUM";
}
const names = {
top: i18n.Messages.USER_SETTINGS,
aboveNitro: i18n.Messages.BILLING_SETTINGS,
belowNitro: i18n.Messages.APP_SETTINGS,
aboveActivity: i18n.Messages.ACTIVITY_SETTINGS
};
return header === names[settingsLocation];
},
patchedSettings: new WeakSet(),
@ -191,23 +197,8 @@ 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() {
return VencordNative.native.getVersions().electron || window.legcord?.electron || null;
return VencordNative.native.getVersions().electron || window.armcord?.electron || null;
},
get chromiumVersion() {

View file

@ -16,13 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { addAccessory } from "@api/MessageAccessories";
import { definePluginSettings } from "@api/Settings";
import { getUserSettingLazy } from "@api/UserSettings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
import { Link } from "@components/Link";
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, KNOWN_ISSUES_CHANNEL_ID, REGULAR_ROLE_ID, SUPPORT_CHANNEL_ID, VENBOT_USER_ID, VENCORD_GUILD_ID } from "@utils/constants";
import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants";
import { sendMessage } from "@utils/discord";
import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
@ -33,13 +34,15 @@ import { makeCodeblock } from "@utils/text";
import definePlugin from "@utils/types";
import { checkForUpdates, isOutdated, update } from "@utils/updater";
import { Alerts, Button, Card, ChannelStore, Forms, GuildMemberStore, Parser, RelationshipStore, showToast, Text, Toasts, UserStore } from "@webpack/common";
import { JSX } from "react";
import gitHash from "~git-hash";
import plugins, { PluginMeta } from "~plugins";
import SettingsPlugin from "./settings";
const VENCORD_GUILD_ID = "1015060230222131221";
const VENBOT_USER_ID = "1017176847865352332";
const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
const CodeBlockRe = /```js\n(.+?)```/s;
const AllowedChannelIds = [
@ -49,14 +52,14 @@ const AllowedChannelIds = [
];
const TrustedRolesIds = [
CONTRIB_ROLE_ID, // contributor
REGULAR_ROLE_ID, // regular
DONOR_ROLE_ID, // donor
"1026534353167208489", // contributor
"1026504932959977532", // regular
"1042507929485586532", // donor
];
const AsyncFunction = async function () { }.constructor;
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame");
async function forceUpdate() {
const outdated = await checkForUpdates();
@ -74,7 +77,7 @@ async function generateDebugInfoMessage() {
const client = (() => {
if (IS_DISCORD_DESKTOP) return `Discord Desktop v${DiscordNative.app.getVersion()}`;
if (IS_VESKTOP) return `Vesktop v${VesktopNative.app.getVersion()}`;
if ("legcord" in window) return `Legcord v${window.legcord.version}`;
if ("armcord" in window) return `ArmCord v${window.armcord.version}`;
// @ts-expect-error
const name = typeof unsafeWindow !== "undefined" ? "UserScript" : "Web";
@ -139,15 +142,15 @@ export default definePlugin({
required: true,
description: "Helps us provide support to you",
authors: [Devs.Ven],
dependencies: ["UserSettingsAPI"],
dependencies: ["CommandsAPI", "UserSettingsAPI", "MessageAccessoriesAPI"],
settings,
patches: [{
find: "#{intl::BEGINNING_DM}",
find: ".BEGINNING_DM.format",
replacement: {
match: /#{intl::BEGINNING_DM},{.+?}\),(?=.{0,300}(\i)\.isMultiUserDM)/,
replace: "$& $self.renderContributorDmWarningCard({ channel: $1 }),"
match: /BEGINNING_DM\.format\(\{.+?\}\),(?=.{0,100}userId:(\i\.getRecipientId\(\)))/,
replace: "$& $self.ContributorDmWarningCard({ userId: $1 }),"
}
}],
@ -232,87 +235,7 @@ export default definePlugin({
}
},
renderMessageAccessory(props) {
const buttons = [] as JSX.Element[];
const shouldAddUpdateButton =
!IS_UPDATER_DISABLED
&& (
(props.channel.id === KNOWN_ISSUES_CHANNEL_ID) ||
(props.channel.id === SUPPORT_CHANNEL_ID && props.message.author.id === VENBOT_USER_ID)
)
&& props.message.content?.includes("update");
if (shouldAddUpdateButton) {
buttons.push(
<Button
key="vc-update"
color={Button.Colors.GREEN}
onClick={async () => {
try {
if (await forceUpdate())
showToast("Success! Restarting...", Toasts.Type.SUCCESS);
else
showToast("Already up to date!", Toasts.Type.MESSAGE);
} catch (e) {
new Logger(this.name).error("Error while updating:", e);
showToast("Failed to update :(", Toasts.Type.FAILURE);
}
}}
>
Update Now
</Button>
);
}
if (props.channel.id === SUPPORT_CHANNEL_ID) {
if (props.message.content.includes("/vencord-debug") || props.message.content.includes("/vencord-plugins")) {
buttons.push(
<Button
key="vc-dbg"
onClick={async () => sendMessage(props.channel.id, { content: await generateDebugInfoMessage() })}
>
Run /vencord-debug
</Button>,
<Button
key="vc-plg-list"
onClick={async () => sendMessage(props.channel.id, { content: generatePluginList() })}
>
Run /vencord-plugins
</Button>
);
}
if (props.message.author.id === VENBOT_USER_ID) {
const match = CodeBlockRe.exec(props.message.content || props.message.embeds[0]?.rawDescription || "");
if (match) {
buttons.push(
<Button
key="vc-run-snippet"
onClick={async () => {
try {
await AsyncFunction(match[1])();
showToast("Success!", Toasts.Type.SUCCESS);
} catch (e) {
new Logger(this.name).error("Error while running snippet:", e);
showToast("Failed to run snippet :(", Toasts.Type.FAILURE);
}
}}
>
Run Snippet
</Button>
);
}
}
}
return buttons.length
? <Flex>{buttons}</Flex>
: null;
},
renderContributorDmWarningCard: ErrorBoundary.wrap(({ channel }) => {
const userId = channel.getRecipientId();
ContributorDmWarningCard: ErrorBoundary.wrap(({ userId }) => {
if (!isPluginDev(userId)) return null;
if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id)) return null;
@ -325,4 +248,85 @@ export default definePlugin({
</Card>
);
}, { noop: true }),
start() {
addAccessory("vencord-debug", props => {
const buttons = [] as JSX.Element[];
const shouldAddUpdateButton =
!IS_UPDATER_DISABLED
&& (
(props.channel.id === KNOWN_ISSUES_CHANNEL_ID) ||
(props.channel.id === SUPPORT_CHANNEL_ID && props.message.author.id === VENBOT_USER_ID)
)
&& props.message.content?.includes("update");
if (shouldAddUpdateButton) {
buttons.push(
<Button
key="vc-update"
color={Button.Colors.GREEN}
onClick={async () => {
try {
if (await forceUpdate())
showToast("Success! Restarting...", Toasts.Type.SUCCESS);
else
showToast("Already up to date!", Toasts.Type.MESSAGE);
} catch (e) {
new Logger(this.name).error("Error while updating:", e);
showToast("Failed to update :(", Toasts.Type.FAILURE);
}
}}
>
Update Now
</Button>
);
}
if (props.channel.id === SUPPORT_CHANNEL_ID) {
if (props.message.content.includes("/vencord-debug") || props.message.content.includes("/vencord-plugins")) {
buttons.push(
<Button
key="vc-dbg"
onClick={async () => sendMessage(props.channel.id, { content: await generateDebugInfoMessage() })}
>
Run /vencord-debug
</Button>,
<Button
key="vc-plg-list"
onClick={async () => sendMessage(props.channel.id, { content: generatePluginList() })}
>
Run /vencord-plugins
</Button>
);
}
if (props.message.author.id === VENBOT_USER_ID) {
const match = CodeBlockRe.exec(props.message.content || props.message.embeds[0]?.rawDescription || "");
if (match) {
buttons.push(
<Button
key="vc-run-snippet"
onClick={async () => {
try {
await AsyncFunction(match[1])();
showToast("Success!", Toasts.Type.SUCCESS);
} catch (e) {
new Logger(this.name).error("Error while running snippet:", e);
showToast("Failed to run snippet :(", Toasts.Type.FAILURE);
}
}}
>
Run Snippet
</Button>
);
}
}
}
return buttons.length
? <Flex>{buttons}</Flex>
: null;
});
},
});

View file

@ -1,7 +0,0 @@
# AccountPanelServerProfile
Right click your account panel in the bottom left to view your profile in the current server
![](https://github.com/user-attachments/assets/3228497d-488f-479c-93d2-a32ccdb08f0f)
![](https://github.com/user-attachments/assets/6fc45363-d95f-4810-812f-2f9fb28b41b5)

View file

@ -1,134 +0,0 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { ContextMenuApi, Menu, useEffect, useRef } from "@webpack/common";
import { User } from "discord-types/general";
interface UserProfileProps {
popoutProps: Record<string, any>;
currentUser: User;
originalRenderPopout: () => React.ReactNode;
}
const UserProfile = findComponentByCodeLazy("UserProfilePopoutWrapper: user cannot be undefined");
const styles = findByPropsLazy("accountProfilePopoutWrapper");
let openAlternatePopout = false;
let accountPanelRef: React.RefObject<Record<PropertyKey, any> | null> = { current: null };
const AccountPanelContextMenu = ErrorBoundary.wrap(() => {
const { prioritizeServerProfile } = settings.use(["prioritizeServerProfile"]);
return (
<Menu.Menu
navId="vc-ap-server-profile"
onClose={ContextMenuApi.closeContextMenu}
>
<Menu.MenuItem
id="vc-ap-view-alternate-popout"
label={prioritizeServerProfile ? "View Account Profile" : "View Server Profile"}
disabled={getCurrentChannel()?.getGuildId() == null}
action={e => {
openAlternatePopout = true;
accountPanelRef.current?.props.onMouseDown();
accountPanelRef.current?.props.onClick(e);
}}
/>
<Menu.MenuCheckboxItem
id="vc-ap-prioritize-server-profile"
label="Prioritize Server Profile"
checked={prioritizeServerProfile}
action={() => settings.store.prioritizeServerProfile = !prioritizeServerProfile}
/>
</Menu.Menu>
);
}, { noop: true });
const settings = definePluginSettings({
prioritizeServerProfile: {
type: OptionType.BOOLEAN,
description: "Prioritize Server Profile when left clicking your account panel",
default: false
}
});
export default definePlugin({
name: "AccountPanelServerProfile",
description: "Right click your account panel in the bottom left to view your profile in the current server",
authors: [Devs.Nuckyz, Devs.relitrix],
settings,
patches: [
{
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
group: true,
replacement: [
{
match: /(?<=\.AVATAR_SIZE\);)/,
replace: "$self.useAccountPanelRef();"
},
{
match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/,
replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},originalRenderPopout:()=>{${originalPopout}}})`
},
{
match: /\.AVATAR,children:.+?(?=renderPopout:)/,
replace: "$&onRequestClose:$self.onPopoutClose,"
},
{
match: /(?<=#{intl::SET_STATUS}\),)/,
replace: "ref:$self.accountPanelRef,onContextMenu:$self.openAccountPanelContextMenu,"
}
]
}
],
get accountPanelRef() {
return accountPanelRef;
},
useAccountPanelRef() {
useEffect(() => () => {
accountPanelRef.current = null;
}, []);
return (accountPanelRef = useRef(null));
},
openAccountPanelContextMenu(event: React.UIEvent) {
ContextMenuApi.openContextMenu(event, AccountPanelContextMenu);
},
onPopoutClose() {
openAlternatePopout = false;
},
UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, originalRenderPopout }: UserProfileProps) => {
if (
(settings.store.prioritizeServerProfile && openAlternatePopout) ||
(!settings.store.prioritizeServerProfile && !openAlternatePopout)
) {
return originalRenderPopout();
}
const currentChannel = getCurrentChannel();
if (currentChannel?.getGuildId() == null) {
return originalRenderPopout();
}
return (
<div className={styles.accountProfilePopoutWrapper}>
<UserProfile {...popoutProps} userId={currentUser.id} guildId={currentChannel.getGuildId()} channelId={currentChannel.id} />
</div>
);
}, { noop: true })
});

View file

@ -41,10 +41,10 @@ export default definePlugin({
},
{
// Status emojis
find: "#{intl::GUILD_OWNER}),children:",
find: ".Messages.GUILD_OWNER,",
replacement: {
match: /(\.CUSTOM_STATUS.+?animate:)\i/,
replace: (_, rest) => `${rest}!0`
match: /(?<=\.activityEmoji,.+?animate:)\i/,
replace: "!0"
}
},
{

View file

@ -1,3 +0,0 @@
# Always Expand Roles
Always expands the role list in profile popouts

View file

@ -1,45 +0,0 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { migratePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
migratePluginSettings("AlwaysExpandRoles", "ShowAllRoles");
export default definePlugin({
name: "AlwaysExpandRoles",
description: "Always expands the role list in profile popouts",
authors: [Devs.surgedevs],
patches: [
{
find: 'action:"EXPAND_ROLES"',
replacement: [
{
match: /(roles:\i(?=.+?(\i)\(!0\)[,;]\i\({action:"EXPAND_ROLES"}\)).+?\[\i,\2\]=\i\.useState\()!1\)/,
replace: (_, rest, setExpandedRoles) => `${rest}!0)`
},
{
// Fix not calculating non-expanded roles because the above patch makes the default "expanded",
// which makes the collapse button never show up and calculation never occur
match: /(?<=useLayoutEffect\(\(\)=>{if\()\i/,
replace: isExpanded => "false"
}
]
}
]
});

View file

@ -51,7 +51,7 @@ export default definePlugin({
{
find: "bitbucket.org",
replacement: {
match: /function \i\(\i\){(?=.{0,30}pathname:\i)/,
match: /function \i\(\i\){(?=.{0,60}\.parse\(\i\))/,
replace: "$&return null;"
},
predicate: () => settings.store.file

View file

@ -21,12 +21,12 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { findByProps, findComponentByCode } from "@webpack";
type AnonUpload = Upload & { anonymise?: boolean; };
const ActionBarIcon = findByCodeLazy(".actionBarIcon)");
const UploadDraft = findByPropsLazy("popFirstFile", "update");
const ActionBarIcon = findComponentByCode(".actionBarIcon)");
const UploadDraft = findByProps("popFirstFile", "update");
const enum Methods {
Random,
@ -71,7 +71,7 @@ export default definePlugin({
description: "Anonymise uploaded file names",
patches: [
{
find: "instantBatchUpload:",
find: "instantBatchUpload:function",
replacement: {
match: /uploadFiles:(\i),/,
replace:
@ -86,9 +86,9 @@ export default definePlugin({
}
},
{
find: "#{intl::ATTACHMENT_UTILITIES_SPOILER}",
find: ".Messages.ATTACHMENT_UTILITIES_SPOILER",
replacement: {
match: /(?<=children:\[)(?=.{10,80}tooltip:.{0,100}#{intl::ATTACHMENT_UTILITIES_SPOILER})/,
match: /(?<=children:\[)(?=.{10,80}tooltip:.{0,100}\i\.\i\.Messages\.ATTACHMENT_UTILITIES_SPOILER)/,
replace: "arguments[0].canEdit!==false?$self.renderIcon(arguments[0]):null,"
},
},

Some files were not shown because too many files have changed in this diff Show more