Compare commits

...

24 Commits

Author SHA1 Message Date
d55f3720f2 merge unconflict
Some checks failed
Build DevBuild / Build (push) Has been cancelled
test / test (push) Has been cancelled
2025-11-18 22:54:48 +01:00
Cobblestone
eec4771646 too late now 2025-11-13 22:40:11 -05:00
Cobblestone
f1d9f26c79 finish adding latex support to more markdown 2025-11-13 22:36:38 -05:00
Cobblestone
03449a8985 Merge branch 'main' of https://github.com/Nexulien/Nexulien 2025-11-13 19:56:11 -05:00
Zoid
2d01bbb279 Merge branch 'Vendicated:main' into main 2025-11-12 16:34:40 -05:00
Vendicated
efe6f5c697 bump to v1.13.6 2025-11-12 22:16:13 +01:00
Vendicated
b3c070bca2 ViewIcons: fix viewing icon in dm header 2025-11-12 22:08:18 +01:00
Vendicated
e90b31e717 fix chat bar buttons not showing 2025-11-12 22:05:20 +01:00
Vendicated
ed1baadac3 LastFMRichPresence: linkify track/artist/album & make api key optional 2025-11-12 16:56:27 +01:00
Vendicated
00ae603884 VoiceMessages: fix crash when uploading invalid audio files 2025-11-12 16:16:33 +01:00
Jaegerwald
fd34978e1a tone indicators: /nh not hateful 2025-11-11 09:47:09 +01:00
Jaegerwald
08146aada4 Merge branch 'Vendicated:main' into main 2025-11-05 18:38:47 +01:00
thororen
c9ebece84d FakeProfileThemes: Fix broken ProfileModal find (#3766) 2025-11-05 13:29:37 -03:00
thororen
6bbc4783cd Experiments: Fix Link Embeds (#3763) 2025-11-04 15:18:30 -03:00
Zoid
e30c335c9a Merge branch 'Vendicated:main' into main 2025-11-04 09:39:28 -05:00
Vendicated
7c708acf0b bump to v1.13.5 2025-11-02 18:35:01 +01:00
thororen
44a75e4e94 fix Decor & NoTrack (#3752)
Co-authored-by: Vendicated <vendicated@riseup.net>
2025-11-02 17:28:53 +00:00
Vendicated
3992f971d0 fix missing Toolbox 2025-11-02 18:21:54 +01:00
hich4t
b6d727607f CustomRPC: add detail/state and image URL fields (#3758)
Co-authored-by: Vendicated <vendicated@riseup.net>
2025-11-02 17:24:16 +01:00
Vendicated
cf8db5df6f Merge remote-tracking branch 'origin/main' into dev 2025-11-02 17:04:37 +01:00
Andrew
0f258731db ReplaceGoogleSearch: add option to replace engine with single option (#3737)
Co-authored-by: Vendicated <vendicated@riseup.net>
2025-10-28 17:46:07 +00:00
boop-the-dog
6e5a55a961 Merge branch 'main' of https://github.com/Nexulien/Nexulien 2025-10-18 13:53:49 -04:00
boop-the-dog
79b5c43213 Merge branch 'main' of https://github.com/Nexulien/Nexulien 2025-10-10 12:08:05 -04:00
boop-the-dog
55496b9017 a 2025-10-10 12:08:01 -04:00
20 changed files with 394 additions and 183 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "not-nexulien",
"private": "true",
"version": "1.13.4",
"version": "1.13.6",
"description": "the best (worst) discord client mod, now with custom badges and plugins whenever i feel like it",
"homepage": "https://git.defautluser0.xyz/not-nexulien/Not-Nexulien",
"bugs": {
@@ -42,6 +42,7 @@
"floyd-steinberg": "^1.0.6",
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
"jimp": "^1.6.0",
"katex": "^0.16.22",
"monaco-editor": "^0.52.2",
"nanoid": "^5.1.5",
"virtual-merge": "^1.0.1"
@@ -81,7 +82,7 @@
"typescript-transform-paths": "^3.5.5",
"zip-local": "^0.3.5"
},
"packageManager": "pnpm@10.4.1",
"packageManager": "pnpm@10.8.0",
"pnpm": {
"patchedDependencies": {
"eslint@9.20.1": "patches/eslint@9.20.1.patch",

View File

@@ -3,8 +3,10 @@ import { ActivityFlags, ActivityStatusDisplayType, ActivityType } from "../../en
export interface ActivityAssets {
large_image?: string;
large_text?: string;
large_url?: string;
small_image?: string;
small_text?: string;
small_url?: string;
}
export interface ActivityButton {

217
pnpm-lock.yaml generated
View File

@@ -37,6 +37,9 @@ importers:
jimp:
specifier: ^1.6.0
version: 1.6.0
katex:
specifier: ^0.16.22
version: 0.16.22
monaco-editor:
specifier: ^0.52.2
version: 0.52.2
@@ -85,7 +88,7 @@ importers:
version: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
eslint-import-resolver-alias:
specifier: ^1.1.2
version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)))
version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)))
eslint-plugin-path-alias:
specifier: 2.1.0
version: 2.1.0(patch_hash=87545cb13985b338c8fa2ea7b0a3c75c57ad7fbc81c56b38d6c9438329957727)(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
@@ -100,7 +103,7 @@ importers:
version: 12.1.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
eslint-plugin-unused-imports:
specifier: ^4.1.4
version: 4.1.4(@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
version: 4.1.4(@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
highlight.js:
specifier: 11.11.1
version: 11.11.1
@@ -139,7 +142,7 @@ importers:
version: 5.8.2
typescript-eslint:
specifier: ^8.28.0
version: 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
version: 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
typescript-transform-paths:
specifier: ^3.5.5
version: 3.5.5(typescript@5.8.2)
@@ -385,6 +388,12 @@ packages:
cpu: [x64]
os: [win32]
'@eslint-community/eslint-utils@4.4.1':
resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
'@eslint-community/eslint-utils@4.5.1':
resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -676,51 +685,76 @@ packages:
'@types/yazl@2.4.6':
resolution: {integrity: sha512-/ifFjQtcKaoZOjl5NNCQRR0fAKafB3Foxd7J/WvFPTMea46zekapcR30uzkwIkKAAuq5T6d0dkwz754RFH27hg==}
'@typescript-eslint/eslint-plugin@8.28.0':
resolution: {integrity: sha512-lvFK3TCGAHsItNdWZ/1FkvpzCxTHUVuFrdnOGLMa0GGCFIbCgQWVk3CzCGdA7kM3qGVc+dfW9tr0Z/sHnGDFyg==}
'@typescript-eslint/eslint-plugin@8.29.0':
resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/parser@8.28.0':
resolution: {integrity: sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ==}
'@typescript-eslint/parser@8.29.0':
resolution: {integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/scope-manager@8.28.0':
resolution: {integrity: sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==}
'@typescript-eslint/scope-manager@8.24.1':
resolution: {integrity: sha512-OdQr6BNBzwRjNEXMQyaGyZzgg7wzjYKfX2ZBV3E04hUCBDv3GQCHiz9RpqdUIiVrMgJGkXm3tcEh4vFSHreS2Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/type-utils@8.28.0':
resolution: {integrity: sha512-oRoXu2v0Rsy/VoOGhtWrOKDiIehvI+YNrDk5Oqj40Mwm0Yt01FC/Q7nFqg088d3yAsR1ZcZFVfPCTTFCe/KPwg==}
'@typescript-eslint/scope-manager@8.29.0':
resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/type-utils@8.29.0':
resolution: {integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/types@8.28.0':
resolution: {integrity: sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==}
'@typescript-eslint/types@8.24.1':
resolution: {integrity: sha512-9kqJ+2DkUXiuhoiYIUvIYjGcwle8pcPpdlfkemGvTObzgmYfJ5d0Qm6jwb4NBXP9W1I5tss0VIAnWFumz3mC5A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.28.0':
resolution: {integrity: sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==}
'@typescript-eslint/types@8.29.0':
resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.24.1':
resolution: {integrity: sha512-UPyy4MJ/0RE648DSKQe9g0VDSehPINiejjA6ElqnFaFIhI6ZEiZAkUI0D5MCk0bQcTf/LVqZStvQ6K4lPn/BRg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <5.8.0'
'@typescript-eslint/typescript-estree@8.29.0':
resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/utils@8.28.0':
resolution: {integrity: sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ==}
'@typescript-eslint/utils@8.24.1':
resolution: {integrity: sha512-OOcg3PMMQx9EXspId5iktsI3eMaXVwlhC8BvNnX6B5w9a4dVgpkQZuU8Hy67TolKcl+iFWq0XX+jbDGN4xWxjQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.8.0'
'@typescript-eslint/utils@8.29.0':
resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/visitor-keys@8.28.0':
resolution: {integrity: sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==}
'@typescript-eslint/visitor-keys@8.24.1':
resolution: {integrity: sha512-EwVHlp5l+2vp8CoqJm9KikPZgi3gbdZAtabKT9KPShGeOcJhsv4Zdo3oc8T8I0uKEmYoU4ItyxbptjF08enaxg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/visitor-keys@8.29.0':
resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@vap/core@0.0.12':
@@ -992,6 +1026,10 @@ packages:
commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
commander@8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
@@ -1862,6 +1900,10 @@ packages:
jszip@2.7.0:
resolution: {integrity: sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==}
katex@0.16.22:
resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
hasBin: true
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -2218,7 +2260,6 @@ packages:
engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
deprecated: |-
You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.
(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
queue-microtask@1.2.3:
@@ -2606,8 +2647,8 @@ packages:
typed-query-selector@2.12.0:
resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==}
typescript-eslint@8.28.0:
resolution: {integrity: sha512-jfZtxJoHm59bvoCMYCe2BM0/baMswRhMmYhy+w6VfcyHrjxZ0OJe0tGasydCpIpA+A/WIJhTyZfb3EtwNC/kHQ==}
typescript-eslint@8.29.0:
resolution: {integrity: sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -2863,6 +2904,11 @@ snapshots:
'@esbuild/win32-x64@0.25.1':
optional: true
'@eslint-community/eslint-utils@4.4.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))':
dependencies:
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
eslint-visitor-keys: 3.4.3
'@eslint-community/eslint-utils@4.5.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))':
dependencies:
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
@@ -3168,7 +3214,7 @@ snapshots:
'@stylistic/eslint-plugin@4.2.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
dependencies:
'@typescript-eslint/utils': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/utils': 8.24.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
eslint-visitor-keys: 4.2.0
espree: 10.3.0
@@ -3248,14 +3294,14 @@ snapshots:
dependencies:
'@types/node': 22.13.13
'@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
'@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
dependencies:
'@eslint-community/regexpp': 4.12.1
'@typescript-eslint/parser': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/scope-manager': 8.28.0
'@typescript-eslint/type-utils': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/utils': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/visitor-keys': 8.28.0
'@typescript-eslint/parser': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/scope-manager': 8.29.0
'@typescript-eslint/type-utils': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/utils': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/visitor-keys': 8.29.0
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
graphemer: 1.4.0
ignore: 5.3.2
@@ -3265,27 +3311,32 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
'@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
dependencies:
'@typescript-eslint/scope-manager': 8.28.0
'@typescript-eslint/types': 8.28.0
'@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2)
'@typescript-eslint/visitor-keys': 8.28.0
'@typescript-eslint/scope-manager': 8.29.0
'@typescript-eslint/types': 8.29.0
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2)
'@typescript-eslint/visitor-keys': 8.29.0
debug: 4.4.0
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
typescript: 5.8.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@8.28.0':
'@typescript-eslint/scope-manager@8.24.1':
dependencies:
'@typescript-eslint/types': 8.28.0
'@typescript-eslint/visitor-keys': 8.28.0
'@typescript-eslint/types': 8.24.1
'@typescript-eslint/visitor-keys': 8.24.1
'@typescript-eslint/type-utils@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
'@typescript-eslint/scope-manager@8.29.0':
dependencies:
'@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2)
'@typescript-eslint/utils': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/types': 8.29.0
'@typescript-eslint/visitor-keys': 8.29.0
'@typescript-eslint/type-utils@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
dependencies:
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2)
'@typescript-eslint/utils': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
debug: 4.4.0
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
ts-api-utils: 2.1.0(typescript@5.8.2)
@@ -3293,12 +3344,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@8.28.0': {}
'@typescript-eslint/types@8.24.1': {}
'@typescript-eslint/typescript-estree@8.28.0(typescript@5.8.2)':
'@typescript-eslint/types@8.29.0': {}
'@typescript-eslint/typescript-estree@8.24.1(typescript@5.8.2)':
dependencies:
'@typescript-eslint/types': 8.28.0
'@typescript-eslint/visitor-keys': 8.28.0
'@typescript-eslint/types': 8.24.1
'@typescript-eslint/visitor-keys': 8.24.1
debug: 4.4.0
fast-glob: 3.3.3
is-glob: 4.0.3
@@ -3309,20 +3362,50 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
'@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.2)':
dependencies:
'@eslint-community/eslint-utils': 4.5.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
'@typescript-eslint/scope-manager': 8.28.0
'@typescript-eslint/types': 8.28.0
'@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2)
'@typescript-eslint/types': 8.29.0
'@typescript-eslint/visitor-keys': 8.29.0
debug: 4.4.0
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.7.1
ts-api-utils: 2.1.0(typescript@5.8.2)
typescript: 5.8.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.24.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
'@typescript-eslint/scope-manager': 8.24.1
'@typescript-eslint/types': 8.24.1
'@typescript-eslint/typescript-estree': 8.24.1(typescript@5.8.2)
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
typescript: 5.8.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/visitor-keys@8.28.0':
'@typescript-eslint/utils@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)':
dependencies:
'@typescript-eslint/types': 8.28.0
'@eslint-community/eslint-utils': 4.4.1(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
'@typescript-eslint/scope-manager': 8.29.0
'@typescript-eslint/types': 8.29.0
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2)
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
typescript: 5.8.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/visitor-keys@8.24.1':
dependencies:
'@typescript-eslint/types': 8.24.1
eslint-visitor-keys: 4.2.0
'@typescript-eslint/visitor-keys@8.29.0':
dependencies:
'@typescript-eslint/types': 8.29.0
eslint-visitor-keys: 4.2.0
'@vap/core@0.0.12':
@@ -3625,6 +3708,8 @@ snapshots:
commander@2.20.3: {}
commander@8.3.0: {}
component-emitter@1.3.1: {}
concat-map@0.0.1: {}
@@ -3899,9 +3984,9 @@ snapshots:
optionalDependencies:
source-map: 0.6.1
eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))):
eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))):
dependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
eslint-import-resolver-node@0.3.9:
dependencies:
@@ -3911,17 +3996,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)):
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/parser': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)):
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -3932,7 +4017,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -3944,7 +4029,7 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
'@typescript-eslint/parser': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/parser': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -3989,11 +4074,11 @@ snapshots:
dependencies:
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)):
eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)):
dependencies:
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
optionalDependencies:
'@typescript-eslint/eslint-plugin': 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
eslint-scope@8.3.0:
dependencies:
@@ -4665,6 +4750,10 @@ snapshots:
dependencies:
pako: 1.0.11
katex@0.16.22:
dependencies:
commander: 8.3.0
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -5546,11 +5635,11 @@ snapshots:
typed-query-selector@2.12.0: {}
typescript-eslint@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2):
typescript-eslint@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2):
dependencies:
'@typescript-eslint/eslint-plugin': 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/parser': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/utils': 8.28.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2))(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/parser': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
'@typescript-eslint/utils': 8.29.0(eslint@9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215))(typescript@5.8.2)
eslint: 9.20.1(patch_hash=4f22e92770bf528b2448fbec0984b9c0761dd588ed0e83dcc41edfc9af711215)
typescript: 5.8.2
transitivePeerDependencies:

