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
273 changed files with 5030 additions and 5002 deletions

2
.gitignore vendored
View file

@ -18,5 +18,7 @@ lerna-debug.log*
.pnpm-debug.log* .pnpm-debug.log*
*.tsbuildinfo *.tsbuildinfo
src/userplugins
ExtensionCache/ ExtensionCache/
settings/ 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

@ -5,7 +5,6 @@
// @author Vendicated (https://github.com/Vendicated) // @author Vendicated (https://github.com/Vendicated)
// @namespace https://github.com/Vendicated/Vencord // @namespace https://github.com/Vendicated/Vencord
// @supportURL 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 // @license GPL-3.0
// @match *://*.discord.com/* // @match *://*.discord.com/*
// @grant GM_xmlhttpRequest // @grant GM_xmlhttpRequest

View file

@ -90,7 +90,13 @@ export default tseslint.config(
"no-invalid-regexp": "error", "no-invalid-regexp": "error",
"no-constant-condition": ["error", { "checkLoops": false }], "no-constant-condition": ["error", { "checkLoops": false }],
"no-duplicate-imports": "error", "no-duplicate-imports": "error",
"dot-notation": "error", "@typescript-eslint/dot-notation": [
"error",
{
"allowPrivateClassPropertyAccess": true,
"allowProtectedClassPropertyAccess": true
}
],
"no-useless-escape": [ "no-useless-escape": [
"error", "error",
{ {

View file

@ -1,7 +1,7 @@
{ {
"name": "vencord", "name": "vencord",
"private": "true", "private": "true",
"version": "1.10.7", "version": "1.9.8",
"description": "The cutest Discord client mod", "description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme", "homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": { "bugs": {
@ -35,7 +35,6 @@
"testTsc": "tsc --noEmit" "testTsc": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@intrnl/xxhash64": "^0.1.2",
"@sapphi-red/web-noise-suppressor": "0.3.5", "@sapphi-red/web-noise-suppressor": "0.3.5",
"@vap/core": "0.0.12", "@vap/core": "0.0.12",
"@vap/shiki": "0.10.5", "@vap/shiki": "0.10.5",
@ -71,7 +70,6 @@
"stylelint": "^16.8.1", "stylelint": "^16.8.1",
"stylelint-config-standard": "^36.0.1", "stylelint-config-standard": "^36.0.1",
"ts-patch": "^3.2.1", "ts-patch": "^3.2.1",
"ts-pattern": "^5.3.1",
"tsx": "^4.16.5", "tsx": "^4.16.5",
"type-fest": "^4.23.0", "type-fest": "^4.23.0",
"typescript": "^5.5.4", "typescript": "^5.5.4",

View file

@ -16,9 +16,6 @@ importers:
.: .:
dependencies: dependencies:
'@intrnl/xxhash64':
specifier: ^0.1.2
version: 0.1.2
'@sapphi-red/web-noise-suppressor': '@sapphi-red/web-noise-suppressor':
specifier: 0.3.5 specifier: 0.3.5
version: 0.3.5 version: 0.3.5
@ -119,9 +116,6 @@ importers:
ts-patch: ts-patch:
specifier: ^3.2.1 specifier: ^3.2.1
version: 3.2.1 version: 3.2.1
ts-pattern:
specifier: ^5.3.1
version: 5.3.1
tsx: tsx:
specifier: ^4.16.5 specifier: ^4.16.5
version: 4.16.5 version: 4.16.5
@ -540,9 +534,6 @@ packages:
resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==}
engines: {node: '>=18.18'} engines: {node: '>=18.18'}
'@intrnl/xxhash64@0.1.2':
resolution: {integrity: sha512-1+lx7j99fdph+uy3EnjQyr39KQZ7LP56+aWOr6finJWpgYpvb7XrhFUqDwnEk/wpPC98nCjAT6RulpW3crWjlg==}
'@jridgewell/gen-mapping@0.3.5': '@jridgewell/gen-mapping@0.3.5':
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
@ -2533,9 +2524,6 @@ packages:
resolution: {integrity: sha512-hlR43v+GUIUy8/ZGFP1DquEqPh7PFKQdDMTAmYt671kCCA6AkDQMoeFaFmZ7ObPLYOmpMgyKUqL1C+coFMf30w==} resolution: {integrity: sha512-hlR43v+GUIUy8/ZGFP1DquEqPh7PFKQdDMTAmYt671kCCA6AkDQMoeFaFmZ7ObPLYOmpMgyKUqL1C+coFMf30w==}
hasBin: true hasBin: true
ts-pattern@5.3.1:
resolution: {integrity: sha512-1RUMKa8jYQdNfmnK4jyzBK3/PS/tnjcZ1CW0v1vWDeYe5RBklc/nquw03MEoB66hVBm4BnlCfmOqDVxHyT1DpA==}
tsconfig-paths@3.15.0: tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
@ -2945,8 +2933,6 @@ snapshots:
'@humanwhocodes/retry@0.3.0': {} '@humanwhocodes/retry@0.3.0': {}
'@intrnl/xxhash64@0.1.2': {}
'@jridgewell/gen-mapping@0.3.5': '@jridgewell/gen-mapping@0.3.5':
dependencies: dependencies:
'@jridgewell/set-array': 1.2.1 '@jridgewell/set-array': 1.2.1
@ -5172,8 +5158,6 @@ snapshots:
semver: 7.6.3 semver: 7.6.3
strip-ansi: 6.0.1 strip-ansi: 6.0.1
ts-pattern@5.3.1: {}
tsconfig-paths@3.15.0: tsconfig-paths@3.15.0:
dependencies: dependencies:
'@types/json5': 0.0.29 '@types/json5': 0.0.29

View file

@ -312,7 +312,7 @@ export const commonOpts = {
logLevel: "info", logLevel: "info",
bundle: true, bundle: true,
watch, watch,
minify: !watch, minify: !watch && !IS_REPORTER,
sourcemap: watch ? "inline" : "", sourcemap: watch ? "inline" : "",
legalComments: "linked", legalComments: "linked",
banner, banner,
@ -334,6 +334,5 @@ export const commonRendererPlugins = [
banImportPlugin(builtinModuleRegex, "Cannot import node inbuilt modules in browser code. You need to use a native.ts file"), 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(/^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(/^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"),
...commonOpts.plugins ...commonOpts.plugins
]; ];

View file

@ -26,7 +26,7 @@
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import pup, { JSHandle } from "puppeteer-core"; import pup, { JSHandle } from "puppeteer-core";
for (const variable of ["DISCORD_TOKEN", "CHROMIUM_BIN"]) { for (const variable of ["CHROMIUM_BIN"]) {
if (!process.env[variable]) { if (!process.env[variable]) {
console.error(`Missing environment variable ${variable}`); console.error(`Missing environment variable ${variable}`);
process.exit(1); process.exit(1);
@ -214,7 +214,7 @@ page.on("console", async e => {
switch (tag) { switch (tag) {
case "WebpackInterceptor:": case "WebpackInterceptor:":
const patchFailMatch = message.match(/Patch by (.+?) (had no effect|errored|found no module) \(Module id is (.+?)\): (.+)/)!; const patchFailMatch = message.match(/Patch by (.+?) (had no effect|errored|found no module|took [\d.]+?ms) \(Module id is (.+?)\): (.+)/)!;
if (!patchFailMatch) break; if (!patchFailMatch) break;
console.error(await getText()); console.error(await getText());
@ -225,7 +225,7 @@ page.on("console", async e => {
plugin, plugin,
type, type,
id, id,
match: regex.replace(/\(\?:\[A-Za-z_\$\]\[\\w\$\]\*\)/g, "\\i"), match: regex.replace(/\[A-Za-z_\$\]\[\\w\$\]\*/g, "\\i"),
error: await maybeGetError(e.args()[3]) error: await maybeGetError(e.args()[3])
}); });
@ -291,7 +291,7 @@ page.on("error", e => console.error("[Error]", e.message));
page.on("pageerror", e => { page.on("pageerror", e => {
if (e.message.includes("Sentry successfully disabled")) return; if (e.message.includes("Sentry successfully disabled")) return;
if (!e.message.startsWith("Object") && !e.message.includes("Cannot find module")) { if (!e.message.startsWith("Object") && !e.message.includes("Cannot find module") && !/^.{1,2}$/.test(e.message)) {
console.error("[Page Error]", e.message); console.error("[Page Error]", e.message);
report.otherErrors.push(e.message); report.otherErrors.push(e.message);
} else { } else {
@ -299,20 +299,9 @@ page.on("pageerror", e => {
} }
}); });
async function reporterRuntime(token: string) {
Vencord.Webpack.waitFor(
"loginToken",
m => {
console.log("[PUP_DEBUG]", "Logging in with token...");
m.loginToken(token);
}
);
}
await page.evaluateOnNewDocument(` await page.evaluateOnNewDocument(`
if (location.host.endsWith("discord.com")) { if (location.host.endsWith("discord.com")) {
${readFileSync("./dist/browser.js", "utf-8")}; ${readFileSync("./dist/browser.js", "utf-8")};
(${reporterRuntime.toString()})(${JSON.stringify(process.env.DISCORD_TOKEN)});
} }
`); `);

View file

@ -1,2 +0,0 @@
git remote add upstream https://github.com/Vendicated/Vencord.git
git remote set-url --pull upstream DISABLED

View file

@ -23,10 +23,10 @@ export * as Util from "./utils";
export * as QuickCss from "./utils/quickCss"; export * as QuickCss from "./utils/quickCss";
export * as Updater from "./utils/updater"; export * as Updater from "./utils/updater";
export * as Webpack from "./webpack"; export * as Webpack from "./webpack";
export * as WebpackPatcher from "./webpack/patchWebpack";
export { PlainSettings, Settings }; export { PlainSettings, Settings };
import "./utils/quickCss"; import "./utils/quickCss";
import "./webpack/patchWebpack";
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab"; import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
import { StartAt } from "@utils/types"; import { StartAt } from "@utils/types";
@ -39,7 +39,7 @@ import { localStorage } from "./utils/localStorage";
import { relaunch } from "./utils/native"; import { relaunch } from "./utils/native";
import { getCloudSettings, putCloudSettings } from "./utils/settingsSync"; import { getCloudSettings, putCloudSettings } from "./utils/settingsSync";
import { checkForUpdates, update, UpdateLogger } from "./utils/updater"; import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
import { onceReady } from "./webpack"; import { onceDiscordLoaded } from "./webpack";
import { SettingsRouter } from "./webpack/common"; import { SettingsRouter } from "./webpack/common";
if (IS_REPORTER) { if (IS_REPORTER) {
@ -86,7 +86,7 @@ async function syncSettings() {
} }
async function init() { async function init() {
await onceReady; await onceDiscordLoaded;
startAllPlugins(StartAt.WebpackReady); startAllPlugins(StartAt.WebpackReady);
syncSettings(); syncSettings();
@ -125,7 +125,7 @@ async function init() {
const pendingPatches = patches.filter(p => !p.all && p.predicate?.() !== false); const pendingPatches = patches.filter(p => !p.all && p.predicate?.() !== false);
if (pendingPatches.length) if (pendingPatches.length)
PMLogger.warn( PMLogger.warn(
"Webpack has finished initialising, but some patches haven't been applied yet.", "Webpack has finished initializing, but some patches haven't been applied yet.",
"This might be expected since some Modules are lazy loaded, but please verify", "This might be expected since some Modules are lazy loaded, but please verify",
"that all plugins are working as intended.", "that all plugins are working as intended.",
"You are seeing this warning because this is a Development build of Vencord.", "You are seeing this warning because this is a Development build of Vencord.",

View file

@ -8,13 +8,12 @@ import "./ChatButton.css";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { waitFor } from "@webpack"; import { findByProps } from "@webpack";
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common"; import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
import { Channel } from "discord-types/general"; import { Channel } from "discord-types/general";
import { HTMLProps, MouseEventHandler, ReactNode } from "react"; import { HTMLProps, MouseEventHandler, ReactNode } from "react";
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>; const ChannelTextAreaClasses = findByProps<Record<"button" | "buttonContainer", string>>("buttonContainer", "channelTextArea");
waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
export interface ChatBarProps { export interface ChatBarProps {
channel: Channel; channel: Channel;

View file

@ -17,14 +17,14 @@
*/ */
import { mergeDefaults } from "@utils/mergeDefaults"; import { mergeDefaults } from "@utils/mergeDefaults";
import { findByCodeLazy } from "@webpack"; import { findByCode } from "@webpack";
import { MessageActions, SnowflakeUtils } from "@webpack/common"; import { MessageActions, SnowflakeUtils } from "@webpack/common";
import { Message } from "discord-types/general"; import { Message } from "discord-types/general";
import type { PartialDeep } from "type-fest"; import type { PartialDeep } from "type-fest";
import { Argument } from "./types"; import { Argument } from "./types";
const createBotMessage = findByCodeLazy('username:"Clyde"'); const createBotMessage = findByCode('username:"Clyde"');
export function generateId() { export function generateId() {
return `-${SnowflakeUtils.fromTimestamp(Date.now())}`; return `-${SnowflakeUtils.fromTimestamp(Date.now())}`;

View file

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

View file

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

View file

@ -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 * 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 id The id of the child. If an array is specified, all ids will be tried
* @param children The context menu children * @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 | null | undefined>, matchSubstring = false): Array<ReactElement | null | undefined> | null { export function findGroupChildrenByChildId(id: string | string[], children: Array<ReactElement | null>): Array<ReactElement | null> | null {
for (const child of children) { for (const child of children) {
if (child == null) continue; if (child == null) continue;
if (Array.isArray(child)) { if (Array.isArray(child)) {
const found = findGroupChildrenByChildId(id, child, matchSubstring); const found = findGroupChildrenByChildId(id, child);
if (found !== null) return found; if (found !== null) return found;
} }
if ( if (
(Array.isArray(id) && id.some(id => matchSubstring ? child.props?.id?.includes(id) : child.props?.id === id)) (Array.isArray(id) && id.some(id => child.props?.id === id))
|| (matchSubstring ? child.props?.id?.includes(id) : child.props?.id === id) || child.props?.id === id
) return children; ) return children;
let nextChildren = child.props?.children; let nextChildren = child.props?.children;
@ -113,7 +112,7 @@ export function findGroupChildrenByChildId(id: string | string[], children: Arra
child.props.children = nextChildren; child.props.children = nextChildren;
} }
const found = findGroupChildrenByChildId(id, nextChildren, matchSubstring); const found = findGroupChildrenByChildId(id, nextChildren);
if (found !== null) return found; if (found !== null) return found;
} }
} }

View file

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

View file

@ -32,9 +32,10 @@ export interface Settings {
autoUpdate: boolean; autoUpdate: boolean;
autoUpdateNotification: boolean, autoUpdateNotification: boolean,
useQuickCss: boolean; useQuickCss: boolean;
enableReactDevtools: boolean;
themeLinks: string[]; themeLinks: string[];
eagerPatches: boolean;
enabledThemes: string[]; enabledThemes: string[];
enableReactDevtools: boolean;
frameless: boolean; frameless: boolean;
transparent: boolean; transparent: boolean;
winCtrlQ: boolean; winCtrlQ: boolean;
@ -81,6 +82,7 @@ const DefaultSettings: Settings = {
autoUpdateNotification: true, autoUpdateNotification: true,
useQuickCss: true, useQuickCss: true,
themeLinks: [], themeLinks: [],
eagerPatches: IS_REPORTER,
enabledThemes: [], enabledThemes: [],
enableReactDevtools: false, enableReactDevtools: false,
frameless: false, frameless: false,
@ -116,7 +118,6 @@ const saveSettingsOnFrequentAction = debounce(async () => {
} }
}, 60_000); }, 60_000);
export const SettingsStore = new SettingsStoreClass(settings, { export const SettingsStore = new SettingsStoreClass(settings, {
readOnly: true, readOnly: true,
getDefaultValue({ getDefaultValue({

View file

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

View file

@ -17,8 +17,7 @@
*/ */
import { proxyLazy } from "@utils/lazy"; import { proxyLazy } from "@utils/lazy";
import { Logger } from "@utils/Logger"; import { findByFactoryCode } from "@webpack";
import { findModuleId, proxyLazyWebpack, wreq } from "@webpack";
interface UserSettingDefinition<T> { interface UserSettingDefinition<T> {
/** /**
@ -43,12 +42,7 @@ interface UserSettingDefinition<T> {
userSettingsAPIName: string; userSettingsAPIName: string;
} }
export const UserSettings: Record<PropertyKey, UserSettingDefinition<any>> | undefined = proxyLazyWebpack(() => { export const UserSettings = findByFactoryCode<Record<PropertyKey, UserSettingDefinition<any>>>('"textAndImages","renderSpoilers"');
const modId = findModuleId('"textAndImages","renderSpoilers"');
if (modId == null) return new Logger("UserSettingsAPI ").error("Didn't find settings module.");
return wreq(modId as any);
});
/** /**
* Get the setting with the given setting group and name. * Get the setting with the given setting group and name.
@ -56,7 +50,7 @@ export const UserSettings: Record<PropertyKey, UserSettingDefinition<any>> | und
* @param group The setting group * @param group The setting group
* @param name The name of the setting * @param name The name of the setting
*/ */
export function getUserSetting<T = any>(group: string, name: string): UserSettingDefinition<T> | undefined { export function getUserSetting<T = any>(group: string, name: string): UserSettingDefinition<T> {
if (!Vencord.Plugins.isPluginEnabled("UserSettingsAPI")) throw new Error("Cannot use UserSettingsAPI without setting as dependency."); if (!Vencord.Plugins.isPluginEnabled("UserSettingsAPI")) throw new Error("Cannot use UserSettingsAPI without setting as dependency.");
for (const key in UserSettings) { for (const key in UserSettings) {
@ -66,10 +60,12 @@ export function getUserSetting<T = any>(group: string, name: string): UserSettin
return userSetting; return userSetting;
} }
} }
throw new Error(`UserSettingsAPI: Setting ${group}.${name} not found.`);
} }
/** /**
* {@link getUserSettingDefinition}, lazy. * Lazy version of {@link getUserSetting}
* *
* Get the setting with the given setting group and name. * Get the setting with the given setting group and name.
* *

View file

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

View file

@ -18,8 +18,9 @@
import "./iconStyles.css"; import "./iconStyles.css";
import { getIntlMessage, getTheme, Theme } from "@utils/discord"; import { getTheme, Theme } from "@utils/discord";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import { i18n } from "@webpack/common";
import type { PropsWithChildren } from "react"; import type { PropsWithChildren } from "react";
interface BaseIconProps extends IconProps { interface BaseIconProps extends IconProps {
@ -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) { export function CopyIcon(props: IconProps) {
return ( return (
@ -74,9 +76,8 @@ export function CopyIcon(props: IconProps) {
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >
<g fill="currentColor"> <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="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1z" />
<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="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" />
<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" />
</g> </g>
</Icon> </Icon>
); );
@ -132,7 +133,7 @@ export function InfoIcon(props: IconProps) {
export function OwnerCrownIcon(props: IconProps) { export function OwnerCrownIcon(props: IconProps) {
return ( return (
<Icon <Icon
aria-label={getIntlMessage("GUILD_OWNER")} aria-label={i18n.Messages.GUILD_OWNER}
{...props} {...props}
className={classes(props.className, "vc-owner-crown-icon")} className={classes(props.className, "vc-owner-crown-icon")}
role="img" role="img"

View file

@ -24,13 +24,12 @@ import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex"; import { Flex } from "@components/Flex";
import { gitRemote } from "@shared/vencordUserAgent"; import { gitRemote } from "@shared/vencordUserAgent";
import { proxyLazy } from "@utils/lazy";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc"; import { classes, isObjectEmpty } from "@utils/misc";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { OptionType, Plugin } from "@utils/types"; import { OptionType, Plugin } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack"; import { find, findByProps, findComponentByCode } from "@webpack";
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common"; import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserUtils } from "@webpack/common";
import { User } from "discord-types/general"; import { User } from "discord-types/general";
import { Constructor } from "type-fest"; import { Constructor } from "type-fest";
@ -50,9 +49,9 @@ import { GithubButton, WebsiteButton } from "./LinkIconButton";
const cl = classNameFactory("vc-plugin-modal-"); const cl = classNameFactory("vc-plugin-modal-");
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers"); const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar"); const AvatarStyles = findByProps("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
const UserRecord: Constructor<Partial<User>> = proxyLazy(() => UserStore.getCurrentUser().constructor) as any; const UserRecord = find<Constructor<Partial<User>>>(m => m?.prototype?.getAvatarURL && m?.prototype?.hasHadPremium);
interface PluginModalProps extends ModalProps { interface PluginModalProps extends ModalProps {
plugin: Plugin; plugin: Plugin;

View file

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

View file

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

View file

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

View file

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

View file

@ -33,19 +33,19 @@ import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc"; import { classes, isObjectEmpty } from "@utils/misc";
import { useAwaiter } from "@utils/react"; import { useAwaiter } from "@utils/react";
import { Plugin } from "@utils/types"; import { Plugin } from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByProps } from "@webpack";
import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common"; import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common";
import Plugins, { ExcludedPlugins } from "~plugins"; import Plugins, { ExcludedPlugins } from "~plugins";
// Avoid circular dependency // Avoid circular dependency
const { startDependenciesRecursive, startPlugin, stopPlugin } = proxyLazy(() => require("../../plugins")); const PluginManager = proxyLazy(() => require("../../plugins")) as typeof import("../../plugins");
const cl = classNameFactory("vc-plugins-"); const cl = classNameFactory("vc-plugins-");
const logger = new Logger("PluginSettings", "#a6d189"); const logger = new Logger("PluginSettings", "#a6d189");
const InputStyles = findByPropsLazy("inputWrapper", "inputDefault", "error"); const InputStyles = findByProps("inputWrapper", "inputDefault", "error");
const ButtonClasses = findByPropsLazy("button", "disabled", "enabled"); const ButtonClasses = findByProps("button", "disabled", "enabled");
function showErrorToast(message: string) { function showErrorToast(message: string) {
@ -93,14 +93,14 @@ interface PluginCardProps extends React.HTMLProps<HTMLDivElement> {
export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) { export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) {
const settings = Settings.plugins[plugin.name]; const settings = Settings.plugins[plugin.name];
const isEnabled = () => Vencord.Plugins.isPluginEnabled(plugin.name); const isEnabled = () => settings.enabled ?? false;
function toggleEnabled() { function toggleEnabled() {
const wasEnabled = isEnabled(); const wasEnabled = isEnabled();
// If we're enabling a plugin, make sure all deps are enabled recursively. // If we're enabling a plugin, make sure all deps are enabled recursively.
if (!wasEnabled) { if (!wasEnabled) {
const { restartNeeded, failures } = startDependenciesRecursive(plugin); const { restartNeeded, failures } = PluginManager.startDependenciesRecursive(plugin);
if (failures.length) { if (failures.length) {
logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`); logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(", ")}`);
showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null); showNotice("Failed to start dependencies: " + failures.join(", "), "Close", () => null);
@ -126,7 +126,7 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
return; return;
} }
const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin); const result = wasEnabled ? PluginManager.stopPlugin(plugin) : PluginManager.startPlugin(plugin);
if (!result) { if (!result) {
settings.enabled = false; settings.enabled = false;
@ -292,10 +292,10 @@ export default function PluginSettings() {
if (!pluginFilter(p)) continue; 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) { if (isRequired) {
const tooltipText = p.required || !depMap[p.name] const tooltipText = p.required
? "This plugin is required for Vencord to function." ? "This plugin is required for Vencord to function."
: makeDependencyList(depMap[p.name]?.filter(d => settings.plugins[d].enabled)); : makeDependencyList(depMap[p.name]?.filter(d => settings.plugins[d].enabled));

View file

@ -19,7 +19,7 @@
import "./Switch.css"; import "./Switch.css";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack"; import { findByProps } from "@webpack";
interface SwitchProps { interface SwitchProps {
checked: boolean; checked: boolean;
@ -29,7 +29,7 @@ interface SwitchProps {
const SWITCH_ON = "var(--green-360)"; const SWITCH_ON = "var(--green-360)";
const SWITCH_OFF = "var(--primary-400)"; const SWITCH_OFF = "var(--primary-400)";
const SwitchClasses = findByPropsLazy("slider", "input", "container"); const SwitchClasses = findByProps("slider", "input", "container");
export function Switch({ checked, onChange, disabled }: SwitchProps) { export function Switch({ checked, onChange, disabled }: SwitchProps) {
return ( return (

View file

@ -22,7 +22,7 @@ import { Margins } from "@utils/margins";
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches"; import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
import { makeCodeblock } from "@utils/text"; import { makeCodeblock } from "@utils/text";
import { Patch, ReplaceFn } from "@utils/types"; import { Patch, ReplaceFn } from "@utils/types";
import { search } from "@webpack"; import { searchFactories } from "@webpack";
import { Button, Clipboard, Forms, Parser, React, Switch, TextArea, TextInput } from "@webpack/common"; import { Button, Clipboard, Forms, Parser, React, Switch, TextArea, TextInput } from "@webpack/common";
import { SettingsTab, wrapTab } from "./shared"; import { SettingsTab, wrapTab } from "./shared";
@ -33,7 +33,7 @@ if (IS_DEV) {
} }
const findCandidates = debounce(function ({ find, setModule, setError }) { const findCandidates = debounce(function ({ find, setModule, setError }) {
const candidates = search(find); const candidates = searchFactories(find);
const keys = Object.keys(candidates); const keys = Object.keys(candidates);
const len = keys.length; const len = keys.length;
if (len === 0) if (len === 0)
@ -56,7 +56,7 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
const [compileResult, setCompileResult] = React.useState<[boolean, string]>(); const [compileResult, setCompileResult] = React.useState<[boolean, string]>();
const [patchedCode, matchResult, diff] = React.useMemo(() => { const [patchedCode, matchResult, diff] = React.useMemo(() => {
const src: string = fact.toString().replaceAll("\n", ""); const src = String(fact).replaceAll("\n", "");
try { try {
new RegExp(match); new RegExp(match);
@ -247,7 +247,7 @@ function FullPatchInput({ setFind, setParsedFind, setMatch, setReplacement }: Fu
} }
try { 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.find) throw new Error("No 'find' field");
if (!parsed.replacement) throw new Error("No 'replacement' field"); if (!parsed.replacement) throw new Error("No 'replacement' field");
@ -382,7 +382,6 @@ function PatchHelper() {
<Forms.FormTitle className={Margins.top20}>Code</Forms.FormTitle> <Forms.FormTitle className={Margins.top20}>Code</Forms.FormTitle>
<CodeBlock lang="js" content={code} /> <CodeBlock lang="js" content={code} />
<Button onClick={() => Clipboard.copy(code)}>Copy to Clipboard</Button> <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> </SettingsTab>

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { Settings, useSettings } from "@api/Settings"; import { useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles"; import { classNameFactory } from "@api/Styles";
import { Flex } from "@components/Flex"; import { Flex } from "@components/Flex";
import { DeleteIcon, FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons"; import { DeleteIcon, FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons";
@ -27,9 +27,9 @@ import { openInviteModal } from "@utils/discord";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { showItemInFolder } from "@utils/native"; import { showItemInFolder } from "@utils/native";
import { useAwaiter } from "@utils/react"; import { useAwaiter } from "@utils/react";
import { findLazy } from "@webpack"; import { findComponentByFields } from "@webpack";
import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common"; import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
import type { ComponentType, Ref, SyntheticEvent } from "react"; import type { Ref, SyntheticEvent } from "react";
import Plugins from "~plugins"; import Plugins from "~plugins";
@ -37,14 +37,14 @@ import { AddonCard } from "./AddonCard";
import { QuickAction, QuickActionCard } from "./quickActions"; import { QuickAction, QuickActionCard } from "./quickActions";
import { SettingsTab, wrapTab } from "./shared"; import { SettingsTab, wrapTab } from "./shared";
type FileInput = ComponentType<{ type FileInputProps = {
ref: Ref<HTMLInputElement>; ref: Ref<HTMLInputElement>;
onChange: (e: SyntheticEvent<HTMLInputElement>) => void; onChange: (e: SyntheticEvent<HTMLInputElement>) => void;
multiple?: boolean; multiple?: boolean;
filters?: { name?: string; extensions: string[]; }[]; filters?: { name?: string; extensions: string[]; }[];
}>; };
const FileInput: FileInput = findLazy(m => m.prototype?.activateUploadDialogue && m.prototype.setRef); const FileInput = findComponentByFields<FileInputProps>("activateUploadDialogue", "setRef");
const cl = classNameFactory("vc-settings-theme-"); const cl = classNameFactory("vc-settings-theme-");
@ -77,16 +77,8 @@ function Validators({ themeLinks }: { themeLinks: string[]; }) {
<Forms.FormTitle className={Margins.top20} tag="h5">Validator</Forms.FormTitle> <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> <Forms.FormText>This section will tell you whether your themes can successfully be loaded</Forms.FormText>
<div> <div>
{themeLinks.map(rawLink => { {themeLinks.map(link => (
const { label, link } = (() => { <Card style={{
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={{
padding: ".5em", padding: ".5em",
marginBottom: ".5em", marginBottom: ".5em",
marginTop: ".5em" marginTop: ".5em"
@ -94,11 +86,11 @@ function Validators({ themeLinks }: { themeLinks: string[]; }) {
<Forms.FormTitle tag="h5" style={{ <Forms.FormTitle tag="h5" style={{
overflowWrap: "break-word" overflowWrap: "break-word"
}}> }}>
{label} {link}
</Forms.FormTitle> </Forms.FormTitle>
<Validator link={link} /> <Validator link={link} />
</Card>; </Card>
})} ))}
</div> </div>
</> </>
); );
@ -257,7 +249,7 @@ function ThemesTab() {
Icon={PaintbrushIcon} Icon={PaintbrushIcon}
/> />
{Settings.plugins.ClientTheme.enabled && ( {Vencord.Plugins.isPluginEnabled("ClientTheme") && (
<QuickAction <QuickAction
text="Edit ClientTheme" text="Edit ClientTheme"
action={() => openPluginModal(Plugins.ClientTheme)} action={() => openPluginModal(Plugins.ClientTheme)}
@ -304,7 +296,6 @@ function ThemesTab() {
<Card className="vc-settings-card vc-text-selectable"> <Card className="vc-settings-card vc-text-selectable">
<Forms.FormTitle tag="h5">Paste links to css files here</Forms.FormTitle> <Forms.FormTitle tag="h5">Paste links to css files here</Forms.FormTitle>
<Forms.FormText>One link per line</Forms.FormText> <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> <Forms.FormText>Make sure to use direct links to files (raw or github.io)!</Forms.FormText>
</Card> </Card>

View file

@ -23,35 +23,61 @@ if (IS_DEV || IS_REPORTER) {
var logger = new Logger("Tracer", "#FFD166"); var logger = new Logger("Tracer", "#FFD166");
} }
const noop = function () { }; export const beginTrace = !(IS_DEV || IS_REPORTER) ? () => { } :
export const beginTrace = !(IS_DEV || IS_REPORTER) ? noop :
function beginTrace(name: string, ...args: any[]) { function beginTrace(name: string, ...args: any[]) {
if (name in traces) if (name in traces) {
throw new Error(`Trace ${name} already exists!`); throw new Error(`Trace ${name} already exists!`);
}
traces[name] = [performance.now(), args]; traces[name] = [performance.now(), args];
}; };
export const finishTrace = !(IS_DEV || IS_REPORTER) ? noop : function finishTrace(name: string) { export const finishTrace = !(IS_DEV || IS_REPORTER) ? () => 0 :
function finishTrace(name: string) {
const end = performance.now(); const end = performance.now();
const [start, args] = traces[name]; const [start, args] = traces[name];
delete traces[name]; delete traces[name];
logger.debug(`${name} took ${end - start}ms`, args); const totalTime = end - start;
logger.debug(`${name} took ${totalTime}ms`, args);
return totalTime;
}; };
type Func = (...args: any[]) => any; type Func = (...args: any[]) => any;
type TraceNameMapper<F extends Func> = (...args: Parameters<F>) => string; type TraceNameMapper<F extends Func> = (...args: Parameters<F>) => string;
const noopTracer = function noopTracerWithResults<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) {
<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) => f; return function (this: unknown, ...args: Parameters<F>): [ReturnType<F>, number] {
return [f.apply(this, args), 0];
};
}
function noopTracer<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) {
return f;
}
export const traceFunctionWithResults = !(IS_DEV || IS_REPORTER)
? noopTracerWithResults
: function traceFunctionWithResults<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): (this: unknown, ...args: Parameters<F>) => [ReturnType<F>, number] {
return function (this: unknown, ...args: Parameters<F>) {
const traceName = mapper?.(...args) ?? name;
beginTrace(traceName, ...arguments);
try {
return [f.apply(this, args), finishTrace(traceName)];
} catch (e) {
finishTrace(traceName);
throw e;
}
};
};
export const traceFunction = !(IS_DEV || IS_REPORTER) export const traceFunction = !(IS_DEV || IS_REPORTER)
? noopTracer ? noopTracer
: function traceFunction<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): F { : function traceFunction<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): F {
return function (this: any, ...args: Parameters<F>) { return function (this: unknown, ...args: Parameters<F>) {
const traceName = mapper?.(...args) ?? name; const traceName = mapper?.(...args) ?? name;
beginTrace(traceName, ...arguments); beginTrace(traceName, ...arguments);

View file

@ -8,10 +8,11 @@ import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches"; import { canonicalizeMatch } from "@utils/patches";
import * as Webpack from "@webpack"; import * as Webpack from "@webpack";
import { wreq } from "@webpack"; import { wreq } from "@webpack";
import { AnyModuleFactory, ModuleFactory } from "webpack";
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
export async function loadLazyChunks() { export async function loadLazyChunks() {
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
try { try {
LazyChunkLoaderLogger.log("Loading all chunks..."); LazyChunkLoaderLogger.log("Loading all chunks...");
@ -25,19 +26,12 @@ export async function loadLazyChunks() {
// True if resolved, false otherwise // True if resolved, false otherwise
const chunksSearchPromises = [] as Array<() => boolean>; const chunksSearchPromises = [] as Array<() => boolean>;
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g); const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g);
const foundCssDebuggingLoad = false;
async function searchAndLoadLazyChunks(factoryCode: string) { async function searchAndLoadLazyChunks(factoryCode: string) {
// Workaround to avoid loading the CSS debugging chunk which turns the app pink
const hasCssDebuggingLoad = foundCssDebuggingLoad ? false : factoryCode.includes(".cssDebuggingEnabled&&");
const lazyChunks = factoryCode.matchAll(LazyChunkRegex); const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>(); const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
const shouldForceDefer = false;
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => { await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : []; const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Webpack.ChunkIdsRegex)).map(m => Number(m[1])) : [];
@ -48,16 +42,6 @@ export async function loadLazyChunks() {
let invalidChunkGroup = false; let invalidChunkGroup = false;
for (const id of chunkIds) { 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; if (wreq.u(id) == null || wreq.u(id) === "undefined.js") continue;
const isWorkerAsset = await fetch(wreq.p + wreq.u(id)) const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
@ -82,19 +66,14 @@ export async function loadLazyChunks() {
await Promise.all( await Promise.all(
Array.from(validChunkGroups) Array.from(validChunkGroups)
.map(([chunkIds]) => .map(([chunkIds]) =>
Promise.all(chunkIds.map(id => wreq.e(id as any).catch(() => { }))) Promise.all(chunkIds.map(id => wreq.e(id)))
) )
); );
// Requires the entry points for all valid chunk groups // Requires the entry points for all valid chunk groups
for (const [, entryPoint] of validChunkGroups) { for (const [, entryPoint] of validChunkGroups) {
try { try {
if (shouldForceDefer) { if (wreq.m[entryPoint]) wreq(entryPoint);
deferredRequires.add(entryPoint);
continue;
}
if (wreq.m[entryPoint]) wreq(entryPoint as any);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
@ -122,32 +101,33 @@ export async function loadLazyChunks() {
}, 0); }, 0);
} }
Webpack.factoryListeners.add(factory => { function factoryListener(factory: AnyModuleFactory | ModuleFactory) {
let isResolved = false; let isResolved = false;
searchAndLoadLazyChunks(factory.toString()).then(() => isResolved = true); searchAndLoadLazyChunks(String(factory))
.then(() => isResolved = true)
chunksSearchPromises.push(() => isResolved); .catch(() => isResolved = true);
});
for (const factoryId in wreq.m) {
let isResolved = false;
searchAndLoadLazyChunks(wreq.m[factoryId].toString()).then(() => isResolved = true);
chunksSearchPromises.push(() => isResolved); chunksSearchPromises.push(() => isResolved);
} }
Webpack.factoryListeners.add(factoryListener);
for (const factoryId in wreq.m) {
factoryListener(wreq.m[factoryId]);
}
await chunksSearchingDone; await chunksSearchingDone;
Webpack.factoryListeners.delete(factoryListener);
// Require deferred entry points // Require deferred entry points
for (const deferredRequire of deferredRequires) { for (const deferredRequire of deferredRequires) {
wreq!(deferredRequire as any); wreq(deferredRequire);
} }
// All chunks Discord has mapped to asset files, even if they are not used anymore // All chunks Discord has mapped to asset files, even if they are not used anymore
const allChunks = [] as number[]; const allChunks = [] as number[];
// Matches "id" or id: // Matches "id" or id:
for (const currentMatch of wreq!.u.toString().matchAll(/(?:"([\deE]+?)"(?![,}]))|(?:([\deE]+?):)/g)) { for (const currentMatch of String(wreq.u).matchAll(/(?:"([\deE]+?)"(?![,}]))|(?:([\deE]+?):)/g)) {
const id = currentMatch[1] ?? currentMatch[2]; const id = currentMatch[1] ?? currentMatch[2];
if (id == null) continue; if (id == null) continue;
@ -156,7 +136,8 @@ export async function loadLazyChunks() {
if (allChunks.length === 0) throw new Error("Failed to get all chunks"); if (allChunks.length === 0) throw new Error("Failed to get all chunks");
// Chunks that are not loaded (not used) by Discord code anymore // Chunks which our regex could not catch to load
// It will always contain WebWorker assets, and also currently contains some language packs which are loaded differently
const chunksLeft = allChunks.filter(id => { const chunksLeft = allChunks.filter(id => {
return !(validChunks.has(id) || invalidChunks.has(id)); return !(validChunks.has(id) || invalidChunks.has(id));
}); });
@ -166,12 +147,9 @@ export async function loadLazyChunks() {
.then(r => r.text()) .then(r => r.text())
.then(t => t.includes("importScripts(")); .then(t => t.includes("importScripts("));
// Loads and requires a chunk // Loads the chunk. Currently this only happens with the language packs which are loaded differently
if (!isWorkerAsset) { if (!isWorkerAsset) {
await wreq.e(id as any); await wreq.e(id);
// Technically, the id of the chunk does not match the entry point
// But, still try it because we have no way to get the actual entry point
if (wreq.m[id]) wreq(id as any);
} }
})); }));

View file

@ -4,22 +4,39 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { SYM_PROXY_INNER_GET, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
import * as Webpack from "@webpack"; import * as Webpack from "@webpack";
import { patches } from "plugins"; import { addPatch, patches } from "plugins";
import { loadLazyChunks } from "./loadLazyChunks"; import { loadLazyChunks } from "./loadLazyChunks";
async function runReporter() {
const ReporterLogger = new Logger("Reporter"); const ReporterLogger = new Logger("Reporter");
async function runReporter() {
try { try {
ReporterLogger.log("Starting test..."); ReporterLogger.log("Starting test...");
let loadLazyChunksResolve: (value: void | PromiseLike<void>) => void; let loadLazyChunksResolve: (value: void) => void;
const loadLazyChunksDone = new Promise<void>(r => loadLazyChunksResolve = r); const loadLazyChunksDone = new Promise<void>(r => loadLazyChunksResolve = r);
Webpack.beforeInitListeners.add(() => loadLazyChunks().then((loadLazyChunksResolve))); // The main patch for starting the reporter chunk loading
addPatch({
find: '"Could not find app-mount"',
replacement: {
match: /(?<="use strict";)/,
replace: "Vencord.Webpack._initReporter();"
}
}, "Vencord Reporter");
// @ts-ignore
Vencord.Webpack._initReporter = function () {
// initReporter is called in the patched entry point of Discord
// setImmediate to only start searching for lazy chunks after Discord initialized the app
setTimeout(() => loadLazyChunks().then(loadLazyChunksResolve), 0);
};
await loadLazyChunksDone; await loadLazyChunksDone;
for (const patch of patches) { for (const patch of patches) {
@ -28,52 +45,158 @@ async function runReporter() {
} }
} }
for (const [searchType, args] of Webpack.lazyWebpackSearchHistory) { for (const [plugin, moduleId, match, totalTime] of Vencord.WebpackPatcher.patchTimings) {
let method = searchType; if (totalTime > 3) {
new Logger("WebpackInterceptor").warn(`Patch by ${plugin} took ${totalTime}ms (Module id is ${String(moduleId)}): ${match}`);
if (searchType === "findComponent") method = "find"; }
if (searchType === "findExportedComponent") method = "findByProps";
if (searchType === "waitFor" || searchType === "waitForComponent") {
if (typeof args[0] === "string") method = "findByProps";
else method = "find";
} }
if (searchType === "waitForStore") method = "findStore";
let result: any; await Promise.all(Webpack.webpackSearchHistory.map(async ([searchType, args]) => {
args = [...args];
let result = null as any;
try { try {
if (method === "proxyLazyWebpack" || method === "LazyComponentWebpack") { switch (searchType) {
case "webpackDependantLazy":
case "webpackDependantLazyComponent": {
const [factory] = args; const [factory] = args;
result = factory(); result = factory();
} else if (method === "extractAndLoadChunks") { break;
const [code, matcher] = args; }
case "extractAndLoadChunks": {
const extractAndLoadChunks = args.shift();
result = await Webpack.extractAndLoadChunks(code, matcher); result = await extractAndLoadChunks();
if (result === false) result = null; if (result === false) {
} else if (method === "mapMangledModule") { result = null;
const [code, mapper] = args;
result = Webpack.mapMangledModule(code, mapper);
if (Object.keys(result).length !== Object.keys(mapper).length) throw new Error("Webpack Find Fail");
} else {
// @ts-ignore
result = Webpack[method](...args);
} }
if (result == null || (result.$$vencordInternal != null && result.$$vencordInternal() == null)) throw new Error("Webpack Find Fail"); break;
}
default: {
const findResult = args.shift();
if (findResult != null) {
if (findResult.$$vencordCallbackCalled != null && findResult.$$vencordCallbackCalled()) {
result = findResult;
break;
}
if (findResult[SYM_PROXY_INNER_GET] != null) {
result = findResult[SYM_PROXY_INNER_VALUE];
break;
}
if (findResult[SYM_LAZY_COMPONENT_INNER] != null) {
result = findResult[SYM_LAZY_COMPONENT_INNER]();
break;
}
if (searchType === "mapMangledModule") {
result = findResult;
for (const innerMap in result) {
if (
(result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) ||
(result[innerMap][SYM_LAZY_COMPONENT_INNER] != null && result[innerMap][SYM_LAZY_COMPONENT_INNER]() == null)
) {
throw new Error("Webpack Find Fail");
}
}
break;
}
// This can happen if a `find` was immediately found
result = findResult;
}
break;
}
}
if (result == null) {
throw new Error("Webpack Find Fail");
}
} catch (e) { } catch (e) {
let logMessage = searchType; let logMessage = searchType;
if (method === "find" || method === "proxyLazyWebpack" || method === "LazyComponentWebpack") logMessage += `(${args[0].toString().slice(0, 147)}...)`;
else if (method === "extractAndLoadChunks") logMessage += `([${args[0].map(arg => `"${arg}"`).join(", ")}], ${args[1].toString()})`;
else if (method === "mapMangledModule") {
const failedMappings = Object.keys(args[1]).filter(key => result?.[key] == null);
logMessage += `("${args[0]}", {\n${failedMappings.map(mapping => `\t${mapping}: ${args[1][mapping].toString().slice(0, 147)}...`).join(",\n")}\n})`; let filterName = "";
let parsedArgs = args;
if (args[0].$$vencordProps != null) {
if (["find", "findComponent", "waitFor"].includes(searchType)) {
filterName = args[0].$$vencordProps[0];
parsedArgs = args[0].$$vencordProps.slice(1);
} else {
parsedArgs = args[0].$$vencordProps;
}
}
function stringifyFilter(code: Webpack.CodeFilterWithSingle) {
if (Array.isArray(code)) {
return `[${code.map(arg => arg instanceof RegExp ? String(arg) : JSON.stringify(arg)).join(", ")}]`;
}
return code instanceof RegExp ? String(code) : JSON.stringify(code);
}
// if parsedArgs is the same as args, it means vencordProps of the filter was not available (like in normal filter functions),
// so log the filter function instead
if (
parsedArgs === args &&
["waitFor", "find", "findComponent", "webpackDependantLazy", "webpackDependantLazyComponent"].includes(searchType)
) {
let filter = String(parsedArgs[0]);
if (filter.length > 150) {
filter = filter.slice(0, 147) + "...";
}
logMessage += `(${filter})`;
} else if (searchType === "extractAndLoadChunks") {
const [code, matcher] = parsedArgs;
let regexStr: string;
if (matcher === Webpack.DefaultExtractAndLoadChunksRegex) {
regexStr = "DefaultExtractAndLoadChunksRegex";
} else {
regexStr = String(matcher);
}
logMessage += `(${stringifyFilter(code)}, ${regexStr})`;
} else if (searchType === "mapMangledModule") {
const [code, mappers] = parsedArgs;
const parsedFailedMappers = Object.entries<any>(mappers)
.filter(([key]) =>
result == null ||
(result[key]?.[SYM_PROXY_INNER_GET] != null && result[key][SYM_PROXY_INNER_VALUE] == null) ||
(result[key]?.[SYM_LAZY_COMPONENT_INNER] != null && result[key][SYM_LAZY_COMPONENT_INNER]() == null)
)
.map(([key, filter]) => {
let parsedFilter: string;
if (filter.$$vencordProps != null) {
const filterName = filter.$$vencordProps[0];
parsedFilter = `${filterName}(${filter.$$vencordProps.slice(1).map((arg: any) => arg instanceof RegExp ? String(arg) : JSON.stringify(arg)).join(", ")})`;
} else {
parsedFilter = String(filter);
if (parsedFilter.length > 150) {
parsedFilter = parsedFilter.slice(0, 147) + "...";
}
}
return [key, parsedFilter];
});
logMessage += `(${stringifyFilter(code)}, {\n${parsedFailedMappers.map(([key, parsedFilter]) => `\t${key}: ${parsedFilter}`).join(",\n")}\n})`;
} else {
logMessage += `(${filterName.length ? `${filterName}(` : ""}${parsedArgs.map(stringifyFilter).join(", ")})${filterName.length ? ")" : ""}`;
} }
else logMessage += `(${args.map(arg => `"${arg}"`).join(", ")})`;
ReporterLogger.log("Webpack Find Fail:", logMessage); ReporterLogger.log("Webpack Find Fail:", logMessage);
} }
} }));
ReporterLogger.log("Finished test"); ReporterLogger.log("Finished test");
} catch (e) { } catch (e) {
@ -81,4 +204,5 @@ async function runReporter() {
} }
} }
runReporter(); // Run after the Vencord object has been created
setTimeout(runReporter, 0);

7
src/globals.d.ts vendored
View file

@ -64,13 +64,8 @@ declare global {
export var Vesktop: any; export var Vesktop: any;
export var VesktopNative: any; export var VesktopNative: any;
interface Window { interface Window extends Record<PropertyKey, any> {
webpackChunkdiscord_app: {
push(chunk: any): any;
pop(): any;
};
_: LoDashStatic; _: LoDashStatic;
[k: string]: any;
} }
} }

View file

@ -17,7 +17,7 @@
*/ */
import { onceDefined } from "@shared/onceDefined"; import { onceDefined } from "@shared/onceDefined";
import electron, { app, BrowserWindowConstructorOptions, Menu, nativeTheme } from "electron"; import electron, { app, BrowserWindowConstructorOptions, Menu } from "electron";
import { dirname, join } from "path"; import { dirname, join } from "path";
import { initIpc } from "./ipcMain"; import { initIpc } from "./ipcMain";
@ -100,19 +100,6 @@ if (!IS_VANILLA) {
super(options); super(options);
initIpc(this); initIpc(this);
// Workaround for https://github.com/electron/electron/issues/43367. Vesktop also has its own workaround
// @TODO: Remove this when the issue is fixed
if (IS_DISCORD_DESKTOP) {
this.webContents.on("devtools-opened", () => {
if (!nativeTheme.shouldUseDarkColors) return;
nativeTheme.themeSource = "light";
setTimeout(() => {
nativeTheme.themeSource = "dark";
}, 100);
});
}
} else super(options); } else super(options);
} }
} }

View file

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

View file

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import "./fixBadgeOverflow.css";
import { _getBadges, BadgePosition, BadgeUserArgs, ProfileBadge } from "@api/Badges"; import { _getBadges, BadgePosition, BadgeUserArgs, ProfileBadge } from "@api/Badges";
import DonateButton from "@components/DonateButton"; import DonateButton from "@components/DonateButton";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
@ -77,7 +79,7 @@ export default definePlugin({
replace: "...$1.props,$& $1.image??" replace: "...$1.props,$& $1.image??"
}, },
{ {
match: /(?<=text:(\i)\.description,.{0,200})children:/, match: /(?<=text:(\i)\.description,.{0,50})children:/,
replace: "children:$1.component ? $self.renderBadgeComponent({ ...$1 }) :" replace: "children:$1.component ? $self.renderBadgeComponent({ ...$1 }) :"
}, },
// conditionally override their onClick with badge.onClick if it exists // conditionally override their onClick with badge.onClick if it exists

View file

@ -1,24 +0,0 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
export default definePlugin({
name: "DynamicImageModalAPI",
authors: [Devs.sadan, Devs.Nuckyz],
description: "Allows you to omit either width or height when opening an image modal",
patches: [
{
find: "SCALE_DOWN:",
replacement: {
match: /!\(null==(\i)\|\|0===\i\|\|null==(\i)\|\|0===\i\)/,
replace: (_, width, height) => `!((null == ${width} || 0 === ${width}) && (null == ${height} || 0 === ${height}))`
}
}
]
});

View file

@ -31,7 +31,7 @@ export default definePlugin({
match: /let\{[^}]*lostPermissionTooltipText:\i[^}]*\}=(\i),/, match: /let\{[^}]*lostPermissionTooltipText:\i[^}]*\}=(\i),/,
replace: "$&vencordProps=$1," replace: "$&vencordProps=$1,"
}, { }, {
match: /#{intl::GUILD_OWNER}(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/, match: /\.Messages\.GUILD_OWNER(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps))," replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
} }
] ]

View file

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

View file

@ -27,7 +27,7 @@ export default definePlugin({
{ {
find: '"Message Username"', find: '"Message Username"',
replacement: { replacement: {
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?}\),\i(?=\])/, match: /\.Messages\.GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE.+?}\),\i(?=\])/,
replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])" replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
} }
} }

View file

@ -25,7 +25,7 @@ export default definePlugin({
authors: [Devs.Arjix, Devs.hunt, Devs.Ven], authors: [Devs.Arjix, Devs.hunt, Devs.Ven],
patches: [ patches: [
{ {
find: "#{intl::EDIT_TEXTAREA_HELP}", find: ".Messages.EDIT_TEXTAREA_HELP",
replacement: { replacement: {
match: /(?<=,channel:\i\}\)\.then\().+?(?=return \i\.content!==this\.props\.message\.content&&\i\((.+?)\))/, match: /(?<=,channel:\i\}\)\.then\().+?(?=return \i\.content!==this\.props\.message\.content&&\i\((.+?)\))/,
replace: (match, args) => "" + replace: (match, args) => "" +

View file

@ -24,9 +24,9 @@ export default definePlugin({
description: "API to add buttons to message popovers.", description: "API to add buttons to message popovers.",
authors: [Devs.KingFish, Devs.Ven, Devs.Nuckyz], authors: [Devs.KingFish, Devs.Ven, Devs.Nuckyz],
patches: [{ patches: [{
find: "#{intl::MESSAGE_UTILITIES_A11Y_LABEL}", find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
replacement: { replacement: {
match: /\.jsx\)\((\i\.\i),\{label:\i\.\i\.string\(\i\.\i#{intl::MESSAGE_ACTION_REPLY}.{0,200}?"reply-self".{0,50}?\}\):null(?=,.+?message:(\i))/, 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)" replace: "$&,Vencord.Api.MessagePopover._buildPopoverElements($1,$2)"
} }
}], }],

View file

@ -25,16 +25,16 @@ export default definePlugin({
description: "Api required for plugins that modify the server list", description: "Api required for plugins that modify the server list",
patches: [ patches: [
{ {
find: "#{intl::DISCODO_DISABLED}", find: "Messages.DISCODO_DISABLED",
replacement: { 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))" replace: "[$1].concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Above))"
} }
}, },
{ {
find: "#{intl::SERVERS}),children", find: "Messages.SERVERS,children",
replacement: { 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($&)" replace: "Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($&)"
} }
} }

View file

@ -20,6 +20,7 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, StartAt } from "@utils/types"; import definePlugin, { OptionType, StartAt } from "@utils/types";
import { WebpackRequire } from "webpack";
const settings = definePluginSettings({ const settings = definePluginSettings({
disableAnalytics: { disableAnalytics: {
@ -48,7 +49,7 @@ export default definePlugin({
}, },
}, },
{ {
find: ".METRICS", find: ".METRICS,",
replacement: [ replacement: [
{ {
match: /this\._intervalId=/, match: /this\._intervalId=/,
@ -59,7 +60,15 @@ export default definePlugin({
replace: "$&return;" replace: "$&return;"
} }
] ]
},
{
find: ".installedLogHooks)",
replacement: {
// if getDebugLogging() returns false, the hooks don't get installed.
match: "getDebugLogging(){",
replace: "getDebugLogging(){return false;"
} }
},
], ],
startAt: StartAt.Init, startAt: StartAt.Init,
@ -73,9 +82,9 @@ export default definePlugin({
Object.defineProperty(Function.prototype, "g", { Object.defineProperty(Function.prototype, "g", {
configurable: true, configurable: true,
set(v: any) { set(this: WebpackRequire, globalObj: WebpackRequire["g"]) {
Object.defineProperty(this, "g", { Object.defineProperty(this, "g", {
value: v, value: globalObj,
configurable: true, configurable: true,
enumerable: true, enumerable: true,
writable: true writable: true
@ -84,11 +93,11 @@ export default definePlugin({
// Ensure this is most likely the Sentry WebpackInstance. // Ensure this is most likely the Sentry WebpackInstance.
// Function.g is a very generic property and is not uncommon for another WebpackInstance (or even a React component: <g></g>) to include it // Function.g is a very generic property and is not uncommon for another WebpackInstance (or even a React component: <g></g>) to include it
const { stack } = new Error(); const { stack } = new Error();
if (!(stack?.includes("discord.com") || stack?.includes("discordapp.com")) || !String(this).includes("exports:{}") || this.c != null) { if (this.c != null || !stack?.includes("http") || !String(this).includes("exports:{}")) {
return; return;
} }
const assetPath = stack?.match(/\/assets\/.+?\.js/)?.[0]; const assetPath = stack.match(/http.+?(?=:\d+?:\d+?$)/m)?.[0];
if (!assetPath) { if (!assetPath) {
return; return;
} }
@ -98,7 +107,8 @@ export default definePlugin({
srcRequest.send(); srcRequest.send();
// Final condition to see if this is the Sentry WebpackInstance // Final condition to see if this is the Sentry WebpackInstance
if (!srcRequest.responseText.includes("window.DiscordSentry=")) { // This is matching window.DiscordSentry=, but without `window` to avoid issues on some proxies
if (!srcRequest.responseText.includes(".DiscordSentry=")) {
return; return;
} }

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { Settings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import BackupAndRestoreTab from "@components/VencordSettings/BackupAndRestoreTab"; import BackupAndRestoreTab from "@components/VencordSettings/BackupAndRestoreTab";
import CloudTab from "@components/VencordSettings/CloudTab"; import CloudTab from "@components/VencordSettings/CloudTab";
import PatchHelperTab from "@components/VencordSettings/PatchHelperTab"; import PatchHelperTab from "@components/VencordSettings/PatchHelperTab";
@ -25,20 +25,35 @@ import ThemesTab from "@components/VencordSettings/ThemesTab";
import UpdaterTab from "@components/VencordSettings/UpdaterTab"; import UpdaterTab from "@components/VencordSettings/UpdaterTab";
import VencordTab from "@components/VencordSettings/VencordTab"; import VencordTab from "@components/VencordSettings/VencordTab";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { React } from "@webpack/common"; import { i18n, React } from "@webpack/common";
import gitHash from "~git-hash"; import gitHash from "~git-hash";
type SectionType = "HEADER" | "DIVIDER" | "CUSTOM"; type SectionType = "HEADER" | "DIVIDER" | "CUSTOM";
type SectionTypes = Record<SectionType, SectionType>; type SectionTypes = Record<SectionType, SectionType>;
const settings = definePluginSettings({
settingsLocation: {
type: OptionType.SELECT,
description: "Where to put the Vencord settings section",
options: [
{ label: "At the very top", value: "top" },
{ label: "Above the Nitro section", value: "aboveNitro", default: true },
{ label: "Below the Nitro section", value: "belowNitro" },
{ label: "Above Activity Settings", value: "aboveActivity" },
{ label: "Below Activity Settings", value: "belowActivity" },
{ label: "At the very bottom", value: "bottom" },
]
}
});
export default definePlugin({ export default definePlugin({
name: "Settings", name: "Settings",
description: "Adds Settings UI and debug info", description: "Adds Settings UI and debug info",
authors: [Devs.Ven, Devs.Megu], authors: [Devs.Ven, Devs.Megu],
required: true, required: true,
settings,
patches: [ patches: [
{ {
@ -58,20 +73,20 @@ export default definePlugin({
] ]
}, },
{ {
find: ".SEARCH_NO_RESULTS&&0===", find: "Messages.ACTIVITY_SETTINGS",
replacement: [ replacement: [
{ {
match: /(?<=section:(.{0,50})\.DIVIDER\}\))([,;])(?=.{0,200}(\i)\.push.{0,100}label:(\i)\.header)/, 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}` replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
}, },
{ {
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})` replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
} }
] ]
}, },
{ {
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}", find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
replacement: { replacement: {
match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.\i\).*?(\i\.\i)\.open\()/, match: /(?<=function\((\i),\i\)\{)(?=let \i=Object.values\(\i.\i\).*?(\i\.\i)\.open\()/,
replace: "$2.open($1);return;" replace: "$2.open($1);return;"
@ -137,30 +152,25 @@ export default definePlugin({
].filter(Boolean); ].filter(Boolean);
}, },
isRightSpot({ header, settings }: { header?: string; settings?: string[]; }) { isRightSpot({ header, settingsChilds }: { header?: string; settingsChilds?: string[]; }) {
const firstChild = settings?.[0]; const firstChild = settingsChilds?.[0];
// lowest two elements... sanity backup // lowest two elements... sanity backup
if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true; if (firstChild === "LOGOUT" || firstChild === "SOCIAL_LINKS") return true;
const { settingsLocation } = Settings.plugins.Settings; const { settingsLocation } = settings.store;
if (settingsLocation === "bottom") return firstChild === "LOGOUT"; if (settingsLocation === "bottom") return firstChild === "LOGOUT";
if (settingsLocation === "belowActivity") return firstChild === "CHANGELOG"; if (settingsLocation === "belowActivity") return firstChild === "CHANGELOG";
if (!header) return; if (!header) return;
try {
const names = { const names = {
top: getIntlMessage("USER_SETTINGS"), top: i18n.Messages.USER_SETTINGS,
aboveNitro: getIntlMessage("BILLING_SETTINGS"), aboveNitro: i18n.Messages.BILLING_SETTINGS,
belowNitro: getIntlMessage("APP_SETTINGS"), belowNitro: i18n.Messages.APP_SETTINGS,
aboveActivity: getIntlMessage("ACTIVITY_SETTINGS") aboveActivity: i18n.Messages.ACTIVITY_SETTINGS
}; };
return header === names[settingsLocation]; return header === names[settingsLocation];
} catch {
return firstChild === "PREMIUM";
}
}, },
patchedSettings: new WeakSet(), patchedSettings: new WeakSet(),
@ -187,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() { get electronVersion() {
return VencordNative.native.getVersions().electron || window.legcord?.electron || null; return VencordNative.native.getVersions().electron || window.armcord?.electron || null;
}, },
get chromiumVersion() { get chromiumVersion() {

View file

@ -59,7 +59,7 @@ const TrustedRolesIds = [
const AsyncFunction = async function () { }.constructor; const AsyncFunction = async function () { }.constructor;
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!; const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame");
async function forceUpdate() { async function forceUpdate() {
const outdated = await checkForUpdates(); const outdated = await checkForUpdates();
@ -77,7 +77,7 @@ async function generateDebugInfoMessage() {
const client = (() => { const client = (() => {
if (IS_DISCORD_DESKTOP) return `Discord Desktop v${DiscordNative.app.getVersion()}`; if (IS_DISCORD_DESKTOP) return `Discord Desktop v${DiscordNative.app.getVersion()}`;
if (IS_VESKTOP) return `Vesktop v${VesktopNative.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 // @ts-expect-error
const name = typeof unsafeWindow !== "undefined" ? "UserScript" : "Web"; const name = typeof unsafeWindow !== "undefined" ? "UserScript" : "Web";
@ -142,15 +142,15 @@ export default definePlugin({
required: true, required: true,
description: "Helps us provide support to you", description: "Helps us provide support to you",
authors: [Devs.Ven], authors: [Devs.Ven],
dependencies: ["UserSettingsAPI", "MessageAccessoriesAPI"], dependencies: ["CommandsAPI", "UserSettingsAPI", "MessageAccessoriesAPI"],
settings, settings,
patches: [{ patches: [{
find: "#{intl::BEGINNING_DM}", find: ".BEGINNING_DM.format",
replacement: { replacement: {
match: /#{intl::BEGINNING_DM},{.+?}\),(?=.{0,300}(\i)\.isMultiUserDM)/, match: /BEGINNING_DM\.format\(\{.+?\}\),(?=.{0,100}userId:(\i\.getRecipientId\(\)))/,
replace: "$& $self.renderContributorDmWarningCard({ channel: $1 })," replace: "$& $self.ContributorDmWarningCard({ userId: $1 }),"
} }
}], }],
@ -235,8 +235,7 @@ export default definePlugin({
} }
}, },
renderContributorDmWarningCard: ErrorBoundary.wrap(({ channel }) => { ContributorDmWarningCard: ErrorBoundary.wrap(({ userId }) => {
const userId = channel.getRecipientId();
if (!isPluginDev(userId)) return null; if (!isPluginDev(userId)) return null;
if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id)) return null; if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id)) return 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;
originalPopout: () => React.ReactNode;
}
const UserProfile = findComponentByCodeLazy("UserProfilePopoutWrapper: user cannot be undefined");
const styles = findByPropsLazy("accountProfilePopoutWrapper");
let openAlternatePopout = false;
let accountPanelRef: React.MutableRefObject<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: /(?<=\.SIZE_32\)}\);)/,
replace: "$self.useAccountPanelRef();"
},
{
match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/,
replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},originalPopout:()=>{${originalPopout}}})`
},
{
match: /\.AVATAR,children:.+?(?=renderPopout:)/,
replace: "$&onRequestClose:$self.onPopoutClose,"
},
{
match: /(?<=.avatarWrapper,)/,
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, originalPopout }: UserProfileProps) => {
if (
(settings.store.prioritizeServerProfile && openAlternatePopout) ||
(!settings.store.prioritizeServerProfile && !openAlternatePopout)
) {
return originalPopout();
}
const currentChannel = getCurrentChannel();
if (currentChannel?.getGuildId() == null) {
return originalPopout();
}
return (
<div className={styles.accountProfilePopoutWrapper}>
<UserProfile {...popoutProps} userId={currentUser.id} guildId={currentChannel.getGuildId()} channelId={currentChannel.id} />
</div>
);
}, { noop: true })
});

View file

@ -41,7 +41,7 @@ export default definePlugin({
}, },
{ {
// Status emojis // Status emojis
find: "#{intl::GUILD_OWNER}", find: ".Messages.GUILD_OWNER,",
replacement: { replacement: {
match: /(?<=\.activityEmoji,.+?animate:)\i/, match: /(?<=\.activityEmoji,.+?animate:)\i/,
replace: "!0" 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

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

View file

@ -24,7 +24,7 @@ interface ActivityButton {
} }
interface Activity { interface Activity {
state?: string; state: string;
details?: string; details?: string;
timestamps?: { timestamps?: {
start?: number; start?: number;
@ -52,8 +52,8 @@ const enum ActivityFlag {
export interface TrackData { export interface TrackData {
name: string; name: string;
album?: string; album: string;
artist?: string; artist: string;
appleMusicLink?: string; appleMusicLink?: string;
songLink?: string; songLink?: string;
@ -61,8 +61,8 @@ export interface TrackData {
albumArtwork?: string; albumArtwork?: string;
artistArtwork?: string; artistArtwork?: string;
playerPosition?: number; playerPosition: number;
duration?: number; duration: number;
} }
const enum AssetImageType { const enum AssetImageType {
@ -120,7 +120,7 @@ const settings = definePluginSettings({
stateString: { stateString: {
type: OptionType.STRING, type: OptionType.STRING,
description: "Activity state format string", description: "Activity state format string",
default: "{artist} · {album}" default: "{artist}"
}, },
largeImageType: { largeImageType: {
type: OptionType.SELECT, type: OptionType.SELECT,
@ -155,8 +155,8 @@ const settings = definePluginSettings({
function customFormat(formatStr: string, data: TrackData) { function customFormat(formatStr: string, data: TrackData) {
return formatStr return formatStr
.replaceAll("{name}", data.name) .replaceAll("{name}", data.name)
.replaceAll("{album}", data.album ?? "") .replaceAll("{album}", data.album)
.replaceAll("{artist}", data.artist ?? ""); .replaceAll("{artist}", data.artist);
} }
function getImageAsset(type: AssetImageType, data: TrackData) { function getImageAsset(type: AssetImageType, data: TrackData) {
@ -212,16 +212,14 @@ export default definePlugin({
const assets: ActivityAssets = {}; const assets: ActivityAssets = {};
const isRadio = Number.isNaN(trackData.duration) && (trackData.playerPosition === 0);
if (settings.store.largeImageType !== AssetImageType.Disabled) { if (settings.store.largeImageType !== AssetImageType.Disabled) {
assets.large_image = largeImageAsset; assets.large_image = largeImageAsset;
if (!isRadio) assets.large_text = customFormat(settings.store.largeTextString, trackData); assets.large_text = customFormat(settings.store.largeTextString, trackData);
} }
if (settings.store.smallImageType !== AssetImageType.Disabled) { if (settings.store.smallImageType !== AssetImageType.Disabled) {
assets.small_image = smallImageAsset; assets.small_image = smallImageAsset;
if (!isRadio) assets.small_text = customFormat(settings.store.smallTextString, trackData); assets.small_text = customFormat(settings.store.smallTextString, trackData);
} }
const buttons: ActivityButton[] = []; const buttons: ActivityButton[] = [];
@ -245,17 +243,17 @@ export default definePlugin({
name: customFormat(settings.store.nameString, trackData), name: customFormat(settings.store.nameString, trackData),
details: customFormat(settings.store.detailsString, trackData), details: customFormat(settings.store.detailsString, trackData),
state: isRadio ? undefined : customFormat(settings.store.stateString, trackData), state: customFormat(settings.store.stateString, trackData),
timestamps: (trackData.playerPosition && trackData.duration && settings.store.enableTimestamps) ? { timestamps: (settings.store.enableTimestamps ? {
start: Date.now() - (trackData.playerPosition * 1000), start: Date.now() - (trackData.playerPosition * 1000),
end: Date.now() - (trackData.playerPosition * 1000) + (trackData.duration * 1000), end: Date.now() - (trackData.playerPosition * 1000) + (trackData.duration * 1000),
} : undefined, } : undefined),
assets, assets,
buttons: !isRadio && buttons.length ? buttons.map(v => v.label) : undefined, buttons: buttons.length ? buttons.map(v => v.label) : undefined,
metadata: !isRadio && buttons.length ? { button_urls: buttons.map(v => v.url) } : undefined, metadata: { button_urls: buttons.map(v => v.url) || undefined, },
type: settings.store.activityType, type: settings.store.activityType,
flags: ActivityFlag.INSTANCE, flags: ActivityFlag.INSTANCE,

View file

@ -11,11 +11,37 @@ import type { TrackData } from ".";
const exec = promisify(execFile); const exec = promisify(execFile);
// function exec(file: string, args: string[] = []) {
// return new Promise<{ code: number | null, stdout: string | null, stderr: string | null; }>((resolve, reject) => {
// const process = spawn(file, args, { stdio: [null, "pipe", "pipe"] });
// let stdout: string | null = null;
// process.stdout.on("data", (chunk: string) => { stdout ??= ""; stdout += chunk; });
// let stderr: string | null = null;
// process.stderr.on("data", (chunk: string) => { stdout ??= ""; stderr += chunk; });
// process.on("exit", code => { resolve({ code, stdout, stderr }); });
// process.on("error", err => reject(err));
// });
// }
async function applescript(cmds: string[]) { async function applescript(cmds: string[]) {
const { stdout } = await exec("osascript", cmds.map(c => ["-e", c]).flat()); const { stdout } = await exec("osascript", cmds.map(c => ["-e", c]).flat());
return stdout; return stdout;
} }
function makeSearchUrl(type: string, query: string) {
const url = new URL("https://tools.applemediaservices.com/api/apple-media/music/US/search.json");
url.searchParams.set("types", type);
url.searchParams.set("limit", "1");
url.searchParams.set("term", query);
return url;
}
const requestOptions: RequestInit = {
headers: { "user-agent": "Mozilla/5.0 (Windows NT 10.0; rv:125.0) Gecko/20100101 Firefox/125.0" },
};
interface RemoteData { interface RemoteData {
appleMusicLink?: string, appleMusicLink?: string,
songLink?: string, songLink?: string,
@ -25,24 +51,6 @@ interface RemoteData {
let cachedRemoteData: { id: string, data: RemoteData; } | { id: string, failures: number; } | null = null; let cachedRemoteData: { id: string, data: RemoteData; } | { id: string, failures: number; } | null = null;
const APPLE_MUSIC_BUNDLE_REGEX = /<script type="module" crossorigin src="([a-zA-Z0-9.\-/]+)"><\/script>/;
const APPLE_MUSIC_TOKEN_REGEX = /\w+="([A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*)",\w+="x-apple-jingle-correlation-key"/;
let cachedToken: string | undefined = undefined;
const getToken = async () => {
if (cachedToken) return cachedToken;
const html = await fetch("https://music.apple.com/").then(r => r.text());
const bundleUrl = new URL(html.match(APPLE_MUSIC_BUNDLE_REGEX)![1], "https://music.apple.com/");
const bundle = await fetch(bundleUrl).then(r => r.text());
const token = bundle.match(APPLE_MUSIC_TOKEN_REGEX)![1];
cachedToken = token;
return token;
};
async function fetchRemoteData({ id, name, artist, album }: { id: string, name: string, artist: string, album: string; }) { async function fetchRemoteData({ id, name, artist, album }: { id: string, name: string, artist: string, album: string; }) {
if (id === cachedRemoteData?.id) { if (id === cachedRemoteData?.id) {
if ("data" in cachedRemoteData) return cachedRemoteData.data; if ("data" in cachedRemoteData) return cachedRemoteData.data;
@ -50,39 +58,21 @@ async function fetchRemoteData({ id, name, artist, album }: { id: string, name:
} }
try { try {
const dataUrl = new URL("https://amp-api-edge.music.apple.com/v1/catalog/us/search"); const [songData, artistData] = await Promise.all([
dataUrl.searchParams.set("platform", "web"); fetch(makeSearchUrl("songs", artist + " " + album + " " + name), requestOptions).then(r => r.json()),
dataUrl.searchParams.set("l", "en-US"); fetch(makeSearchUrl("artists", artist.split(/ *[,&] */)[0]), requestOptions).then(r => r.json())
dataUrl.searchParams.set("limit", "1"); ]);
dataUrl.searchParams.set("with", "serverBubbles");
dataUrl.searchParams.set("types", "songs");
dataUrl.searchParams.set("term", `${name} ${artist} ${album}`);
dataUrl.searchParams.set("include[songs]", "artists");
const token = await getToken(); const appleMusicLink = songData?.songs?.data[0]?.attributes.url;
const songLink = songData?.songs?.data[0]?.id ? `https://song.link/i/${songData?.songs?.data[0]?.id}` : undefined;
const songData = await fetch(dataUrl, { const albumArtwork = songData?.songs?.data[0]?.attributes.artwork.url.replace("{w}", "512").replace("{h}", "512");
headers: { const artistArtwork = artistData?.artists?.data[0]?.attributes.artwork.url.replace("{w}", "512").replace("{h}", "512");
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"authorization": `Bearer ${token}`,
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"origin": "https://music.apple.com",
},
})
.then(r => r.json())
.then(data => data.results.song.data[0]);
cachedRemoteData = { cachedRemoteData = {
id, id,
data: { data: { appleMusicLink, songLink, albumArtwork, artistArtwork }
appleMusicLink: songData.attributes.url,
songLink: `https://song.link/i/${songData.id}`,
albumArtwork: songData.attributes.artwork.url.replace("{w}x{h}", "512x512"),
artistArtwork: songData.relationships.artists.data[0].attributes.artwork.url.replace("{w}x{h}", "512x512"),
}
}; };
return cachedRemoteData.data; return cachedRemoteData.data;
} catch (e) { } catch (e) {
console.error("[AppleMusicRichPresence] Failed to fetch remote data:", e); console.error("[AppleMusicRichPresence] Failed to fetch remote data:", e);

View file

@ -20,10 +20,10 @@ import { popNotice, showNotice } from "@api/Notices";
import { Link } from "@components/Link"; import { Link } from "@components/Link";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { ReporterTestable } from "@utils/types"; import definePlugin, { ReporterTestable } from "@utils/types";
import { findByCodeLazy } from "@webpack"; import { findByCode } from "@webpack";
import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common"; import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common";
const fetchApplicationsRPC = findByCodeLazy("APPLICATION_RPC(", "Client ID"); const fetchApplicationsRPC = findByCode("APPLICATION_RPC(", "Client ID");
async function lookupAsset(applicationId: string, key: string): Promise<string> { async function lookupAsset(applicationId: string, key: string): Promise<string> {
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0]; return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
@ -73,8 +73,8 @@ export default definePlugin({
}, },
async start() { async start() {
// Legcord comes with its own arRPC implementation, so this plugin just confuses users // ArmCord comes with its own arRPC implementation, so this plugin just confuses users
if ("legcord" in window) return; if ("armcord" in window) return;
if (ws) ws.close(); if (ws) ws.close();
ws = new WebSocket("ws://127.0.0.1:1337"); // try to open WebSocket ws = new WebSocket("ws://127.0.0.1:1337"); // try to open WebSocket

View file

@ -36,7 +36,7 @@ export default definePlugin({
settings, settings,
patches: [ patches: [
{ {
find: "#{intl::BAN_CONFIRM_TITLE}", find: "BAN_CONFIRM_TITLE.",
replacement: { replacement: {
match: /src:\i\("?\d+"?\)/g, match: /src:\i\("?\d+"?\)/g,
replace: "src:$self.source" replace: "src:$self.source"

View file

@ -17,15 +17,15 @@
*/ */
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; import { findByProps, findComponentByCode, findStore } from "@webpack";
import { useStateFromStores } from "@webpack/common"; import { useStateFromStores } from "@webpack/common";
import type { CSSProperties } from "react"; import type { CSSProperties } from "react";
import { ExpandedGuildFolderStore, settings } from "."; import { ExpandedGuildFolderStore, settings } from ".";
const ChannelRTCStore = findStoreLazy("ChannelRTCStore"); const ChannelRTCStore = findStore("ChannelRTCStore");
const Animations = findByPropsLazy("a", "animated", "useTransition"); const Animations = findByProps("a", "animated", "useTransition");
const GuildsBar = findComponentByCodeLazy('("guildsnav")'); const GuildsBar = findComponentByCode('("guildsnav")');
export default ErrorBoundary.wrap(guildsBarProps => { export default ErrorBoundary.wrap(guildsBarProps => {
const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders()); const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());

View file

@ -1,11 +0,0 @@
# Better Folders
Better Folders offers a variety of options to improve your folder experience
Always show the folder icon, regardless of if the folder is open or not
Only have one folder open at a time
Open folders in a sidebar:
![A folder open in a separate sidebar](https://github.com/user-attachments/assets/432d3146-8091-4bae-9c1e-c19046c72947)

View file

@ -18,10 +18,9 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack"; import { find, findByProps, findStore } from "@webpack";
import { FluxDispatcher, useMemo } from "@webpack/common"; import { FluxDispatcher, i18n, useMemo } from "@webpack/common";
import FolderSideBar from "./FolderSideBar"; import FolderSideBar from "./FolderSideBar";
@ -31,10 +30,10 @@ enum FolderIconDisplay {
MoreThanOneFolderExpanded MoreThanOneFolderExpanded
} }
export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore"); const GuildsTree = find(m => m.prototype?.moveNextTo);
const SortedGuildStore = findStoreLazy("SortedGuildStore"); const SortedGuildStore = findStore("SortedGuildStore");
const GuildsTree = findLazy(m => m.prototype?.moveNextTo); export const ExpandedGuildFolderStore = findStore("ExpandedGuildFolderStore");
const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand"); const FolderUtils = findByProps("move", "toggleGuildFolderExpand");
let lastGuildId = null as string | null; let lastGuildId = null as string | null;
let dispatchingFoldersClose = false; let dispatchingFoldersClose = false;
@ -119,22 +118,22 @@ export default definePlugin({
// If we are rendering the Better Folders sidebar, we filter out guilds that are not in folders and unexpanded folders // If we are rendering the Better Folders sidebar, we filter out guilds that are not in folders and unexpanded folders
{ {
match: /\[(\i)\]=(\(0,\i\.\i\).{0,40}getGuildsTree\(\).+?}\))(?=,)/, match: /\[(\i)\]=(\(0,\i\.\i\).{0,40}getGuildsTree\(\).+?}\))(?=,)/,
replace: (_, originalTreeVar, rest) => `[betterFoldersOriginalTree]=${rest},${originalTreeVar}=$self.getGuildTree(!!arguments[0]?.isBetterFolders,betterFoldersOriginalTree,arguments[0]?.betterFoldersExpandedIds)` replace: (_, originalTreeVar, rest) => `[betterFoldersOriginalTree]=${rest},${originalTreeVar}=$self.getGuildTree(!!arguments[0].isBetterFolders,betterFoldersOriginalTree,arguments[0].betterFoldersExpandedIds)`
}, },
// If we are rendering the Better Folders sidebar, we filter out everything but the servers and folders from the GuildsBar Guild List children // If we are rendering the Better Folders sidebar, we filter out everything but the servers and folders from the GuildsBar Guild List children
{ {
match: /lastTargetNode:\i\[\i\.length-1\].+?Fragment.+?\]}\)\]/, match: /lastTargetNode:\i\[\i\.length-1\].+?Fragment.+?\]}\)\]/,
replace: "$&.filter($self.makeGuildsBarGuildListFilter(!!arguments[0]?.isBetterFolders))" replace: "$&.filter($self.makeGuildsBarGuildListFilter(!!arguments[0].isBetterFolders))"
}, },
// If we are rendering the Better Folders sidebar, we filter out everything but the scroller for the guild list from the GuildsBar Tree children // If we are rendering the Better Folders sidebar, we filter out everything but the scroller for the guild list from the GuildsBar Tree children
{ {
match: /unreadMentionsIndicatorBottom,.+?}\)\]/, match: /unreadMentionsIndicatorBottom,.+?}\)\]/,
replace: "$&.filter($self.makeGuildsBarTreeFilter(!!arguments[0]?.isBetterFolders))" replace: "$&.filter($self.makeGuildsBarTreeFilter(!!arguments[0].isBetterFolders))"
}, },
// Export the isBetterFolders variable to the folders component // Export the isBetterFolders variable to the folders component
{ {
match: /switch\(\i\.type\){case \i\.\i\.FOLDER:.+?folderNode:\i,/, match: /(?<=\.Messages\.SERVERS.+?switch\((\i)\.type\){case \i\.\i\.FOLDER:.+?folderNode:\i,)/,
replace: '$&isBetterFolders:typeof isBetterFolders!=="undefined"?isBetterFolders:false,' replace: 'isBetterFolders:typeof isBetterFolders!=="undefined"?isBetterFolders:false,'
} }
] ]
}, },
@ -168,31 +167,31 @@ export default definePlugin({
{ {
predicate: () => settings.store.keepIcons, predicate: () => settings.store.keepIcons,
match: /(?<=let{folderNode:\i,setNodeRef:\i,.+?expanded:(\i),.+?;)(?=let)/, match: /(?<=let{folderNode:\i,setNodeRef:\i,.+?expanded:(\i),.+?;)(?=let)/,
replace: (_, isExpanded) => `${isExpanded}=!!arguments[0]?.isBetterFolders&&${isExpanded};` replace: (_, isExpanded) => `${isExpanded}=!!arguments[0].isBetterFolders&&${isExpanded};`
}, },
// Disable expanding and collapsing folders transition in the normal GuildsBar sidebar // Disable expanding and collapsing folders transition in the normal GuildsBar sidebar
{ {
predicate: () => !settings.store.keepIcons, predicate: () => !settings.store.keepIcons,
match: /(?<=#{intl::SERVER_FOLDER_PLACEHOLDER}.+?useTransition\)\()/, match: /(?<=\.Messages\.SERVER_FOLDER_PLACEHOLDER.+?useTransition\)\()/,
replace: "$self.shouldShowTransition(arguments[0])&&" replace: "!!arguments[0].isBetterFolders&&"
}, },
// If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded // If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded
{ {
predicate: () => !settings.store.keepIcons, predicate: () => !settings.store.keepIcons,
match: /expandedFolderBackground,.+?,(?=\i\(\(\i,\i,\i\)=>{let{key.{0,45}ul)(?<=selected:\i,expanded:(\i),.+?)/, match: /expandedFolderBackground,.+?,(?=\i\(\(\i,\i,\i\)=>{let{key.{0,45}ul)(?<=selected:\i,expanded:(\i),.+?)/,
replace: (m, isExpanded) => `${m}$self.shouldRenderContents(arguments[0],${isExpanded})?null:` replace: (m, isExpanded) => `${m}!arguments[0].isBetterFolders&&${isExpanded}?null:`
}, },
{ {
// Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar // Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar
predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always, predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,
match: /(?<=\.wrapper,children:\[)/, match: /(?<=\.wrapper,children:\[)/,
replace: "$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)&&" replace: "$self.shouldShowFolderIconAndBackground(!!arguments[0].isBetterFolders,arguments[0].betterFoldersExpandedIds)&&"
}, },
{ {
// Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar // Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar
predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always, predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,
match: /(?<=\.expandedFolderBackground.+?}\),)(?=\i,)/, match: /(?<=\.expandedFolderBackground.+?}\),)(?=\i,)/,
replace: "!$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)?null:" replace: "!$self.shouldShowFolderIconAndBackground(!!arguments[0].isBetterFolders,arguments[0].betterFoldersExpandedIds)?null:"
} }
] ]
}, },
@ -201,12 +200,12 @@ export default definePlugin({
predicate: () => settings.store.sidebar, predicate: () => settings.store.sidebar,
replacement: { replacement: {
// Render the Better Folders sidebar // Render the Better Folders sidebar
match: /(container.{0,50}({className:\i\.guilds,themeOverride:\i})\))/, match: /(?<=({className:\i\.guilds,themeOverride:\i})\))/,
replace: "$1,$self.FolderSideBar({...$2})" replace: ",$self.FolderSideBar($1)"
} }
}, },
{ {
find: "#{intl::DISCODO_DISABLED}", find: ".Messages.DISCODO_DISABLED",
predicate: () => settings.store.closeAllHomeButton, predicate: () => settings.store.closeAllHomeButton,
replacement: { replacement: {
// Close all folders when clicking the home button // Close all folders when clicking the home button
@ -277,11 +276,7 @@ export default definePlugin({
makeGuildsBarGuildListFilter(isBetterFolders: boolean) { makeGuildsBarGuildListFilter(isBetterFolders: boolean) {
return child => { return child => {
if (isBetterFolders) { if (isBetterFolders) {
try { return child?.props?.["aria-label"] === i18n.Messages.SERVERS;
return child?.props?.["aria-label"] === getIntlMessage("SERVERS");
} catch (e) {
console.error(e);
}
} }
return true; return true;
}; };
@ -311,20 +306,7 @@ export default definePlugin({
} }
}, },
shouldShowTransition(props: any) { FolderSideBar: guildsBarProps => <FolderSideBar {...guildsBarProps} />,
// Pending guilds
if (props?.folderNode?.id === 1) return true;
return !!props?.isBetterFolders; closeFolders
},
shouldRenderContents(props: any, isExpanded: boolean) {
// Pending guilds
if (props?.folderNode?.id === 1) return false;
return !props?.isBetterFolders && isExpanded;
},
FolderSideBar,
closeFolders,
}); });

View file

@ -34,9 +34,9 @@ export default definePlugin({
}, },
}, },
{ {
find: "#{intl::GIF}", find: ".Messages.GIF,",
replacement: { replacement: {
match: /alt:(\i)=(\i\.\i\.string\(\i\.\i#{intl::GIF}\))(?=,[^}]*\}=(\i))/, match: /alt:(\i)=(\i\.\i\.Messages\.GIF)(?=,[^}]*\}=(\i))/,
replace: replace:
// rename prop so we can always use default value // rename prop so we can always use default value
"alt_$$:$1=$self.altify($3)||$2", "alt_$$:$1=$self.altify($3)||$2",

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { definePluginSettings, Settings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { canonicalizeMatch } from "@utils/patches"; import { canonicalizeMatch } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
@ -31,7 +31,7 @@ const settings = definePluginSettings({
noSpellCheck: { noSpellCheck: {
type: OptionType.BOOLEAN, type: OptionType.BOOLEAN,
description: "Disable spellcheck in notes", description: "Disable spellcheck in notes",
disabled: () => Settings.plugins.BetterNotesBox.hide, disabled: () => settings.store.hide,
default: false default: false
} }
}); });
@ -63,9 +63,9 @@ export default definePlugin({
} }
}, },
{ {
find: "#{intl::NOTE_PLACEHOLDER}", find: "Messages.NOTE_PLACEHOLDER",
replacement: { replacement: {
match: /#{intl::NOTE_PLACEHOLDER}\),/, match: /\.NOTE_PLACEHOLDER,/,
replace: "$&spellCheck:!$self.noSpellCheck," replace: "$&spellCheck:!$self.noSpellCheck,"
} }
} }

View file

@ -10,12 +10,12 @@ import { ImageIcon } from "@components/Icons";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getCurrentGuild, openImageModal } from "@utils/discord"; import { getCurrentGuild, openImageModal } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByProps } from "@webpack";
import { Clipboard, GuildStore, Menu, PermissionStore } from "@webpack/common"; import { Clipboard, GuildStore, Menu, PermissionStore } from "@webpack/common";
const GuildSettingsActions = findByPropsLazy("open", "selectRole", "updateGuild"); const GuildSettingsActions = findByProps("open", "selectRole", "updateGuild");
const DeveloperMode = getUserSettingLazy("appearance", "developerMode")!; const DeveloperMode = getUserSettingLazy("appearance", "developerMode");
function PencilIcon() { function PencilIcon() {
return ( return (
@ -99,11 +99,7 @@ export default definePlugin({
id="vc-view-role-icon" id="vc-view-role-icon"
label="View Role Icon" label="View Role Icon"
action={() => { action={() => {
openImageModal({ openImageModal(`${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/role-icons/${role.id}/${role.icon}.${settings.store.roleIconFileFormat}`);
url: `${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/role-icons/${role.id}/${role.icon}.${settings.store.roleIconFileFormat}`,
height: 128,
width: 128
});
}} }}
icon={ImageIcon} icon={ImageIcon}
/> />

View file

@ -16,16 +16,32 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { Settings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { Clipboard, Toasts } from "@webpack/common"; import { Clipboard, Toasts } from "@webpack/common";
const settings = definePluginSettings({
bothStyles: {
type: OptionType.BOOLEAN,
description: "Show both role dot and coloured names",
restartNeeded: true,
default: false,
},
copyRoleColorInProfilePopout: {
type: OptionType.BOOLEAN,
description: "Allow click on role dot in profile popout to copy role color",
restartNeeded: true,
default: false
}
});
export default definePlugin({ export default definePlugin({
name: "BetterRoleDot", name: "BetterRoleDot",
authors: [Devs.Ven, Devs.AutumnVN], authors: [Devs.Ven, Devs.AutumnVN],
description: description:
"Copy role colour on RoleDot (accessibility setting) click. Also allows using both RoleDot and coloured names simultaneously", "Copy role colour on RoleDot (accessibility setting) click. Also allows using both RoleDot and coloured names simultaneously",
settings,
patches: [ patches: [
{ {
@ -39,7 +55,7 @@ export default definePlugin({
find: '"dot"===', find: '"dot"===',
all: true, all: true,
noWarn: true, noWarn: true,
predicate: () => Settings.plugins.BetterRoleDot.bothStyles, predicate: () => settings.store.bothStyles,
replacement: { replacement: {
match: /"(?:username|dot)"===\i(?!\.\i)/g, match: /"(?:username|dot)"===\i(?!\.\i)/g,
replace: "true", replace: "true",
@ -47,9 +63,9 @@ export default definePlugin({
}, },
{ {
find: "#{intl::ADD_ROLE_A11Y_LABEL}", find: ".ADD_ROLE_A11Y_LABEL",
all: true, all: true,
predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles, predicate: () => settings.store.copyRoleColorInProfilePopout && !settings.store.bothStyles,
noWarn: true, noWarn: true,
replacement: { replacement: {
match: /"dot"===\i/, match: /"dot"===\i/,
@ -59,7 +75,7 @@ export default definePlugin({
{ {
find: ".roleVerifiedIcon", find: ".roleVerifiedIcon",
all: true, all: true,
predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles, predicate: () => settings.store.copyRoleColorInProfilePopout && !settings.store.bothStyles,
noWarn: true, noWarn: true,
replacement: { replacement: {
match: /"dot"===\i/, match: /"dot"===\i/,
@ -68,21 +84,6 @@ export default definePlugin({
} }
], ],
options: {
bothStyles: {
type: OptionType.BOOLEAN,
description: "Show both role dot and coloured names",
restartNeeded: true,
default: false,
},
copyRoleColorInProfilePopout: {
type: OptionType.BOOLEAN,
description: "Allow click on role dot in profile popout to copy role color",
restartNeeded: true,
default: false
}
},
copyToClipBoard(color: string) { copyToClipBoard(color: string) {
Clipboard.copy(color); Clipboard.copy(color);
Toasts.show({ Toasts.show({

View file

@ -21,20 +21,20 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findExportedComponentLazy, findStoreLazy } from "@webpack"; import { findByProps, findExportedComponent, findStore } from "@webpack";
import { Constants, React, RestAPI, Tooltip } from "@webpack/common"; import { Constants, React, RestAPI, Tooltip } from "@webpack/common";
import { RenameButton } from "./components/RenameButton"; import { RenameButton } from "./components/RenameButton";
import { Session, SessionInfo } from "./types"; import { Session, SessionInfo } from "./types";
import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils"; import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
const AuthSessionsStore = findStoreLazy("AuthSessionsStore"); const AuthSessionsStore = findStore("AuthSessionsStore");
const UserSettingsModal = findByPropsLazy("saveAccountChanges", "open"); const UserSettingsModal = findByProps("saveAccountChanges", "open");
const TimestampClasses = findByPropsLazy("timestampTooltip", "blockquoteContainer"); const TimestampClasses = findByProps("timestampTooltip", "blockquoteContainer");
const SessionIconClasses = findByPropsLazy("sessionIcon"); const SessionIconClasses = findByProps("sessionIcon");
const BlobMask = findExportedComponentLazy("BlobMask"); const BlobMask = findExportedComponent("BlobMask");
const settings = definePluginSettings({ const settings = definePluginSettings({
backgroundCheck: { backgroundCheck: {
@ -60,7 +60,7 @@ export default definePlugin({
patches: [ patches: [
{ {
find: "#{intl::AUTH_SESSIONS_SESSION_LOG_OUT}", find: "Messages.AUTH_SESSIONS_SESSION_LOG_OUT",
replacement: [ replacement: [
// Replace children with a single label with state // Replace children with a single label with state
{ {

View file

@ -1,69 +0,0 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { openPluginModal } from "@components/PluginSettings/PluginModal";
import { getIntlMessage } from "@utils/discord";
import { isObjectEmpty } from "@utils/misc";
import { Alerts, Menu, useMemo, useState } from "@webpack/common";
import Plugins from "~plugins";
function onRestartNeeded() {
Alerts.show({
title: "Restart required",
body: <p>You have changed settings that require a restart.</p>,
confirmText: "Restart now",
cancelText: "Later!",
onConfirm: () => location.reload()
});
}
export default function PluginsSubmenu() {
const sortedPlugins = useMemo(() => Object.values(Plugins)
.sort((a, b) => a.name.localeCompare(b.name)), []);
const [query, setQuery] = useState("");
const search = query.toLowerCase();
const include = (p: typeof Plugins[keyof typeof Plugins]) => (
Vencord.Plugins.isPluginEnabled(p.name)
&& p.options && !isObjectEmpty(p.options)
&& (
p.name.toLowerCase().includes(search)
|| p.description.toLowerCase().includes(search)
|| p.tags?.some(t => t.toLowerCase().includes(search))
)
);
const plugins = sortedPlugins.filter(include);
return (
<>
<Menu.MenuControlItem
id="vc-plugins-search"
control={(props, ref) => (
<Menu.MenuSearchControl
{...props}
query={query}
onChange={setQuery}
ref={ref}
placeholder={getIntlMessage("SEARCH")}
/>
)}
/>
{!!plugins.length && <Menu.MenuSeparator />}
{plugins.map(p => (
<Menu.MenuItem
key={p.name}
id={p.name}
label={p.name}
action={() => openPluginModal(p, onRestartNeeded)}
/>
))}
</>
);
}

View file

@ -7,20 +7,18 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles"; import { classNameFactory } from "@api/Styles";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
import { NoopComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { waitFor } from "@webpack"; import { findByProps } from "@webpack";
import { ComponentDispatch, FocusLock, Menu, useEffect, useRef } from "@webpack/common"; import { ComponentDispatch, FocusLock, i18n, Menu, useEffect, useRef } from "@webpack/common";
import type { HTMLAttributes, ReactElement } from "react"; import type { HTMLAttributes, ReactElement } from "react";
import PluginsSubmenu from "./PluginsSubmenu";
type SettingsEntry = { section: string, label: string; }; type SettingsEntry = { section: string, label: string; };
const cl = classNameFactory(""); const cl = classNameFactory("");
let Classes: Record<string, string>; const Classes = findByProps("animating", "baseLayer", "bg", "layer", "layers");
waitFor(["animating", "baseLayer", "bg", "layer", "layers"], m => Classes = m);
const settings = definePluginSettings({ const settings = definePluginSettings({
disableFade: { disableFade: {
@ -112,7 +110,7 @@ export default definePlugin({
predicate: () => settings.store.disableFade predicate: () => settings.store.disableFade
}, },
{ // Load menu TOC eagerly { // Load menu TOC eagerly
find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}", find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format",
replacement: { replacement: {
match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/, match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/,
replace: "$&(async ()=>$2)()," replace: "$&(async ()=>$2)(),"
@ -120,22 +118,14 @@ export default definePlugin({
predicate: () => settings.store.eagerLoad predicate: () => settings.store.eagerLoad
}, },
{ // Settings cog context menu { // Settings cog context menu
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}", find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
replacement: [ replacement: {
{
match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/, match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/,
replace: "$1$self.wrapMenu($2)" replace: "$1$self.wrapMenu($2)"
},
{
match: /case \i\.\i\.DEVELOPER_OPTIONS:return \i;/,
replace: "$&case 'VencordPlugins':return $self.PluginsSubmenu();"
} }
] }
},
], ],
PluginsSubmenu,
// This is the very outer layer of the entire ui, so we can't wrap this in an ErrorBoundary // This is the very outer layer of the entire ui, so we can't wrap this in an ErrorBoundary
// without possibly also catching unrelated errors of children. // without possibly also catching unrelated errors of children.
// //
@ -143,7 +133,7 @@ export default definePlugin({
// try catch will only catch errors in the Layer function (hence why it's called as a plain function rather than a component), but // try catch will only catch errors in the Layer function (hence why it's called as a plain function rather than a component), but
// not in children // not in children
Layer(props: LayerProps) { Layer(props: LayerProps) {
if (!FocusLock || !ComponentDispatch || !Classes) { if (FocusLock === NoopComponent || ComponentDispatch[SYM_PROXY_INNER_VALUE] == null || Classes[SYM_PROXY_INNER_VALUE] == null) {
new Logger("BetterSettings").error("Failed to find some components"); new Logger("BetterSettings").error("Failed to find some components");
return props.children; return props.children;
} }
@ -160,7 +150,7 @@ export default definePlugin({
if (item.section === "HEADER") { if (item.section === "HEADER") {
items.push({ label: item.label, items: [] }); items.push({ label: item.label, items: [] });
} else if (item.section === "DIVIDER") { } else if (item.section === "DIVIDER") {
items.push({ label: getIntlMessage("OTHER_OPTIONS"), items: [] }); items.push({ label: i18n.Messages.OTHER_OPTIONS, items: [] });
} else { } else {
items.at(-1)!.items.push(item); items.at(-1)!.items.push(item);
} }

View file

@ -57,11 +57,7 @@ export const handleViewPreview = async ({ guildId, channelId, ownerId }: Applica
const previewUrl = await ApplicationStreamPreviewStore.getPreviewURL(guildId, channelId, ownerId); const previewUrl = await ApplicationStreamPreviewStore.getPreviewURL(guildId, channelId, ownerId);
if (!previewUrl) return; if (!previewUrl) return;
openImageModal({ openImageModal(previewUrl);
url: previewUrl,
height: 720,
width: 1280
});
}; };
export const addViewStreamContext: NavContextMenuPatchCallback = (children, { userId }: { userId: string | bigint; }) => { export const addViewStreamContext: NavContextMenuPatchCallback = (children, { userId }: { userId: string | bigint; }) => {

View file

@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { findStoreLazy } from "@webpack"; import { findStore } from "@webpack";
import * as t from "./types/stores"; import * as t from "./types/stores";
export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore"); export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStore("ApplicationStreamPreviewStore");
export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore"); export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStore("ApplicationStreamingStore");

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { Settings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
@ -26,7 +26,7 @@ function setCss() {
style.textContent = ` style.textContent = `
.vc-nsfw-img [class^=imageWrapper] img, .vc-nsfw-img [class^=imageWrapper] img,
.vc-nsfw-img [class^=wrapperPaused] video { .vc-nsfw-img [class^=wrapperPaused] video {
filter: blur(${Settings.plugins.BlurNSFW.blurAmount}px); filter: blur(${settings.store.blurAmount}px);
transition: filter 0.2s; transition: filter 0.2s;
} }
.vc-nsfw-img [class^=imageWrapper]:hover img, .vc-nsfw-img [class^=imageWrapper]:hover img,
@ -36,29 +36,30 @@ function setCss() {
`; `;
} }
export default definePlugin({ const settings = definePluginSettings({
name: "BlurNSFW",
description: "Blur attachments in NSFW channels until hovered",
authors: [Devs.Ven],
patches: [
{
find: ".embedWrapper,embed",
replacement: [{
match: /\.container/,
replace: "$&+(this.props.channel.nsfw? ' vc-nsfw-img': '')"
}]
}
],
options: {
blurAmount: { blurAmount: {
type: OptionType.NUMBER, type: OptionType.NUMBER,
description: "Blur Amount", description: "Blur Amount",
default: 10, default: 10,
onChange: setCss onChange: setCss
} }
}, });
export default definePlugin({
name: "BlurNSFW",
description: "Blur attachments in NSFW channels until hovered",
authors: [Devs.Ven],
settings,
patches: [
{
find: ".embedWrapper,embed",
replacement: [{
match: /\.embedWrapper(?=.+?channel_id:(\i)\.id)/g,
replace: "$&+($1.nsfw?' vc-nsfw-img':'')"
}]
}
],
start() { start() {
style = document.createElement("style"); style = document.createElement("style");

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { Settings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { useTimer } from "@utils/react"; import { useTimer } from "@utils/react";
@ -25,7 +25,7 @@ import { React } from "@webpack/common";
function formatDuration(ms: number) { function formatDuration(ms: number) {
// here be dragons (moment fucking sucks) // here be dragons (moment fucking sucks)
const human = Settings.plugins.CallTimer.format === "human"; const human = settings.store.format === "human";
const format = (n: number) => human ? n : n.toString().padStart(2, "0"); const format = (n: number) => human ? n : n.toString().padStart(2, "0");
const unit = (s: string) => human ? s : ""; const unit = (s: string) => human ? s : "";
@ -46,15 +46,7 @@ function formatDuration(ms: number) {
return res; return res;
} }
export default definePlugin({ const settings = definePluginSettings({
name: "CallTimer",
description: "Adds a timer to vcs",
authors: [Devs.Ven],
startTime: 0,
interval: void 0 as NodeJS.Timeout | undefined,
options: {
format: { format: {
type: OptionType.SELECT, type: OptionType.SELECT,
description: "The timer format. This can be any valid moment.js format", description: "The timer format. This can be any valid moment.js format",
@ -70,7 +62,16 @@ export default definePlugin({
} }
] ]
} }
}, });
export default definePlugin({
name: "CallTimer",
description: "Adds a timer to vcs",
authors: [Devs.Ven],
settings,
startTime: 0,
interval: void 0 as NodeJS.Timeout | undefined,
patches: [{ patches: [{
find: "renderConnectionStatus(){", find: "renderConnectionStatus(){",

View file

@ -155,5 +155,4 @@ export const defaultRules = [
"igshid", "igshid",
"igsh", "igsh",
"share_id@reddit.com", "share_id@reddit.com",
"si@soundcloud.com",
]; ];

View file

@ -11,10 +11,10 @@ import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types"; import definePlugin, { OptionType, StartAt } from "@utils/types";
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; import { findByCode, findComponentByCode, findStore } from "@webpack";
import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common"; import { Button, Forms, useStateFromStores } from "@webpack/common";
const ColorPicker = findComponentByCodeLazy("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)"); const ColorPicker = findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const colorPresets = [ const colorPresets = [
"#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D", "#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D",
@ -30,20 +30,21 @@ function onPickColor(color: number) {
updateColorVars(hexColor); updateColorVars(hexColor);
} }
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"==='); const saveClientTheme = findByCode('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"===');
function setTheme(theme: string) { function setTheme(theme: string) {
saveClientTheme({ theme }); saveClientTheme({ theme });
} }
const NitroThemeStore = findStoreLazy("ClientThemesBackgroundStore"); const ThemeStore = findStore("ThemeStore");
const ClientThemesBackgroundStore = findStore("ClientThemesBackgroundStore");
function ThemeSettings() { function ThemeSettings() {
const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme); const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme);
const isLightTheme = theme === "light"; const isLightTheme = theme === "light";
const oppositeTheme = isLightTheme ? "dark" : "light"; const oppositeTheme = isLightTheme ? "dark" : "light";
const nitroTheme = useStateFromStores([NitroThemeStore], () => NitroThemeStore.gradientPreset); const nitroTheme = useStateFromStores([ClientThemesBackgroundStore], () => ClientThemesBackgroundStore.gradientPreset);
const nitroThemeEnabled = nitroTheme !== undefined; const nitroThemeEnabled = nitroTheme !== undefined;
const selectedLuminance = relativeLuminance(settings.store.color); const selectedLuminance = relativeLuminance(settings.store.color);

View file

@ -1,5 +1,5 @@
# ConsoleJanitor # ConsoleJanitor
Disables annoying console messages/errors. This plugin mainly removes errors/warnings that happen all the time and Discord logger messages. Disables annoying console messages/errors. This plugin mainly removes errors/warnings that happen all the time and noisy/spammy logging messages.
One of the disabled messages is the "Window state not initialized" warning, for example. Some of the disabled messages include the "notosans-400-normalitalic" error and MessageActionCreators, Routing/Utils loggers.

View file

@ -6,7 +6,7 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType, StartAt } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
const Noop = () => { }; const Noop = () => { };
const NoopLogger = { const NoopLogger = {
@ -22,12 +22,10 @@ const NoopLogger = {
fileOnly: Noop fileOnly: Noop
}; };
const logAllow = new Set();
const settings = definePluginSettings({ const settings = definePluginSettings({
disableLoggers: { disableNoisyLoggers: {
type: OptionType.BOOLEAN, type: OptionType.BOOLEAN,
description: "Disables Discords loggers", description: "Disable noisy loggers like the MessageActionCreators",
default: false, default: false,
restartNeeded: true restartNeeded: true
}, },
@ -36,43 +34,18 @@ const settings = definePluginSettings({
description: "Disable the Spotify logger, which leaks account information and access token", description: "Disable the Spotify logger, which leaks account information and access token",
default: true, default: true,
restartNeeded: true restartNeeded: true
},
whitelistedLoggers: {
type: OptionType.STRING,
description: "Semi colon separated list of loggers to allow even if others are hidden",
default: "GatewaySocket; Routing/Utils",
onChange(newVal: string) {
logAllow.clear();
newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));
}
} }
}); });
export default definePlugin({ export default definePlugin({
name: "ConsoleJanitor", name: "ConsoleJanitor",
description: "Disables annoying console messages/errors", description: "Disables annoying console messages/errors",
authors: [Devs.Nuckyz, Devs.sadan], authors: [Devs.Nuckyz],
settings, settings,
startAt: StartAt.Init,
start() {
logAllow.clear();
this.settings.store.whitelistedLoggers?.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));
},
NoopLogger: () => NoopLogger, NoopLogger: () => NoopLogger,
shouldLog(logger: string) {
return logAllow.has(logger);
},
patches: [ patches: [
{
find: 'react-spring: The "interpolate" function',
replacement: {
match: /,console.warn\('react-spring: The "interpolate" function is deprecated in v10 \(use "to" instead\)'\)/,
replace: ""
}
},
{ {
find: 'console.warn("Window state not initialized"', find: 'console.warn("Window state not initialized"',
replacement: { replacement: {
@ -87,6 +60,13 @@ export default definePlugin({
replace: "" replace: ""
} }
}, },
{
find: "notosans-400-normalitalic",
replacement: {
match: /,"notosans-.+?"/g,
replace: ""
}
},
{ {
find: 'console.warn("[DEPRECATED] Please use `subscribeWithSelector` middleware");', find: 'console.warn("[DEPRECATED] Please use `subscribeWithSelector` middleware");',
all: true, all: true,
@ -130,34 +110,34 @@ export default definePlugin({
replace: "" replace: ""
} }
}, },
// Zustand section ...[
{ '("MessageActionCreators")', '("ChannelMessages")',
find: "[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.", '("Routing/Utils")', '("RTCControlSocket")',
replacement: [ '("ConnectionEventFramerateReducer")', '("RTCLatencyTestManager")',
{ '("OverlayBridgeStore")', '("RPCServer:WSS")', '("RPCServer:IPC")'
match: /&&console\.warn\("\[DEPRECATED\] Passing a vanilla store will be unsupported in a future version\. Instead use `import { useStore } from 'zustand'`\."\)/, ].map(logger => ({
replace: "" find: logger,
}, predicate: () => settings.store.disableNoisyLoggers,
{ all: true,
match: /console\.warn\("\[DEPRECATED\] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`\. They can be imported from 'zustand\/traditional'\. https:\/\/github\.com\/pmndrs\/zustand\/discussions\/1937"\),/,
replace: ""
}
]
},
{
find: "[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead.",
replacement: { replacement: {
match: /console\.warn\("\[DEPRECATED\] `getStorage`, `serialize` and `deserialize` options are deprecated\. Use `storage` option instead\."\),/, match: new RegExp(String.raw`new \i\.\i${logger.replace(/([()])/g, "\\$1")}`),
replace: "" replace: `$self.NoopLogger${logger}`
}
})),
{
find: '"Experimental codecs: "',
predicate: () => settings.store.disableNoisyLoggers,
replacement: {
match: /new \i\.\i\("Connection\("\.concat\(\i,"\)"\)\)/,
replace: "$self.NoopLogger()"
} }
}, },
// Patches discords generic logger function
{ {
find: "Σ:", find: '"Handling ping: "',
predicate: () => settings.store.disableLoggers, predicate: () => settings.store.disableNoisyLoggers,
replacement: { replacement: {
match: /(?<=&&)(?=console)/, match: /new \i\.\i\("RTCConnection\("\.concat.+?\)\)(?=,)/,
replace: "$self.shouldLog(arguments[0])&&" replace: "$self.NoopLogger()"
} }
}, },
{ {

View file

@ -18,13 +18,14 @@
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getCurrentChannel, getCurrentGuild } from "@utils/discord"; import { getCurrentChannel, getCurrentGuild } from "@utils/discord";
import { runtimeHashMessageKey } from "@utils/intlHash";
import { SYM_LAZY_CACHED, SYM_LAZY_GET } from "@utils/lazy"; import { SYM_LAZY_CACHED, SYM_LAZY_GET } from "@utils/lazy";
import { SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact";
import { relaunch } from "@utils/native"; import { relaunch } from "@utils/native";
import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches"; import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches";
import { SYM_PROXY_INNER_GET, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner";
import definePlugin, { PluginNative, StartAt } from "@utils/types"; import definePlugin, { PluginNative, StartAt } from "@utils/types";
import * as Webpack from "@webpack"; import * as Webpack from "@webpack";
import { extract, filters, findAll, findModuleId, search } from "@webpack"; import { cacheFindAll, cacheFindModuleId, extract, filters, searchFactories } from "@webpack";
import * as Common from "@webpack/common"; import * as Common from "@webpack/common";
import { loadLazyChunks } from "debug/loadLazyChunks"; import { loadLazyChunks } from "debug/loadLazyChunks";
import type { ComponentType } from "react"; import type { ComponentType } from "react";
@ -33,27 +34,29 @@ const DESKTOP_ONLY = (f: string) => () => {
throw new Error(`'${f}' is Discord Desktop only.`); throw new Error(`'${f}' is Discord Desktop only.`);
}; };
const define: typeof Object.defineProperty =
(obj, prop, desc) => {
if (Object.hasOwn(desc, "value"))
desc.writable = true;
return Object.defineProperty(obj, prop, { type Define = typeof Object.defineProperty;
const define: Define = (target, p, attributes) => {
if (Object.hasOwn(attributes, "value")) {
attributes.writable = true;
}
return Object.defineProperty(target, p, {
configurable: true, configurable: true,
enumerable: true, enumerable: true,
...desc ...attributes
}); });
}; };
function makeShortcuts() { function makeShortcuts() {
function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn) { function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn, shouldReturnFactory = false) {
const cache = new Map<string, unknown>(); const cache = new Map<string, unknown>();
return function (...filterProps: unknown[]) { return function (...filterProps: unknown[]) {
const cacheKey = String(filterProps); const cacheKey = String(filterProps);
if (cache.has(cacheKey)) return cache.get(cacheKey); if (cache.has(cacheKey)) return cache.get(cacheKey);
const matches = findAll(filterFactory(...filterProps)); const matches = cacheFindAll(filterFactory(...filterProps), shouldReturnFactory);
const result = (() => { const result = (() => {
switch (matches.length) { switch (matches.length) {
@ -61,51 +64,71 @@ function makeShortcuts() {
case 1: return matches[0]; case 1: return matches[0];
default: default:
const uniqueMatches = [...new Set(matches)]; const uniqueMatches = [...new Set(matches)];
if (uniqueMatches.length > 1) if (uniqueMatches.length > 1) {
console.warn(`Warning: This filter matches ${matches.length} modules. Make it more specific!\n`, uniqueMatches); console.warn(`Warning: This filter matches ${matches.length} modules. Make it more specific!\n`, uniqueMatches);
}
return matches[0]; return uniqueMatches[0];
} }
})(); })();
if (result && cacheKey) cache.set(cacheKey, result); if (result && cacheKey) cache.set(cacheKey, result);
return result; return result;
}; };
} }
let fakeRenderWin: WeakRef<Window> | undefined; let fakeRenderWin: WeakRef<Window> | undefined;
const find = newFindWrapper(f => f); const find = newFindWrapper(f => f);
const findByProps = newFindWrapper(filters.byProps); const findByProps = newFindWrapper(filters.byProps);
return { return {
...Object.fromEntries(Object.keys(Common).map(key => [key, { getter: () => Common[key] }])),
wp: Webpack, wp: Webpack,
wpc: { getter: () => Webpack.cache }, wpc: { getter: () => Webpack.cache },
wreq: { getter: () => Webpack.wreq }, wreq: { getter: () => Webpack.wreq },
wpsearch: search,
wpex: extract, WebpackInstances: { getter: () => Vencord.WebpackPatcher.allWebpackInstances },
wpexs: (code: string) => extract(findModuleId(code)!),
loadLazyChunks: IS_DEV ? loadLazyChunks : () => { throw new Error("loadLazyChunks is dev only."); }, loadLazyChunks: IS_DEV ? loadLazyChunks : () => { throw new Error("loadLazyChunks is dev only."); },
wpsearch: searchFactories,
wpex: extract,
wpexs: (...code: Webpack.CodeFilter) => extract(cacheFindModuleId(...code)!),
filters,
find, find,
findAll: findAll, findAll: cacheFindAll,
findByProps, findComponent: find,
findAllByProps: (...props: string[]) => findAll(filters.byProps(...props)), findAllComponents: cacheFindAll,
findByCode: newFindWrapper(filters.byCode), findExportedComponent: (...props: Webpack.PropsFilter) => findByProps(...props)[props[0]],
findAllByCode: (code: string) => findAll(filters.byCode(code)),
findComponentByCode: newFindWrapper(filters.componentByCode), findComponentByCode: newFindWrapper(filters.componentByCode),
findAllComponentsByCode: (...code: string[]) => findAll(filters.componentByCode(...code)), findAllComponentsByCode: (...code: Webpack.PropsFilter) => cacheFindAll(filters.componentByCode(...code)),
findExportedComponent: (...props: string[]) => findByProps(...props)[props[0]], findComponentByFields: newFindWrapper(filters.componentByFields),
findAllComponentsByFields: (...fields: Webpack.PropsFilter) => cacheFindAll(filters.componentByFields(...fields)),
findByProps,
findAllByProps: (...props: Webpack.PropsFilter) => cacheFindAll(filters.byProps(...props)),
findProp: (...props: Webpack.PropsFilter) => findByProps(...props)[props[0]],
findByCode: newFindWrapper(filters.byCode),
findAllByCode: (code: Webpack.CodeFilter) => cacheFindAll(filters.byCode(...code)),
findStore: newFindWrapper(filters.byStoreName), findStore: newFindWrapper(filters.byStoreName),
PluginsApi: { getter: () => Vencord.Plugins }, findByFactoryCode: newFindWrapper(filters.byFactoryCode),
findAllByFactoryCode: (...code: Webpack.CodeFilter) => cacheFindAll(filters.byFactoryCode(...code)),
findModuleFactory: newFindWrapper(filters.byFactoryCode, true),
findAllModuleFactories: (...code: Webpack.CodeFilter) => cacheFindAll(filters.byFactoryCode(...code), true),
plugins: { getter: () => Vencord.Plugins.plugins }, plugins: { getter: () => Vencord.Plugins.plugins },
PluginsApi: { getter: () => Vencord.Plugins },
Settings: { getter: () => Vencord.Settings }, Settings: { getter: () => Vencord.Settings },
Api: { getter: () => Vencord.Api }, Api: { getter: () => Vencord.Api },
Util: { getter: () => Vencord.Util }, Util: { getter: () => Vencord.Util },
reload: () => location.reload(), reload: () => location.reload(),
restart: IS_WEB ? DESKTOP_ONLY("restart") : relaunch, restart: IS_WEB ? DESKTOP_ONLY("restart") : relaunch,
canonicalizeMatch, canonicalizeMatch,
canonicalizeReplace, canonicalizeReplace,
canonicalizeReplacement, canonicalizeReplacement,
runtimeHashMessageKey,
preEnable: (plugin: string) => (Vencord.Settings.plugins[plugin] ??= { enabled: true }).enabled = true,
fakeRender: (component: ComponentType, props: any) => { fakeRender: (component: ComponentType, props: any) => {
const prevWin = fakeRenderWin?.deref(); const prevWin = fakeRenderWin?.deref();
const win = prevWin?.closed === false const win = prevWin?.closed === false
@ -135,8 +158,6 @@ function makeShortcuts() {
Common.ReactDOM.render(Common.React.createElement(component, props), doc.body.appendChild(document.createElement("div"))); Common.ReactDOM.render(Common.React.createElement(component, props), doc.body.appendChild(document.createElement("div")));
}, },
preEnable: (plugin: string) => (Vencord.Settings.plugins[plugin] ??= { enabled: true }).enabled = true,
channel: { getter: () => getCurrentChannel(), preload: false }, channel: { getter: () => getCurrentChannel(), preload: false },
channelId: { getter: () => Common.SelectedChannelStore.getChannelId(), preload: false }, channelId: { getter: () => Common.SelectedChannelStore.getChannelId(), preload: false },
guild: { getter: () => getCurrentGuild(), preload: false }, guild: { getter: () => getCurrentGuild(), preload: false },
@ -145,6 +166,7 @@ function makeShortcuts() {
meId: { getter: () => Common.UserStore.getCurrentUser().id, preload: false }, meId: { getter: () => Common.UserStore.getCurrentUser().id, preload: false },
messages: { getter: () => Common.MessageStore.getMessages(Common.SelectedChannelStore.getChannelId()), preload: false }, messages: { getter: () => Common.MessageStore.getMessages(Common.SelectedChannelStore.getChannelId()), preload: false },
...Object.fromEntries(Object.keys(Common).map(key => [key, { getter: () => Common[key] }])),
Stores: { Stores: {
getter: () => Object.fromEntries( getter: () => Object.fromEntries(
Common.Flux.Store.getAll() Common.Flux.Store.getAll()
@ -159,11 +181,39 @@ function loadAndCacheShortcut(key: string, val: any, forceLoad: boolean) {
const currentVal = val.getter(); const currentVal = val.getter();
if (!currentVal || val.preload === false) return currentVal; if (!currentVal || val.preload === false) return currentVal;
const value = currentVal[SYM_LAZY_GET] function unwrapProxy(value: any) {
? forceLoad ? currentVal[SYM_LAZY_GET]() : currentVal[SYM_LAZY_CACHED] if (value[SYM_LAZY_GET]) {
: currentVal; return forceLoad ? value[SYM_LAZY_GET]() : value[SYM_LAZY_CACHED];
} else if (value[SYM_PROXY_INNER_GET]) {
return forceLoad ? value[SYM_PROXY_INNER_GET]() : value[SYM_PROXY_INNER_VALUE];
} else if (value[SYM_LAZY_COMPONENT_INNER]) {
return value[SYM_LAZY_COMPONENT_INNER]() != null ? value[SYM_LAZY_COMPONENT_INNER]() : value;
}
if (value) define(window.shortcutList, key, { value }); return value;
}
const value = unwrapProxy(currentVal);
if (value != null && typeof value === "object") {
const descriptors = Object.getOwnPropertyDescriptors(value);
for (const propKey in descriptors) {
if (value[propKey] == null) continue;
const descriptor = descriptors[propKey];
if (descriptor.writable === true || descriptor.set != null) {
const currentValue = value[propKey];
const newValue = unwrapProxy(currentValue);
if (newValue != null && currentValue !== newValue) {
value[propKey] = newValue;
}
}
}
}
if (value != null) {
define(window.shortcutList, key, { value });
}
return value; return value;
} }
@ -178,8 +228,10 @@ export default definePlugin({
const shortcuts = makeShortcuts(); const shortcuts = makeShortcuts();
window.shortcutList = {}; window.shortcutList = {};
for (const [key, val] of Object.entries(shortcuts)) { for (const key in shortcuts) {
if ("getter" in val) { const val = shortcuts[key];
if (Object.hasOwn(val, "getter")) {
define(window.shortcutList, key, { define(window.shortcutList, key, {
get: () => loadAndCacheShortcut(key, val, true) get: () => loadAndCacheShortcut(key, val, true)
}); });
@ -193,8 +245,8 @@ export default definePlugin({
} }
} }
// unproxy loaded modules // Unproxy loaded modules
Webpack.onceReady.then(() => { Webpack.onceDiscordLoaded.then(() => {
setTimeout(() => this.eagerLoad(false), 1000); setTimeout(() => this.eagerLoad(false), 1000);
if (!IS_WEB) { if (!IS_WEB) {
@ -205,13 +257,13 @@ export default definePlugin({
}, },
async eagerLoad(forceLoad: boolean) { async eagerLoad(forceLoad: boolean) {
await Webpack.onceReady; await Webpack.onceDiscordLoaded;
const shortcuts = makeShortcuts(); const shortcuts = makeShortcuts();
for (const key in shortcuts) {
const val = shortcuts[key];
for (const [key, val] of Object.entries(shortcuts)) { if (!Object.hasOwn(val, "getter") || val.preload === false) continue;
if (!Object.hasOwn(val, "getter") || (val as any).preload === false) continue;
try { try {
loadAndCacheShortcut(key, val, forceLoad); loadAndCacheShortcut(key, val, forceLoad);
} catch { } // swallow not found errors in DEV } catch { } // swallow not found errors in DEV

View file

@ -8,10 +8,10 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { copyWithToast } from "@utils/misc"; import { copyWithToast } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findProp } from "@webpack";
import { Menu } from "@webpack/common"; import { Menu } from "@webpack/common";
const { convertNameToSurrogate } = findByPropsLazy("convertNameToSurrogate"); const convertNameToSurrogate = findProp("convertNameToSurrogate");
interface Emoji { interface Emoji {
type: string; type: string;
@ -55,7 +55,7 @@ export default definePlugin({
settings, settings,
contextMenus: { contextMenus: {
"expression-picker"(children, { target }: { target: Target }) { "expression-picker"(children, { target }: { target: Target; }) {
if (target.dataset.type !== "emoji") return; if (target.dataset.type !== "emoji") return;
children.push( children.push(

View file

@ -1,5 +0,0 @@
# CopyFileContents
Adds a button to text file attachments to copy their contents.
![](https://github.com/user-attachments/assets/b1a0f6f4-106f-4953-94d9-4c5ef5810bca)

View file

@ -1,60 +0,0 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import "./style.css";
import ErrorBoundary from "@components/ErrorBoundary";
import { CopyIcon, NoEntrySignIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { copyWithToast } from "@utils/misc";
import definePlugin from "@utils/types";
import { Tooltip, useState } from "@webpack/common";
const CheckMarkIcon = () => {
return <svg width="24" height="24" viewBox="0 0 24 24">
<path fill="currentColor" d="M21.7 5.3a1 1 0 0 1 0 1.4l-12 12a1 1 0 0 1-1.4 0l-6-6a1 1 0 1 1 1.4-1.4L9 16.58l11.3-11.3a1 1 0 0 1 1.4 0Z"></path>
</svg>;
};
export default definePlugin({
name: "CopyFileContents",
description: "Adds a button to text file attachments to copy their contents",
authors: [Devs.Obsidian, Devs.Nuckyz],
patches: [
{
find: "#{intl::PREVIEW_BYTES_LEFT}",
replacement: {
match: /\.footerGap.+?url:\i,fileName:\i,fileSize:\i}\),(?<=fileContents:(\i),bytesLeft:(\i).+?)/g,
replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2}),"
}
}
],
addCopyButton: ErrorBoundary.wrap(({ fileContents, bytesLeft }: { fileContents: string, bytesLeft: number; }) => {
const [recentlyCopied, setRecentlyCopied] = useState(false);
return (
<Tooltip text={recentlyCopied ? "Copied!" : bytesLeft > 0 ? "File too large to copy" : "Copy File Contents"}>
{tooltipProps => (
<div
{...tooltipProps}
className="vc-cfc-button"
role="button"
onClick={() => {
if (!recentlyCopied && bytesLeft <= 0) {
copyWithToast(fileContents);
setRecentlyCopied(true);
setTimeout(() => setRecentlyCopied(false), 2000);
}
}}
>
{recentlyCopied ? <CheckMarkIcon /> : bytesLeft > 0 ? <NoEntrySignIcon color="var(--channel-icon)" /> : <CopyIcon />}
</div>
)}
</Tooltip>
);
}, { noop: true }),
});

View file

@ -1,9 +0,0 @@
.vc-cfc-button {
color: var(--interactive-normal);
cursor: pointer;
padding-left: 4px;
}
.vc-cfc-button:hover {
color: var(--interactive-hover);
}

View file

@ -23,22 +23,12 @@ import { Logger } from "@utils/Logger";
import { closeAllModals } from "@utils/modal"; import { closeAllModals } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { maybePromptToUpdate } from "@utils/updater"; import { maybePromptToUpdate } from "@utils/updater";
import { filters, findBulk, proxyLazyWebpack } from "@webpack"; import { findByProps } from "@webpack";
import { DraftType, ExpressionPickerStore, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common"; import { DraftType, ExpressionPickerStore, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
const CrashHandlerLogger = new Logger("CrashHandler"); const CrashHandlerLogger = new Logger("CrashHandler");
const ModalStack = findByProps("pushLazy", "popAll");
const { ModalStack, DraftManager } = proxyLazyWebpack(() => { const DraftManager = findByProps("clearDraft", "saveDraft");
const [ModalStack, DraftManager] = findBulk(
filters.byProps("pushLazy", "popAll"),
filters.byProps("clearDraft", "saveDraft"),
);
return {
ModalStack,
DraftManager
};
});
const settings = definePluginSettings({ const settings = definePluginSettings({
attemptToPreventCrashes: { attemptToPreventCrashes: {
@ -67,7 +57,7 @@ export default definePlugin({
patches: [ patches: [
{ {
find: "#{intl::ERRORS_UNEXPECTED_CRASH}", find: ".Messages.ERRORS_UNEXPECTED_CRASH",
replacement: { replacement: {
match: /this\.setState\((.+?)\)/, match: /this\.setState\((.+?)\)/,
replace: "$self.handleCrash(this,$1);" replace: "$self.handleCrash(this,$1);"
@ -175,7 +165,7 @@ export default definePlugin({
} }
if (settings.store.attemptToNavigateToHome) { if (settings.store.attemptToNavigateToHome) {
try { try {
NavigationRouter.transitionToGuild("@me"); NavigationRouter.transitionTo("/channels/@me");
} catch (err) { } catch (err) {
CrashHandlerLogger.debug("Failed to navigate to home", err); CrashHandlerLogger.debug("Failed to navigate to home", err);
} }

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { definePluginSettings, Settings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { getUserSettingLazy } from "@api/UserSettings"; import { getUserSettingLazy } from "@api/UserSettings";
import { ErrorCard } from "@components/ErrorCard"; import { ErrorCard } from "@components/ErrorCard";
import { Link } from "@components/Link"; import { Link } from "@components/Link";
@ -26,13 +26,14 @@ import { Margins } from "@utils/margins";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import { useAwaiter } from "@utils/react"; import { useAwaiter } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findComponentByCodeLazy } from "@webpack"; import { findByCode, findByProps, findComponentByCode } from "@webpack";
import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common"; import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common";
const useProfileThemeStyle = findByCodeLazy("profileThemeStyle:", "--profile-gradient-primary-color"); const useProfileThemeStyle = findByCode("profileThemeStyle:", "--profile-gradient-primary-color");
const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile"); const ActivityComponent = findComponentByCode("onOpenGameProfile");
const ActivityClassName = findByProps("activity", "buttonColor");
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!; const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame");
async function getApplicationAsset(key: string): Promise<string> { async function getApplicationAsset(key: string): Promise<string> {
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, ""); if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
@ -260,7 +261,7 @@ const settings = definePluginSettings({
function onChange() { function onChange() {
setRpc(true); setRpc(true);
if (Settings.plugins.CustomRPC.enabled) setRpc(); if (Vencord.Plugins.isPluginEnabled("CustomRPC")) setRpc();
} }
function isStreamLinkDisabled() { function isStreamLinkDisabled() {
@ -435,8 +436,8 @@ export default definePlugin({
<Forms.FormDivider className={Margins.top8} /> <Forms.FormDivider className={Margins.top8} />
<div style={{ width: "284px", ...profileThemeStyle, padding: 8, marginTop: 8, borderRadius: 8, background: "var(--bg-mod-faint)" }}> <div style={{ width: "284px", ...profileThemeStyle }}>
{activity[0] && <ActivityComponent activity={activity[0]} channelId={SelectedChannelStore.getChannelId()} {activity[0] && <ActivityComponent activity={activity[0]} className={ActivityClassName.activity} channelId={SelectedChannelStore.getChannelId()}
guild={GuildStore.getGuild(SelectedGuildStore.getLastSelectedGuildId())} guild={GuildStore.getGuild(SelectedGuildStore.getLastSelectedGuildId())}
application={{ id: settings.store.appID }} application={{ id: settings.store.appID }}
user={UserStore.getCurrentUser()} />} user={UserStore.getCurrentUser()} />}

View file

@ -37,8 +37,8 @@ export default definePlugin({
find: 'type:"IDLE",idle:', find: 'type:"IDLE",idle:',
replacement: [ replacement: [
{ {
match: /(?<=Date\.now\(\)-\i>)\i\.\i\|\|/, match: /(?<=Date\.now\(\)-\i>)\i\.\i/,
replace: "$self.getIdleTimeout()||" replace: "$self.getIdleTimeout()"
}, },
{ {
match: /Math\.min\((\i\.\i\.getSetting\(\)\*\i\.\i\.\i\.SECOND),\i\.\i\)/, match: /Math\.min\((\i\.\i\.getSetting\(\)\*\i\.\i\.\i\.SECOND),\i\.\i\)/,

View file

@ -46,7 +46,7 @@ const embedUrlRe = /https:\/\/www\.youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/;
async function embedDidMount(this: Component<Props>) { async function embedDidMount(this: Component<Props>) {
try { try {
const { embed } = this.props; const { embed } = this.props;
const { replaceElements, dearrowByDefault } = settings.store; const { replaceElements } = settings.store;
if (!embed || embed.dearrow || embed.provider?.name !== "YouTube" || !embed.video?.url) return; if (!embed || embed.dearrow || embed.provider?.name !== "YouTube" || !embed.video?.url) return;
@ -63,22 +63,18 @@ async function embedDidMount(this: Component<Props>) {
if (!hasTitle && !hasThumb) return; if (!hasTitle && !hasThumb) return;
embed.dearrow = { embed.dearrow = {
enabled: dearrowByDefault enabled: true
}; };
if (hasTitle && replaceElements !== ReplaceElements.ReplaceThumbnailsOnly) { if (hasTitle && replaceElements !== ReplaceElements.ReplaceThumbnailsOnly) {
const replacementTitle = titles[0].title.replace(/(^|\s)>(\S)/g, "$1$2"); embed.dearrow.oldTitle = embed.rawTitle;
embed.rawTitle = titles[0].title.replace(/(^|\s)>(\S)/g, "$1$2");
embed.dearrow.oldTitle = dearrowByDefault ? embed.rawTitle : replacementTitle;
if (dearrowByDefault) embed.rawTitle = replacementTitle;
} }
if (hasThumb && replaceElements !== ReplaceElements.ReplaceTitlesOnly) {
const replacementProxyURL = `https://dearrow-thumb.ajay.app/api/v1/getThumbnail?videoID=${videoId}&time=${thumbnails[0].timestamp}`;
embed.dearrow.oldThumb = dearrowByDefault ? embed.thumbnail.proxyURL : replacementProxyURL; if (hasThumb && replaceElements !== ReplaceElements.ReplaceTitlesOnly) {
if (dearrowByDefault) embed.thumbnail.proxyURL = replacementProxyURL; embed.dearrow.oldThumb = embed.thumbnail.proxyURL;
embed.thumbnail.proxyURL = `https://dearrow-thumb.ajay.app/api/v1/getThumbnail?videoID=${videoId}&time=${thumbnails[0].timestamp}`;
} }
this.forceUpdate(); this.forceUpdate();
@ -100,7 +96,6 @@ function DearrowButton({ component }: { component: Component<Props>; }) {
className={"vc-dearrow-toggle-" + (embed.dearrow.enabled ? "on" : "off")} className={"vc-dearrow-toggle-" + (embed.dearrow.enabled ? "on" : "off")}
onClick={() => { onClick={() => {
const { enabled, oldThumb, oldTitle } = embed.dearrow; const { enabled, oldThumb, oldTitle } = embed.dearrow;
settings.store.dearrowByDefault = !enabled;
embed.dearrow.enabled = !enabled; embed.dearrow.enabled = !enabled;
if (oldTitle) { if (oldTitle) {
embed.dearrow.oldTitle = embed.rawTitle; embed.dearrow.oldTitle = embed.rawTitle;
@ -158,12 +153,6 @@ const settings = definePluginSettings({
{ label: "Titles", value: ReplaceElements.ReplaceTitlesOnly }, { label: "Titles", value: ReplaceElements.ReplaceTitlesOnly },
{ label: "Thumbnails", value: ReplaceElements.ReplaceThumbnailsOnly }, { label: "Thumbnails", value: ReplaceElements.ReplaceThumbnailsOnly },
], ],
},
dearrowByDefault: {
description: "Dearrow videos automatically",
type: OptionType.BOOLEAN,
default: true,
restartNeeded: false
} }
}); });

View file

@ -41,7 +41,7 @@ export default definePlugin({
{ {
find: "DefaultCustomizationSections", find: "DefaultCustomizationSections",
replacement: { replacement: {
match: /(?<=#{intl::USER_SETTINGS_AVATAR_DECORATION}\)},"decoration"\),)/, match: /(?<=USER_SETTINGS_AVATAR_DECORATION},"decoration"\),)/,
replace: "$self.DecorSection()," replace: "$self.DecorSection(),"
} }
}, },
@ -54,7 +54,7 @@ export default definePlugin({
replace: "$self.DecorationGridItem=$&" replace: "$self.DecorationGridItem=$&"
}, },
{ {
match: /(?<==)\i=>{let{user:\i,avatarDecoration/, match: /(?<==)\i=>{let{user:\i,avatarDecoration.{300,600}decorationGridItemChurned/,
replace: "$self.DecorationGridDecoration=$&" replace: "$self.DecorationGridDecoration=$&"
}, },
// Remove NEW label from decor avatar decorations // Remove NEW label from decor avatar decorations

View file

@ -93,7 +93,7 @@ export const useAuthorizationStore = proxyLazy(() => zustandCreate(
} as AuthorizationState), } as AuthorizationState),
{ {
name: "decor-auth", name: "decor-auth",
storage: indexedDBStorage, getStorage: () => indexedDBStorage,
partialize: state => ({ tokens: state.tokens }), partialize: state => ({ tokens: state.tokens }),
onRehydrateStorage: () => state => state?.init() onRehydrateStorage: () => state => state?.init()
} }

View file

@ -95,13 +95,10 @@ export const useUsersDecorationsStore = proxyLazy(() => zustandCreate((set: any,
} as UsersDecorationsState))); } as UsersDecorationsState)));
export function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | null | undefined { export function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | null | undefined {
try {
const [decorAvatarDecoration, setDecorAvatarDecoration] = useState<string | null>(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null); const [decorAvatarDecoration, setDecorAvatarDecoration] = useState<string | null>(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null);
useEffect(() => { useEffect(() => {
const destructor = (() => { const destructor = useUsersDecorationsStore.subscribe(
try {
return useUsersDecorationsStore.subscribe(
state => { state => {
if (!user) return; if (!user) return;
const newDecorAvatarDecoration = state.getAsset(user.id); const newDecorAvatarDecoration = state.getAsset(user.id);
@ -109,25 +106,13 @@ export function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | nu
if (decorAvatarDecoration !== newDecorAvatarDecoration) setDecorAvatarDecoration(newDecorAvatarDecoration); if (decorAvatarDecoration !== newDecorAvatarDecoration) setDecorAvatarDecoration(newDecorAvatarDecoration);
} }
); );
} catch {
return () => { };
}
})();
try {
if (user) { if (user) {
const { fetch: fetchUserDecorAvatarDecoration } = useUsersDecorationsStore.getState(); const { fetch: fetchUserDecorAvatarDecoration } = useUsersDecorationsStore.getState();
fetchUserDecorAvatarDecoration(user.id); fetchUserDecorAvatarDecoration(user.id);
} }
} catch { }
return destructor; return destructor;
}, []); }, []);
return decorAvatarDecoration ? { asset: decorAvatarDecoration, skuId: SKU_ID } : null; return decorAvatarDecoration ? { asset: decorAvatarDecoration, skuId: SKU_ID } : null;
} catch (e) {
console.error(e);
}
return null;
} }

View file

@ -5,7 +5,7 @@
*/ */
import { Flex } from "@components/Flex"; import { Flex } from "@components/Flex";
import { findByCodeLazy } from "@webpack"; import { findComponentByCode } from "@webpack";
import { Button, useEffect } from "@webpack/common"; import { Button, useEffect } from "@webpack/common";
import { useAuthorizationStore } from "../../lib/stores/AuthorizationStore"; import { useAuthorizationStore } from "../../lib/stores/AuthorizationStore";
@ -13,7 +13,7 @@ import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDeco
import { cl } from "../"; import { cl } from "../";
import { openChangeDecorationModal } from "../modals/ChangeDecorationModal"; import { openChangeDecorationModal } from "../modals/ChangeDecorationModal";
const CustomizationSection = findByCodeLazy(".customizationSectionBackground"); const CustomizationSection = findComponentByCode(".customizationSectionBackground");
export interface DecorSectionProps { export interface DecorSectionProps {
hideTitle?: boolean; hideTitle?: boolean;

View file

@ -5,8 +5,7 @@
*/ */
import { PlusIcon } from "@components/Icons"; import { PlusIcon } from "@components/Icons";
import { getIntlMessage } from "@utils/discord"; import { i18n, Text } from "@webpack/common";
import { Text } from "@webpack/common";
import { HTMLProps } from "react"; import { HTMLProps } from "react";
import { DecorationGridItem } from "."; import { DecorationGridItem } from ".";
@ -25,7 +24,7 @@ export default function DecorationGridCreate(props: DecorationGridCreateProps) {
variant="text-xs/normal" variant="text-xs/normal"
color="header-primary" color="header-primary"
> >
{getIntlMessage("CREATE")} {i18n.Messages.CREATE}
</Text> </Text>
</DecorationGridItem >; </DecorationGridItem >;
} }

View file

@ -5,8 +5,7 @@
*/ */
import { NoEntrySignIcon } from "@components/Icons"; import { NoEntrySignIcon } from "@components/Icons";
import { getIntlMessage } from "@utils/discord"; import { i18n, Text } from "@webpack/common";
import { Text } from "@webpack/common";
import { HTMLProps } from "react"; import { HTMLProps } from "react";
import { DecorationGridItem } from "."; import { DecorationGridItem } from ".";
@ -25,7 +24,7 @@ export default function DecorationGridNone(props: DecorationGridNoneProps) {
variant="text-xs/normal" variant="text-xs/normal"
color="header-primary" color="header-primary"
> >
{getIntlMessage("NONE")} {i18n.Messages.NONE}
</Text> </Text>
</DecorationGridItem >; </DecorationGridItem >;
} }

View file

@ -5,13 +5,13 @@
*/ */
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack"; import { findByProps } from "@webpack";
import { React } from "@webpack/common"; import { React } from "@webpack/common";
import { cl } from "../"; import { cl } from "../";
import Grid, { GridProps } from "./Grid"; import Grid, { GridProps } from "./Grid";
const ScrollerClasses = findByPropsLazy("managedReactiveScroller"); const ScrollerClasses = findByProps("managedReactiveScroller");
type Section<SectionT, ItemT> = SectionT & { type Section<SectionT, ItemT> = SectionT & {
items: Array<ItemT>; items: Array<ItemT>;

View file

@ -4,7 +4,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { findComponentByCode, LazyComponentWebpack } from "@webpack"; import { NoopComponent } from "@utils/react";
import { findComponentByCode } from "@webpack";
import { React } from "@webpack/common"; import { React } from "@webpack/common";
import type { ComponentType, HTMLProps, PropsWithChildren } from "react"; import type { ComponentType, HTMLProps, PropsWithChildren } from "react";
@ -15,13 +16,10 @@ type DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTM
isSelected: boolean, isSelected: boolean,
}>; }>;
export let DecorationGridItem: DecorationGridItemComponent; export let DecorationGridItem: DecorationGridItemComponent = NoopComponent;
export const setDecorationGridItem = v => DecorationGridItem = v; export const setDecorationGridItem = v => DecorationGridItem = v;
export const AvatarDecorationModalPreview = LazyComponentWebpack(() => { export const AvatarDecorationModalPreview = findComponentByCode<any>(".shopPreviewBanner", component => React.memo(component));
const component = findComponentByCode(".shopPreviewBanner");
return React.memo(component);
});
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & { type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
avatarDecoration: AvatarDecoration; avatarDecoration: AvatarDecoration;
@ -29,5 +27,5 @@ type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivEl
isSelected: boolean, isSelected: boolean,
}>; }>;
export let DecorationGridDecoration: DecorationGridDecorationComponent; export let DecorationGridDecoration: DecorationGridDecorationComponent = NoopComponent;
export const setDecorationGridDecoration = v => DecorationGridDecoration = v; export const setDecorationGridDecoration = v => DecorationGridDecoration = v;

View file

@ -5,10 +5,10 @@
*/ */
import { classNameFactory } from "@api/Styles"; import { classNameFactory } from "@api/Styles";
import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack"; import { extractAndLoadChunksLazy, findByProps } from "@webpack";
export const cl = classNameFactory("vc-decor-"); export const cl = classNameFactory("vc-decor-");
export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton"); export const DecorationModalStyles = findByProps("modalFooterShopButton");
export const requireAvatarDecorationModal = extractAndLoadChunksLazy([".COLLECTIBLES_SHOP_FULLSCREEN&&"]); export const requireAvatarDecorationModal = extractAndLoadChunksLazy(".COLLECTIBLES_SHOP_FULLSCREEN&&");
export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]); export const requireCreateStickerModal = extractAndLoadChunksLazy("stickerInspected]:");

View file

@ -10,7 +10,7 @@ import { openInviteModal } from "@utils/discord";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { classes, copyWithToast } from "@utils/misc"; import { classes, copyWithToast } from "@utils/misc";
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { findComponentByCodeLazy } from "@webpack"; import { findComponentByCode } from "@webpack";
import { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from "@webpack/common"; import { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from "@webpack/common";
import { User } from "discord-types/general"; import { User } from "discord-types/general";
@ -29,7 +29,7 @@ import SectionedGridList from "../components/SectionedGridList";
import { openCreateDecorationModal } from "./CreateDecorationModal"; import { openCreateDecorationModal } from "./CreateDecorationModal";
import { openGuidelinesModal } from "./GuidelinesModal"; import { openGuidelinesModal } from "./GuidelinesModal";
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers"); const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
function usePresets() { function usePresets() {
const [presets, setPresets] = useState<Preset[]>([]); const [presets, setPresets] = useState<Preset[]>([]);

View file

@ -9,7 +9,7 @@ import { Link } from "@components/Link";
import { openInviteModal } from "@utils/discord"; import { openInviteModal } from "@utils/discord";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { filters, findComponentByCodeLazy, mapMangledModuleLazy } from "@webpack"; import { filters, findComponentByCode, mapMangledModule } from "@webpack";
import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common"; import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common";
import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants"; import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants";
@ -17,11 +17,11 @@ import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDeco
import { cl, DecorationModalStyles, requireAvatarDecorationModal, requireCreateStickerModal } from "../"; import { cl, DecorationModalStyles, requireAvatarDecorationModal, requireCreateStickerModal } from "../";
import { AvatarDecorationModalPreview } from "../components"; import { AvatarDecorationModalPreview } from "../components";
const FileUpload = findComponentByCodeLazy("fileUploadInput,"); const FileUpload = findComponentByCode("fileUploadInput,");
const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE=3]="POSITIVE', { const { HelpMessage, HelpMessageTypes } = mapMangledModule('POSITIVE=3]="POSITIVE', {
HelpMessage: filters.componentByCode(".iconDiv,", "messageType"),
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"), HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"),
HelpMessage: filters.byCode(".iconDiv")
}); });
function useObjectURL(object: Blob | MediaSource | null) { function useObjectURL(object: Blob | MediaSource | null) {

View file

@ -22,7 +22,7 @@ import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches"; import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
import definePlugin, { OptionType, ReporterTestable } from "@utils/types"; import definePlugin, { OptionType, ReporterTestable } from "@utils/types";
import { filters, findAll, search } from "@webpack"; import { cacheFindAll, filters, searchFactories } from "@webpack";
const PORT = 8485; const PORT = 8485;
const NAV_ID = "dev-companion-reconnect"; const NAV_ID = "dev-companion-reconnect";
@ -154,13 +154,13 @@ function initWs(isManual = false) {
case "testPatch": { case "testPatch": {
const { find, replacement } = data as PatchData; const { find, replacement } = data as PatchData;
const candidates = search(find); const candidates = searchFactories(find);
const keys = Object.keys(candidates); const keys = Object.keys(candidates);
if (keys.length !== 1) if (keys.length !== 1)
return reply("Expected exactly one 'find' matches, found " + keys.length); return reply("Expected exactly one 'find' matches, found " + keys.length);
const mod = candidates[keys[0]]; const mod = candidates[keys[0]];
let src = String(mod.original ?? mod).replaceAll("\n", ""); let src = String(mod).replaceAll("\n", "");
if (src.startsWith("function(")) { if (src.startsWith("function(")) {
src = "0," + src; src = "0," + src;
@ -201,22 +201,22 @@ function initWs(isManual = false) {
let results: any[]; let results: any[];
switch (type.replace("find", "").replace("Lazy", "")) { switch (type.replace("find", "").replace("Lazy", "")) {
case "": case "":
results = findAll(parsedArgs[0]); results = cacheFindAll(parsedArgs[0]);
break; break;
case "ByProps": case "ByProps":
results = findAll(filters.byProps(...parsedArgs)); results = cacheFindAll(filters.byProps(...parsedArgs));
break; break;
case "Store": case "Store":
results = findAll(filters.byStoreName(parsedArgs[0])); results = cacheFindAll(filters.byStoreName(parsedArgs[0]));
break; break;
case "ByCode": case "ByCode":
results = findAll(filters.byCode(...parsedArgs)); results = cacheFindAll(filters.byCode(...parsedArgs));
break; break;
case "ModuleId": case "ModuleId":
results = Object.keys(search(parsedArgs[0])); results = Object.keys(searchFactories(parsedArgs[0]));
break; break;
case "ComponentByCode": case "ComponentByCode":
results = findAll(filters.componentByCode(...parsedArgs)); results = cacheFindAll(filters.componentByCode(...parsedArgs));
break; break;
default: default:
return reply("Unknown Find Type " + type); return reply("Unknown Find Type " + type);

View file

@ -27,7 +27,7 @@ export default definePlugin({
authors: [Devs.Nuckyz], authors: [Devs.Nuckyz],
patches: [ patches: [
{ {
find: "#{intl::BOT_CALL_IDLE_DISCONNECT_2}", find: ".Messages.BOT_CALL_IDLE_DISCONNECT",
replacement: { replacement: {
match: /,?(?=\i\(this,"idleTimeout",new \i\.\i\))/, match: /,?(?=\i\(this,"idleTimeout",new \i\.\i\))/,
replace: ";return;" replace: ";return;"

View file

@ -23,12 +23,12 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal"; import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findByCodeLazy, findStoreLazy } from "@webpack"; import { findByCode, findStore } from "@webpack";
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common"; import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
import { Promisable } from "type-fest"; import { Promisable } from "type-fest";
const StickersStore = findStoreLazy("StickersStore"); const StickersStore = findStore("StickersStore");
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START"); const uploadEmoji = findByCode(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
interface Sticker { interface Sticker {
t: "Sticker"; t: "Sticker";

View file

@ -23,13 +23,12 @@ import { ErrorCard } from "@components/ErrorCard";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findLazy } from "@webpack"; import { findByProps } from "@webpack";
import { Forms, React } from "@webpack/common"; import { Forms, React } from "@webpack/common";
import hideBugReport from "./hideBugReport.css?managed"; import hideBugReport from "./hideBugReport.css?managed";
const KbdStyles = findByPropsLazy("key", "combo"); const KbdStyles = findByProps("key", "combo");
const BugReporterExperiment = findLazy(m => m?.definition?.id === "2024-09_bug_reporter");
const settings = definePluginSettings({ const settings = definePluginSettings({
toolbarDevMenu: { toolbarDevMenu: {
@ -79,8 +78,8 @@ export default definePlugin({
{ {
find: "toolbar:function", find: "toolbar:function",
replacement: { replacement: {
match: /hasBugReporterAccess:(\i)/, match: /\i\.isStaff\(\)/,
replace: "_hasBugReporterAccess:$1=true" replace: "true"
}, },
predicate: () => settings.store.toolbarDevMenu predicate: () => settings.store.toolbarDevMenu
}, },
@ -92,18 +91,10 @@ export default definePlugin({
match: /\i\.isDM\(\)\|\|\i\.isThread\(\)/, match: /\i\.isDM\(\)\|\|\i\.isThread\(\)/,
replace: "false", replace: "false",
} }
},
// enable option to always record clips even if you are not streaming
{
find: "isDecoupledGameClippingEnabled(){",
replacement: {
match: /\i\.isStaff\(\)/,
replace: "true"
}
} }
], ],
start: () => !BugReporterExperiment.getCurrentConfig().hasBugReporterAccess && enableStyle(hideBugReport), start: () => enableStyle(hideBugReport),
stop: () => disableStyle(hideBugReport), stop: () => disableStyle(hideBugReport),
settingsAboutComponent: () => { settingsAboutComponent: () => {

View file

@ -20,39 +20,39 @@ import { addPreEditListener, addPreSendListener, removePreEditListener, removePr
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies"; import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies";
import { getCurrentGuild, getEmojiURL } from "@utils/discord"; import { getCurrentGuild } from "@utils/discord";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, Patch } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack"; import { findByCode, findByProps, findStore, webpackDependantLazy } from "@webpack";
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common"; import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, IconUtils, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
import type { Emoji } from "@webpack/types"; import type { Emoji } from "@webpack/types";
import type { Message } from "discord-types/general"; import type { Message } from "discord-types/general";
import { applyPalette, GIFEncoder, quantize } from "gifenc"; import { applyPalette, GIFEncoder, quantize } from "gifenc";
import type { ReactElement, ReactNode } from "react"; import type { ReactElement, ReactNode } from "react";
const StickerStore = findStoreLazy("StickersStore") as { const StickersStore = findStore("StickersStore") as {
getPremiumPacks(): StickerPack[]; getPremiumPacks(): StickerPack[];
getAllGuildStickers(): Map<string, Sticker[]>; getAllGuildStickers(): Map<string, Sticker[]>;
getStickerById(id: string): Sticker | undefined; getStickerById(id: string): Sticker | undefined;
}; };
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore"); const UserSettingsProtoStore = findStore("UserSettingsProtoStore");
const BINARY_READ_OPTIONS = findByPropsLazy("readerFactory"); const BINARY_READ_OPTIONS = findByProps("readerFactory");
function searchProtoClassField(localName: string, protoClass: any) { function searchProtoClassField(localName: string, protoClass: any) {
const field = protoClass?.fields?.find((field: any) => field.localName === localName); const field = protoClass?.fields?.find((field: any) => field.localName === localName);
if (!field) return; if (!field) return;
const fieldGetter = Object.values(field).find(value => typeof value === "function") as any; const fieldGetter = Object.values<any>(field).find(value => typeof value === "function");
return fieldGetter?.(); return fieldGetter?.();
} }
const PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators); const PreloadedUserSettingsActionCreators = webpackDependantLazy(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);
const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass)); const AppearanceSettingsActionCreators = webpackDependantLazy(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass));
const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators)); const ClientThemeSettingsActionsCreators = webpackDependantLazy(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators));
const isUnusableRoleSubscriptionEmoji = findByCodeLazy(".getUserIsAdmin("); const isUnusableRoleSubscriptionEmoji = findByCode(".getUserIsAdmin(");
const enum EmojiIntentions { const enum EmojiIntentions {
REACTION, REACTION,
@ -194,26 +194,6 @@ const hasExternalStickerPerms = (channelId: string) => hasPermission(channelId,
const hasEmbedPerms = (channelId: string) => hasPermission(channelId, PermissionsBits.EMBED_LINKS); const hasEmbedPerms = (channelId: string) => hasPermission(channelId, PermissionsBits.EMBED_LINKS);
const hasAttachmentPerms = (channelId: string) => hasPermission(channelId, PermissionsBits.ATTACH_FILES); const hasAttachmentPerms = (channelId: string) => hasPermission(channelId, PermissionsBits.ATTACH_FILES);
function makeBypassPatches(): Omit<Patch, "plugin"> {
const mapping: Array<{ func: string, predicate?: () => boolean; }> = [
{ func: "canUseCustomStickersEverywhere", predicate: () => settings.store.enableStickerBypass },
{ func: "canUseHighVideoUploadQuality", predicate: () => settings.store.enableStreamQualityBypass },
{ func: "canStreamQuality", predicate: () => settings.store.enableStreamQualityBypass },
{ func: "canUseClientThemes" },
{ func: "canUseCustomNotificationSounds" },
{ func: "canUsePremiumAppIcons" }
];
return {
find: "canUseCustomStickersEverywhere:",
replacement: mapping.map(({ func, predicate }) => ({
match: new RegExp(String.raw`(?<=${func}:function\(\i(?:,\i)?\){)`),
replace: "return true;",
predicate
}))
};
}
export default definePlugin({ export default definePlugin({
name: "FakeNitro", name: "FakeNitro",
authors: [Devs.Arjix, Devs.D3SOX, Devs.Ven, Devs.fawn, Devs.captain, Devs.Nuckyz, Devs.AutumnVN], authors: [Devs.Arjix, Devs.D3SOX, Devs.Ven, Devs.fawn, Devs.captain, Devs.Nuckyz, Devs.AutumnVN],
@ -223,17 +203,6 @@ export default definePlugin({
settings, settings,
patches: [ patches: [
// General bypass patches
makeBypassPatches(),
// Patch the emoji picker in voice calls to not be bypassed by fake nitro
{
find: "emojiItemDisabled]",
predicate: () => settings.store.enableEmojiBypass,
replacement: {
match: /CHAT/,
replace: "STATUS"
}
},
{ {
find: ".PREMIUM_LOCKED;", find: ".PREMIUM_LOCKED;",
group: true, group: true,
@ -274,6 +243,15 @@ export default definePlugin({
replace: (_, rest1, rest2) => `${rest1},fakeNitroOriginal){if(!fakeNitroOriginal)return false;${rest2}` replace: (_, rest1, rest2) => `${rest1},fakeNitroOriginal){if(!fakeNitroOriginal)return false;${rest2}`
} }
}, },
// Allow stickers to be sent everywhere
{
find: "canUseCustomStickersEverywhere:function",
predicate: () => settings.store.enableStickerBypass,
replacement: {
match: /canUseCustomStickersEverywhere:function\(\i\){/,
replace: "$&return true;"
},
},
// Make stickers always available // Make stickers always available
{ {
find: '"SENDABLE"', find: '"SENDABLE"',
@ -283,15 +261,37 @@ export default definePlugin({
replace: "true?" replace: "true?"
} }
}, },
// Allow streaming with high quality
{
find: "canUseHighVideoUploadQuality:function",
predicate: () => settings.store.enableStreamQualityBypass,
replacement: [
"canUseHighVideoUploadQuality",
"canStreamQuality",
].map(func => {
return {
match: new RegExp(`${func}:function\\(\\i(?:,\\i)?\\){`, "g"),
replace: "$&return true;"
};
})
},
// Remove boost requirements to stream with high quality // Remove boost requirements to stream with high quality
{ {
find: "#{intl::STREAM_FPS_OPTION}", find: "STREAM_FPS_OPTION.format",
predicate: () => settings.store.enableStreamQualityBypass, predicate: () => settings.store.enableStreamQualityBypass,
replacement: { replacement: {
match: /guildPremiumTier:\i\.\i\.TIER_\d,?/g, match: /guildPremiumTier:\i\.\i\.TIER_\d,?/g,
replace: "" replace: ""
} }
}, },
// Allow client themes to be changeable
{
find: "canUseClientThemes:function",
replacement: {
match: /canUseClientThemes:function\(\i\){/,
replace: "$&return true;"
}
},
{ {
find: '"UserSettingsProtoStore"', find: '"UserSettingsProtoStore"',
replacement: [ replacement: [
@ -350,13 +350,13 @@ export default definePlugin({
{ {
// Filter attachments to remove fake nitro stickers or emojis // Filter attachments to remove fake nitro stickers or emojis
predicate: () => settings.store.transformStickers, predicate: () => settings.store.transformStickers,
match: /renderAttachments\(\i\){.+?{attachments:(\i).+?;/, match: /renderAttachments\(\i\){let{attachments:(\i).+?;/,
replace: (m, attachments) => `${m}${attachments}=$self.filterAttachments(${attachments});` replace: (m, attachments) => `${m}${attachments}=$self.filterAttachments(${attachments});`
} }
] ]
}, },
{ {
find: "#{intl::STICKER_POPOUT_UNJOINED_PRIVATE_GUILD_DESCRIPTION}", find: ".Messages.STICKER_POPOUT_UNJOINED_PRIVATE_GUILD_DESCRIPTION.format",
predicate: () => settings.store.transformStickers, predicate: () => settings.store.transformStickers,
replacement: [ replacement: [
{ {
@ -381,7 +381,7 @@ export default definePlugin({
} }
}, },
{ {
find: "#{intl::EMOJI_POPOUT_UNJOINED_DISCOVERABLE_GUILD_DESCRIPTION}", find: ".Messages.EMOJI_POPOUT_UNJOINED_DISCOVERABLE_GUILD_DESCRIPTION",
predicate: () => settings.store.transformEmojis, predicate: () => settings.store.transformEmojis,
replacement: { replacement: {
// Add the fake nitro emoji notice // Add the fake nitro emoji notice
@ -389,6 +389,14 @@ export default definePlugin({
replace: (_, reactNode, props) => `$self.addFakeNotice(${FakeNoticeType.Emoji},${reactNode},!!${props}?.fakeNitroNode?.fake)` replace: (_, reactNode, props) => `$self.addFakeNotice(${FakeNoticeType.Emoji},${reactNode},!!${props}?.fakeNitroNode?.fake)`
} }
}, },
// Allow using custom app icons
{
find: "canUsePremiumAppIcons:function",
replacement: {
match: /canUsePremiumAppIcons:function\(\i\){/,
replace: "$&return true;"
}
},
// Separate patch for allowing using custom app icons // Separate patch for allowing using custom app icons
{ {
find: /\.getCurrentDesktopIcon.{0,25}\.isPremium/, find: /\.getCurrentDesktopIcon.{0,25}\.isPremium/,
@ -404,6 +412,14 @@ export default definePlugin({
match: /(?<=type:"(?:SOUNDBOARD_SOUNDS_RECEIVED|GUILD_SOUNDBOARD_SOUND_CREATE|GUILD_SOUNDBOARD_SOUND_UPDATE|GUILD_SOUNDBOARD_SOUNDS_UPDATE)".+?available:)\i\.available/g, match: /(?<=type:"(?:SOUNDBOARD_SOUNDS_RECEIVED|GUILD_SOUNDBOARD_SOUND_CREATE|GUILD_SOUNDBOARD_SOUND_UPDATE|GUILD_SOUNDBOARD_SOUNDS_UPDATE)".+?available:)\i\.available/g,
replace: "true" replace: "true"
} }
},
// Allow using custom notification sounds
{
find: "canUseCustomNotificationSounds:function",
replacement: {
match: /canUseCustomNotificationSounds:function\(\i\){/,
replace: "$&return true;"
}
} }
], ],
@ -550,8 +566,8 @@ export default definePlugin({
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex); const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
if (gifMatch) { if (gifMatch) {
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
if (StickerStore.getStickerById(gifMatch[1])) return null; if (StickersStore.getStickerById(gifMatch[1])) return null;
} }
} }
@ -639,7 +655,7 @@ export default definePlugin({
url = new URL(item); url = new URL(item);
} catch { } } catch { }
const stickerName = StickerStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker"; const stickerName = StickersStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
stickers.push({ stickers.push({
format_type: 1, format_type: 1,
id: imgMatch[1], id: imgMatch[1],
@ -652,9 +668,9 @@ export default definePlugin({
const gifMatch = item.match(fakeNitroGifStickerRegex); const gifMatch = item.match(fakeNitroGifStickerRegex);
if (gifMatch) { if (gifMatch) {
if (!StickerStore.getStickerById(gifMatch[1])) continue; if (!StickersStore.getStickerById(gifMatch[1])) continue;
const stickerName = StickerStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker"; const stickerName = StickersStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
stickers.push({ stickers.push({
format_type: 2, format_type: 2,
id: gifMatch[1], id: gifMatch[1],
@ -687,8 +703,8 @@ export default definePlugin({
const gifMatch = embed.url!.match(fakeNitroGifStickerRegex); const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);
if (gifMatch) { if (gifMatch) {
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
if (StickerStore.getStickerById(gifMatch[1])) return true; if (StickersStore.getStickerById(gifMatch[1])) return true;
} }
} }
@ -705,8 +721,8 @@ export default definePlugin({
const match = attachment.url.match(fakeNitroGifStickerRegex); const match = attachment.url.match(fakeNitroGifStickerRegex);
if (match) { if (match) {
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
if (StickerStore.getStickerById(match[1])) return false; if (StickersStore.getStickerById(match[1])) return false;
} }
return true; return true;
@ -862,7 +878,7 @@ export default definePlugin({
if (!s.enableStickerBypass) if (!s.enableStickerBypass)
break stickerBypass; break stickerBypass;
const sticker = StickerStore.getStickerById(extra.stickers?.[0]!); const sticker = StickersStore.getStickerById(extra.stickers?.[0]!);
if (!sticker) if (!sticker)
break stickerBypass; break stickerBypass;
@ -920,7 +936,7 @@ export default definePlugin({
const emojiString = `<${emoji.animated ? "a" : ""}:${emoji.originalName || emoji.name}:${emoji.id}>`; const emojiString = `<${emoji.animated ? "a" : ""}:${emoji.originalName || emoji.name}:${emoji.id}>`;
const url = new URL(getEmojiURL(emoji.id, emoji.animated, s.emojiSize)); const url = new URL(IconUtils.getEmojiURL({ id: emoji.id, animated: emoji.animated, size: s.emojiSize }));
url.searchParams.set("size", s.emojiSize.toString()); url.searchParams.set("size", s.emojiSize.toString());
url.searchParams.set("name", emoji.name); url.searchParams.set("name", emoji.name);
@ -953,7 +969,7 @@ export default definePlugin({
hasBypass = true; hasBypass = true;
const url = new URL(getEmojiURL(emoji.id, emoji.animated, s.emojiSize)); const url = new URL(IconUtils.getEmojiURL({ id: emoji.id, animated: emoji.animated, size: s.emojiSize }));
url.searchParams.set("size", s.emojiSize.toString()); url.searchParams.set("size", s.emojiSize.toString());
url.searchParams.set("name", emoji.name); url.searchParams.set("name", emoji.name);

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