View File

@@ -84,12 +84,14 @@ export function _injectButtons(buttons: ReactNode[], props: ChatBarProps) {
if (props.disabled) return;
for (const [key, Button] of buttonFactories) {
buttons.push(
buttons.unshift(
<ErrorBoundary noop key={key} onError={e => logger.error(`Failed to render ${key}`, e.error)}>
<Button {...props} isMainChat={props.type.analyticsName === "normal"} />
</ErrorBoundary>
);
}
return buttons;
}
export const addChatBarButton = (id: string, button: ChatBarButtonFactory) => buttonFactories.set(id, button);

View File

@@ -16,8 +16,8 @@ export default definePlugin({
{
find: '"sticker")',
replacement: {
match: /return\(\i\.\i\|\|(?=\(.+?(\i)\.push)/,
replace: "$&(Vencord.Api.ChatButtons._injectButtons($1,arguments[0]),false)||"
match: /(?<=className:.{0,20}\.buttons.{0,50}children:)(\i)/,
replace: "Vencord.Api.ChatButtons._injectButtons($1,arguments[0])"
}
}
]

View File

@@ -49,7 +49,7 @@ export default definePlugin({
},
},
{
find: ".METRICS",
find: ".METRICS_V2",
replacement: [
{
match: /this\._intervalId=/,

View File

@@ -62,7 +62,7 @@ function getBrailleCharacter(image: any, xOff: number, yOff: number) {
];
// i hate javascript
return brailleMap.get(JSON.stringify(thing));
return brailleMap.get(JSON.stringify(thing))!;
}
@@ -133,7 +133,7 @@ export default definePlugin({
const invertParam = opts.find(o => o.name === "invert");
let image = imageData.greyscale();
let s = "```\n";
let s = "";
if (opts.find(o => o.name === "width")) {
image.resize({ w: parseInt(opts.find(o => o.name === "width")!.value) });
@@ -160,11 +160,13 @@ export default definePlugin({
for (let j = 0; j < image.width / 2; j++) {
s += getBrailleCharacter(image, j, i);
}
s = s.replaceAll(/\u2800+$/g, "");
s += "\n";
}
sendBotMessage(ctx.channel.id, {
content: s + "\n```"
content: `\`\`\`\n${s}\n\`\`\``
});
}
}

View File

@@ -73,6 +73,11 @@ function isNumberValid(value: number) {
return true;
}
function isUrlValid(value: string) {
if (value && !/^https?:\/\/.+/.test(value)) return "Must be a valid URL.";
return true;
}
function isImageKeyValid(value: string) {
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//.test(value)) return "Don't use a Discord link. Use an Imgur image link instead.";
if (/https?:\/\/(?!i\.)?imgur\.com\//.test(value)) return "Imgur link must be a direct link to the image (e.g. https://i.imgur.com/...). Right click the image and click 'Copy image address'";
@@ -180,8 +185,15 @@ export function RPCSettings() {
{ settingsKey: "appName", label: "Application Name", isValid: makeValidator(128, true) },
]} />
<SingleSetting settingsKey="details" label="Detail (line 1)" isValid={maxLength128} />
<SingleSetting settingsKey="state" label="State (line 2)" isValid={maxLength128} />
<PairSetting data={[
{ settingsKey: "details", label: "Detail (line 1)", isValid: maxLength128 },
{ settingsKey: "detailsURL", label: "Detail URL", isValid: isUrlValid },
]} />
<PairSetting data={[
{ settingsKey: "state", label: "State (line 2)", isValid: maxLength128 },
{ settingsKey: "stateURL", label: "State URL", isValid: isUrlValid },
]} />
<SingleSetting
settingsKey="streamLink"
@@ -195,13 +207,15 @@ export function RPCSettings() {
settingsKey: "partySize",
label: "Party Size",
transform: parseNumber,
isValid: isNumberValid
isValid: isNumberValid,
disabled: s.type !== ActivityType.PLAYING,
},
{
settingsKey: "partyMaxSize",
label: "Maximum Party Size",
transform: parseNumber,
isValid: isNumberValid
isValid: isNumberValid,
disabled: s.type !== ActivityType.PLAYING,
},
]} />
@@ -211,21 +225,23 @@ export function RPCSettings() {
{ settingsKey: "imageBig", label: "Large Image URL/Key", isValid: isImageKeyValid },
{ settingsKey: "imageBigTooltip", label: "Large Image Text", isValid: maxLength128 },
]} />
<SingleSetting settingsKey="imageBigURL" label="Large Image clickable URL" isValid={isUrlValid} />
<PairSetting data={[
{ settingsKey: "imageSmall", label: "Small Image URL/Key", isValid: isImageKeyValid },
{ settingsKey: "imageSmallTooltip", label: "Small Image Text", isValid: maxLength128 },
]} />
<SingleSetting settingsKey="imageSmallURL" label="Small Image clickable URL" isValid={isUrlValid} />
<Divider />
<PairSetting data={[
{ settingsKey: "buttonOneText", label: "Button1 Text", isValid: makeValidator(31) },
{ settingsKey: "buttonOneURL", label: "Button1 URL" },
{ settingsKey: "buttonOneURL", label: "Button1 URL", isValid: isUrlValid },
]} />
<PairSetting data={[
{ settingsKey: "buttonTwoText", label: "Button2 Text", isValid: makeValidator(31) },
{ settingsKey: "buttonTwoURL", label: "Button2 URL" },
{ settingsKey: "buttonTwoURL", label: "Button2 URL", isValid: isUrlValid },
]} />
<Divider />

View File

@@ -60,15 +60,19 @@ export const settings = definePluginSettings({
appID?: string;
appName?: string;
details?: string;
detailsURL?: string;
state?: string;
stateURL?: string;
type?: ActivityType;
streamLink?: string;
timestampMode?: TimestampMode;
startTime?: number;
endTime?: number;
imageBig?: string;
imageBigURL?: string;
imageBigTooltip?: string;
imageSmall?: string;
imageSmallURL?: string;
imageSmallTooltip?: string;
buttonOneText?: string;
buttonOneURL?: string;
@@ -83,14 +87,18 @@ async function createActivity(): Promise<Activity | undefined> {
appID,
appName,
details,
detailsURL,
state,
stateURL,
type,
streamLink,
startTime,
endTime,
imageBig,
imageBigURL,
imageBigTooltip,
imageSmall,
imageSmallURL,
imageSmallTooltip,
buttonOneText,
buttonOneURL,
@@ -137,6 +145,14 @@ async function createActivity(): Promise<Activity | undefined> {
break;
}
if (detailsURL) {
activity.details_url = detailsURL;
}
if (stateURL) {
activity.state_url = stateURL;
}
if (buttonOneText) {
activity.buttons = [
buttonOneText,
@@ -154,7 +170,8 @@ async function createActivity(): Promise<Activity | undefined> {
if (imageBig) {
activity.assets = {
large_image: await getApplicationAsset(imageBig),
large_text: imageBigTooltip || undefined
large_text: imageBigTooltip || undefined,
large_url: imageBigURL || undefined
};
}
@@ -162,7 +179,8 @@ async function createActivity(): Promise<Activity | undefined> {
activity.assets = {
...activity.assets,
small_image: await getApplicationAsset(imageSmall),
small_text: imageSmallTooltip || undefined
small_text: imageSmallTooltip || undefined,
small_url: imageSmallURL || undefined
};
}

View File

@@ -70,7 +70,7 @@ export default definePlugin({
replacement: [
// Add Decor avatar decoration hook to avatar decoration hook
{
match: /(?<=TryItOut:\i,guildId:\i}\),)(?<=user:(\i).+?)/,
match: /(?<=\.avatarDecoration,guildId:\i\}\)\),)(?<=user:(\i).+?)/,
replace: "vcDecorAvatarDecoration=$self.useUserDecorAvatarDecoration($1),"
},
// Use added hook

View File

@@ -104,18 +104,9 @@ export default definePlugin({
replace: "false",
}
},
// Enable option to always record clips even if you are not streaming
{
find: "isDecoupledGameClippingEnabled(){",
replacement: {
match: /\i\.isStaff\(\)/,
replace: "true"
}
},
// Enable experiment embed on sent experiment links
{
find: "dev://experiment/",
find: ".experimentOverride,children:",
replacement: [
{
match: /\i\.isStaff\(\)/,
@@ -123,7 +114,7 @@ export default definePlugin({
},
// Fix some tricky experiments name causing a client crash
{
match: /.getExperimentBucketName.+?if\(null==(\i)\|\|null==\i(?=\)return null;)/,
match: /\.isStaffPersonal\(\).+?if\(null==(\i)\|\|null==\i(?=\)return null;)/,
replace: "$&||({})[$1]!=null"
}
]

View File

@@ -95,10 +95,10 @@ interface ProfileModalProps {
canUsePremiumCustomization: boolean;
hideExampleButton: boolean;
hideFakeActivity: boolean;
isTryItOutFlow: boolean;
isTryItOut: boolean;
}
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOut:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
function SettingsAboutComponentWrapper() {
const [, , userProfileLoading] = useAwaiter(() => fetchUserProfile(UserStore.getCurrentUser().id));
@@ -188,7 +188,7 @@ function SettingsAboutComponent() {
canUsePremiumCustomization={true}
hideExampleButton={true}
hideFakeActivity={true}
isTryItOutFlow={true}
isTryItOut={true}
/>
</div>
</Forms.FormText>

View File

@@ -17,14 +17,12 @@
*/
import { definePluginSettings } from "@api/Settings";
import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { Activity, ActivityAssets, ActivityButton } from "@vencord/discord-types";
import { ActivityFlags, ActivityStatusDisplayType, ActivityType } from "@vencord/discord-types/enums";
import { findByPropsLazy } from "@webpack";
import { ApplicationAssetUtils, FluxDispatcher, Forms } from "@webpack/common";
import { ApplicationAssetUtils, FluxDispatcher, PresenceStore } from "@webpack/common";
interface TrackData {
name: string;
@@ -43,15 +41,15 @@ const enum NameFormat {
AlbumName = "album"
}
const applicationId = "1108588077900898414";
const placeholderId = "2a96cbd8b46e442fc41c2b86b821562f";
// Last.fm API keys are essentially public information and have no access to your account, so including one here is fine.
const API_KEY = "790c37d90400163a5a5fe00d6ca32ef0";
const DISCORD_APP_ID = "1108588077900898414";
const LASTFM_PLACEHOLDER_IMAGE_HASH = "2a96cbd8b46e442fc41c2b86b821562f";
const logger = new Logger("LastFMRichPresence");
const PresenceStore = findByPropsLazy("getLocalPresence");
async function getApplicationAsset(key: string): Promise<string> {
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
return (await ApplicationAssetUtils.fetchAssetIds(DISCORD_APP_ID, [key]))[0];
}
function setActivity(activity: Activity | null) {
@@ -64,25 +62,21 @@ function setActivity(activity: Activity | null) {
const settings = definePluginSettings({
username: {
description: "last.fm username",
type: OptionType.STRING,
},
apiKey: {
description: "last.fm api key",
description: "Last.fm username",
type: OptionType.STRING,
},
shareUsername: {
description: "show link to last.fm profile",
description: "Show link to Last.fm profile",
type: OptionType.BOOLEAN,
default: false,
},
shareSong: {
description: "show link to song on last.fm",
clickableLinks: {
description: "Make track, artist and album names clickable links",
type: OptionType.BOOLEAN,
default: true,
},
hideWithSpotify: {
description: "hide last.fm presence if spotify is running",
description: "Hide Last.fm presence if spotify is running",
type: OptionType.BOOLEAN,
default: true,
},
@@ -92,7 +86,7 @@ const settings = definePluginSettings({
default: false,
},
statusName: {
description: "custom status text",
description: "Custom status text",
type: OptionType.STRING,
default: "some music",
},
@@ -102,12 +96,12 @@ const settings = definePluginSettings({
options: [
{
label: "Don't show (shows generic listening message)",
value: "off",
default: true
value: "off"
},
{
label: "Show artist name",
value: "artist"
value: "artist",
default: true
},
{
label: "Show track name",
@@ -147,7 +141,7 @@ const settings = definePluginSettings({
],
},
useListeningStatus: {
description: 'show "Listening to" status instead of "Playing"',
description: 'Show "Listening to" status instead of "Playing"',
type: OptionType.BOOLEAN,
default: false,
},
@@ -167,10 +161,14 @@ const settings = definePluginSettings({
],
},
showLastFmLogo: {
description: "show the Last.fm logo by the album cover",
description: "Show the Last.fm logo by the album cover",
type: OptionType.BOOLEAN,
default: true,
}
},
apiKey: {
description: "Custom Last.fm API key. You shouldn't need to set this",
type: OptionType.STRING,
},
});
export default definePlugin({
@@ -178,22 +176,6 @@ export default definePlugin({
description: "Little plugin for Last.fm rich presence",
authors: [Devs.dzshn, Devs.RuiNtD, Devs.blahajZip, Devs.archeruwu],
settingsAboutComponent: () => (
<>
<Forms.FormTitle tag="h3">How to get an API key</Forms.FormTitle>
<Forms.FormText>
An API key is required to fetch your current track. To get one, you can
visit <Link href="https://www.last.fm/api/account/create">this page</Link> and
fill in the following information: <br /> <br />
Application name: Discord Rich Presence <br />
Application description: (personal use) <br /> <br />
And copy the API key (not the shared secret!)
</Forms.FormText>
</>
),
settings,
start() {
@@ -206,13 +188,13 @@ export default definePlugin({
},
async fetchTrackData(): Promise<TrackData | null> {
if (!settings.store.username || !settings.store.apiKey)
if (!settings.store.username)
return null;
try {
const params = new URLSearchParams({
method: "user.getrecenttracks",
api_key: settings.store.apiKey,
api_key: settings.store.apiKey || API_KEY,
user: settings.store.username,
limit: "1",
format: "json"
@@ -252,7 +234,7 @@ export default definePlugin({
},
getLargeImage(track: TrackData): string | undefined {
if (track.imageUrl && !track.imageUrl.includes(placeholderId))
if (track.imageUrl && !track.imageUrl.includes(LASTFM_PLACEHOLDER_IMAGE_HASH))
return track.imageUrl;
if (settings.store.missingArt === "placeholder")
@@ -261,13 +243,13 @@ export default definePlugin({
async getActivity(): Promise<Activity | null> {
if (settings.store.hideWithActivity) {
if (PresenceStore.getActivities().some(a => a.application_id !== applicationId)) {
if (PresenceStore.getActivities().some(a => a.application_id !== DISCORD_APP_ID)) {
return null;
}
}
if (settings.store.hideWithSpotify) {
if (PresenceStore.getActivities().some(a => a.type === ActivityType.LISTENING && a.application_id !== applicationId)) {
if (PresenceStore.getActivities().some(a => a.type === ActivityType.LISTENING && a.application_id !== DISCORD_APP_ID)) {
// there is already music status because of Spotify or richerCider (probably more)
return null;
}
@@ -298,12 +280,6 @@ export default definePlugin({
url: `https://www.last.fm/user/${settings.store.username}`,
});
if (settings.store.shareSong)
buttons.push({
label: "View Song",
url: trackData.url,
});
const statusName = (() => {
switch (settings.store.nameFormat) {
case NameFormat.ArtistFirst:
@@ -321,8 +297,8 @@ export default definePlugin({
}
})();
return {
application_id: applicationId,
const activity: Activity = {
application_id: DISCORD_APP_ID,
name: statusName,
details: trackData.name,
@@ -332,6 +308,7 @@ export default definePlugin({
"artist": ActivityStatusDisplayType.STATE,
"track": ActivityStatusDisplayType.DETAILS
}[settings.store.statusDisplayType],
assets,
buttons: buttons.length ? buttons.map(v => v.label) : undefined,
@@ -342,5 +319,16 @@ export default definePlugin({
type: settings.store.useListeningStatus ? ActivityType.LISTENING : ActivityType.PLAYING,
flags: ActivityFlags.INSTANCE,
};
if (settings.store.clickableLinks) {
activity.details_url = trackData.url;
activity.state_url = `https://www.last.fm/music/${encodeURIComponent(trackData.artist)}`;
if (trackData.album) {
activity.assets!.large_url = `https://www.last.fm/music/${encodeURIComponent(trackData.artist)}/${encodeURIComponent(trackData.album)}`;
}
}
return activity;
}
});

View File

@@ -8,6 +8,7 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { React, useEffect, useRef } from "webpack/common/react";
import katex from 'katex';
const blockReact = (data, output, className, _) => {
return (
@@ -98,7 +99,7 @@ const ShadowDomComponent = ({ children, ...props }) => {
if (hostRef.current) {
try {
const shadowRoot = hostRef.current.shadowRoot || hostRef.current.attachShadow({ mode: "open" });
shadowRoot.innerHTML = DOMPurify.sanitize(children.__html, { ADD_TAGS: ["style", "link"], FORBID_TAGS: ["video", "audio"] });
shadowRoot.innerHTML = DOMPurify.sanitize(children.__html, { ADD_TAGS: ["style", "link", "svg", "math"], FORBID_TAGS: ["video", "audio"] });
} catch (e) {
if (!(e instanceof DOMException && e.name === "NotSupportedError")) {
console.error(e);
@@ -134,20 +135,67 @@ const HTMLReact = (data, _1, _2, _3) => {
);
};
const LaTeXReact = (data, _1, _2, _3) => {
if (!settings.store.html) {
return blockReact(data, _1, "invalid-mm-effect", 0);
}
let trueContent = "";
for (const child of data.content) {
if (child.type === "text") {
trueContent += katex.renderToString(cleanBrokenLatex(child.content), { throwOnError: false, maxSize: 10, /* displayMode: _3 === 1 */ })
// TODO: Fix display mode rendering, this is for future Cobble
// if (_3 === 1) {
// console.log(cleanBrokenLatex(child.content))
// }
}
}
return (
// eslint-disable-next-line react/no-children-prop
// <ShadowDomComponent children={{ __html: trueContent }} />
<span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(trueContent, { ADD_TAGS: ["svg", "math"], FORBID_TAGS: ["video", "audio"] }) }}></span>
);
};
/**
* Fixes broken LaTeX strings caused by Discord escaping
*
* @param brokenLatexString you'd never guess what this is
* @returns the cleaned LaTeX string
*/
function cleanBrokenLatex(brokenLatexString: string): string {
let cleaned = brokenLatexString
.replace(/\\([;{}])\|\\\1/g, '\\$1|\\$1')
.replace(/([;{}])\|\1/g, '\\$1|\\$1')
.replace(/\\\\/g, '\\\\\\\\');
return cleaned;
}
function escapeRegex(str: string): string {
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
}
const createRule = (name, order, charList, type, animLength = 0) => {
const regex = new RegExp(`^${escapeRegex(charList[0])}([\\s\\S]+?)${escapeRegex(charList[1])}`);
const reactFunction =
type === "block" ? blockReact :
type === "character" ? characterReact :
type === "html" ? HTMLReact :
type === "delay" ? delayReact :
() => {
throw new Error(`Unsupported type: ${type}`);
};
let reactFunction: (data, output, className, animLength) => React.ReactNode;
switch (type) {
case "block":
reactFunction = blockReact;
break;
case "character":
reactFunction = characterReact;
break;
case "html":
reactFunction = HTMLReact;
break;
case "delay":
reactFunction = delayReact;
break;
case "latex":
reactFunction = LaTeXReact;
break;
default:
throw new Error(`Unsupported type: ${type}`);
}
const rule = {
name: name,
order: order,
@@ -313,6 +361,8 @@ const rules = [
createRule("html", 24, ["[[[", "]]]"], "html"),
createRule("slam", 24, [">>", "<<"], "delay", 250),
createRule("cursive", 24, ["&&", "&&"], "block"),
// createRule("latex_display", 23, ["$$", "$$"], "latex", 1), TODO: for future Cobble
createRule("latex", 24, ["$", "$"], "latex", 0),
];
const rulesByName = {};
@@ -336,7 +386,7 @@ const settings = definePluginSettings({
},
html: {
type: OptionType.BOOLEAN,
description: "Whether to enable HTML effects. WARNING: This can be dangerous.",
description: "Whether to enable HTML or LaTeX effects. WARNING: This can be dangerous.",
default: false,
}
});
@@ -345,7 +395,7 @@ export default definePlugin({
name: "MoreMarkdown",
description: "More markdown capabilities for Nexulien",
nexulien: true,
authors: [Devs.Zoid, Devs.Jaegerwald, Devs.SwitchedCube],
authors: [Devs.Zoid, Devs.Jaegerwald, Devs.SwitchedCube, Devs.Cobble],
rulesByName: rulesByName,
settings,
@@ -359,6 +409,12 @@ export default definePlugin({
},
],
start: () => {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "https://raw.githubusercontent.com/HoodieRocks/NexulienAssets/refs/heads/main/katex.min.css";
link.crossOrigin = "anonymous";
document.head.appendChild(link);
styles = document.createElement("style");
styles.id = "moreMarkdownStyles";
document.head.appendChild(styles);

View File

@@ -22,6 +22,11 @@ const DefaultEngines = {
Wikipedia: "https://wikipedia.org/w/index.php?search=",
} as const;
const enum ReplacementEngineValue {
OFF = "off",
CUSTOM = "custom",
}
const settings = definePluginSettings({
customEngineName: {
description: "Name of the custom search engine",
@@ -32,6 +37,15 @@ const settings = definePluginSettings({
description: "The URL of your Engine",
type: OptionType.STRING,
placeholder: "https://google.com/search?q="
},
replacementEngine: {
description: "Replace with a specific search engine instead of adding a menu",
type: OptionType.SELECT,
options: [
{ label: "Off", value: ReplacementEngineValue.OFF, default: true },
{ label: "Custom Engine", value: ReplacementEngineValue.CUSTOM },
...Object.keys(DefaultEngines).map(engine => ({ label: engine, value: engine }))
]
}
});
@@ -40,13 +54,31 @@ function search(src: string, engine: string) {
}
function makeSearchItem(src: string) {
let Engines = {};
const { customEngineName, customEngineURL, replacementEngine } = settings.store;
if (settings.store.customEngineName && settings.store.customEngineURL) {
Engines[settings.store.customEngineName] = settings.store.customEngineURL;
const hasCustomEngine = Boolean(customEngineName && customEngineURL);
const hasValidReplacementEngine = replacementEngine !== ReplacementEngineValue.OFF && !(replacementEngine === ReplacementEngineValue.CUSTOM && !hasCustomEngine);
const Engines = { ...DefaultEngines };
if (hasCustomEngine) {
Engines[customEngineName!] = customEngineURL;
}
Engines = { ...Engines, ...DefaultEngines };
if (hasValidReplacementEngine) {
const name = replacementEngine === ReplacementEngineValue.CUSTOM && hasCustomEngine
? customEngineName
: replacementEngine;
return (
<Menu.MenuItem
label={`Search with ${name}`}
key="search-custom-engine"
id="vc-search-custom-engine"
action={() => search(src, Engines[name!])}
/>
);
}
return (
<Menu.MenuItem
@@ -95,7 +127,7 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, _props)
export default definePlugin({
name: "ReplaceGoogleSearch",
description: "Replaces the Google search with different Engines",
description: "Replaces the Google search with different Engine(s)",
authors: [Devs.Moxxie, Devs.Ethan],
settings,

View File

@@ -107,7 +107,8 @@ export const toneIndicators = [
ti(["vu"], "very upset"),
ti(["w"], "warmth"),
ti(["unin"], "unintentional"),
ti(["unre"], "unrelated")
ti(["unre"], "unrelated"),
ti(["nh"], "not hateful")
];
const f = toneIndicators.reduce((ret, cur) => {
return {

View File

@@ -25,7 +25,7 @@ import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
import { Menu, Popout, useRef, useState } from "@webpack/common";
import type { ReactNode } from "react";
import type { PropsWithChildren, ReactNode } from "react";
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '.iconBadge,"top"');
@@ -131,16 +131,20 @@ export default definePlugin({
{
find: '?"BACK_FORWARD_NAVIGATION":',
replacement: {
// TODO: (?:\.button) is for stable compat and should be removed soon:tm:
match: /focusSectionProps:"HELP".{0,20},className:(\i(?:\.button)?)\}\),/,
replace: "$& $self.renderVencordPopoutButton($1),"
match: /(?<=trailing:.{0,50})\i\.Fragment,\{(?=.+?className:(\i))/,
replace: "$self.TrailingWrapper,{className:$1,"
}
}
],
renderVencordPopoutButton: (buttonClass: string) => (
<ErrorBoundary noop>
<VencordPopoutButton buttonClass={buttonClass} />
</ErrorBoundary>
)
TrailingWrapper({ children, className }: PropsWithChildren<{ className: string; }>) {
return (
<>
{children}
<ErrorBoundary noop>
<VencordPopoutButton buttonClass={className} />
</ErrorBoundary>
</>
);
},
});

View File

@@ -233,7 +233,7 @@ export default definePlugin({
},
// User Dms top large icon
{
find: 'experimentLocation:"empty_messages"',
find: ".EMPTY_GROUP_DM)",
replacement: {
match: /(?<=SIZE_80,)(?=src:(.+?\))[,}])/,
replace: (_, avatarUrl) => `onClick:()=>$self.openAvatar(${avatarUrl}),`

View File

@@ -21,6 +21,7 @@ import "./styles.css";
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
import { Microphone } from "@components/Icons";
import { Link } from "@components/Link";
import { Paragraph } from "@components/Paragraph";
import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal";
@@ -144,7 +145,7 @@ function Modal({ modalProps }: { modalProps: ModalProps; }) {
URL.revokeObjectURL(blobUrl);
}, [blobUrl]);
const [meta] = useAwaiter(async () => {
const [meta, metaError] = useAwaiter(async () => {
if (!blob) return EMPTY_META;
const audioContext = new AudioContext();
@@ -214,11 +215,15 @@ function Modal({ modalProps }: { modalProps: ModalProps; }) {
</div>
<Forms.FormTitle>Preview</Forms.FormTitle>
<VoicePreview
src={blobUrl}
waveform={meta.waveform}
recording={isRecording}
/>
{metaError
? <Paragraph className={cl("error")}>Failed to parse selected audio file: {metaError.message}</Paragraph>
: (
<VoicePreview
src={blobUrl}
waveform={meta.waveform}
recording={isRecording}
/>
)}
{isUnsupportedFormat && (
<Card className={`vc-warning-card ${Margins.top16}`}>
@@ -236,7 +241,7 @@ function Modal({ modalProps }: { modalProps: ModalProps; }) {
<Button
disabled={!blob}
onClick={() => {
sendAudio(blob!, meta);
sendAudio(blob!, meta ?? EMPTY_META);
modalProps.onClose();
showToast("Now sending voice message... Please be patient", Toasts.Type.MESSAGE);
}}

View File

@@ -48,3 +48,7 @@
flex: 1;
text-align: center;
}
.vc-vmsg-error {
color: var(--text-danger);
}