From 036de69acd0b7ab288ef8bbedd2da4dfb6f326ab Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:42:10 +0100 Subject: [PATCH 01/14] Update README.md --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bbe290a..4c3b592 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,40 @@ -# ShiggyCord [![Discord](https://img.shields.io/discord/1427396621905432699?style=social&logo=discord&label=ShiggyCord)](https://discord.gg/nQykFF9Ud6) +# GoonCord [![Discord](https://img.shields.io/discord/1427396621905432699?style=social&logo=discord&label=ShiggyCord)](https://discord.gg/nQykFF9Ud6) -Bundle based on Kettu, made just for fun +An unofficial fork of ShiggyGord, made just for fun +Idea taken from me ## Installing ### Android -- Rooted: [Shiggy Xposed](https://github.com/kmmiio99o/ShiggyXposed) +- Rooted: [Goon Xposed](https://github.com/OTKUSteyler/GoonXposed) -- Non-Rooted: [Shiggy Manager](https://github.com/kmmiio99o/ShiggyManager) +- Non-Rooted: [Goon Manger](https://github.com/OTKUSteyler/GoonManager) ### Android/iOS - **Injecting bundle:** ```url - https://github.com/kmmiio99o/ShiggyCord/releases/latest/download/shiggycord.js + https://github.com/OTKUSteyler/GoonCord/releases/latest/download/gooncord.js ``` ## Building -1. Install a ShiggyCord loader with loader config support (any mentioned in the [Installing](#installing) section). +1. Install a GoonCord loader with loader config support (any mentioned in the [Installing](#installing) section). 1. Go to Settings > General and enable Developer Settings. 1. Clone the repo: ``` - git clone https://github.com/kmmiio99o/Shiggycord.git + git clone https://github.com/OTKUSteyler/GoonCord.git ``` 1. Install dependencies: ``` bun i ``` -1. Build ShiggyCord's code: +1. Build GoonCord's code: ``` bun run build ``` 1. In the newly created `dist` directory, run a HTTP server. I recommend [http-server](https://www.npmjs.com/package/http-server). -1. Go to Settings > Developer enabled earlier. Enable `Load from custom url` and input the IP address and port of the server (e.g. `http://192.168.1.236:4040/shiggycord.js`) in the new input box labelled `ShiggyCord URL`. -1. Restart Discord. Upon reload, you should notice that your device will download ShiggyCord's bundled code from your server, rather than GitHub. +1. Go to Settings > Developer enabled earlier. Enable `Load from custom url` and input the IP address and port of the server (e.g. `http://192.168.1.236:4040/gooncord.js`) in the new input box labelled `GoonCord URL`. +1. Restart Discord. Upon reload, you should notice that your device will download GoonCord's bundled code from your server, rather than GitHub. 1. Make your changes, rebuild, reload, go wild! -Alternatively, you can directly *serve* the bundled code by running `bun run serve`. `shiggycord.js` will be served on your local address under the port 4040. You will then insert `http://:4040/shiggycord.js` as a custom url and reload. Whenever you restart your mobile client, the script will rebuild the bundle as your client fetches it. +Alternatively, you can directly *serve* the bundled code by running `bun run serve`. `gooncord.js` will be served on your local address under the port 4040. You will then insert `http://:4040/gooncord.js` as a custom url and reload. Whenever you restart your mobile client, the script will rebuild the bundle as your client fetches it. From 20d6ff15ea17183a3b4611ba2dfa86f76d415620 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:44:02 +0100 Subject: [PATCH 02/14] Update release.yml --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 14a6768..7e57a6a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -110,7 +110,7 @@ jobs: tag_name: ${{ steps.release_info.outputs.release_tag }} name: ${{ steps.release_info.outputs.release_name }} files: | - dist/shiggycord.js - dist/shiggycord.min.js + dist/gooncord.js + dist/gooncord.min.js env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 1523b51108e823f48b44cadf76d88a8994a99fe3 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:45:59 +0100 Subject: [PATCH 03/14] Rename command from 'debug' to 'Goon' --- src/core/commands/debug.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/commands/debug.ts b/src/core/commands/debug.ts index 466af61..a6ca820 100644 --- a/src/core/commands/debug.ts +++ b/src/core/commands/debug.ts @@ -8,7 +8,7 @@ import { messageUtil } from "@metro/common"; export default () => { - name: "debug", + name: "Goon", description: Strings.COMMAND_DEBUG_DESC, options: [ { @@ -20,8 +20,8 @@ export default () => execute([ephemeral], ctx) { const info = getDebugInfo(); const content = [ - "**ShiggyCord Debug Info**", - `> ShiggyCord: ${info.bunny.version} (${info.bunny.loader.name} ${info.bunny.loader.version})`, + "**GoonCord Debug Info**", + `> GoonCord: ${info.bunny.version} (${info.bunny.loader.name} ${info.bunny.loader.version})`, `> Discord: ${info.discord.version} (${info.discord.build})`, `> React: ${info.react.version} (RN ${info.react.nativeVersion})`, `> Hermes: ${info.hermes.version} (bcv${info.hermes.bytecodeVersion})`, From 414cf25ae8a4a9a31a613852385ba4a104fcdf20 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:48:06 +0100 Subject: [PATCH 04/14] Update default.json --- src/core/i18n/default.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/i18n/default.json b/src/core/i18n/default.json index d484854..cc1935c 100644 --- a/src/core/i18n/default.json +++ b/src/core/i18n/default.json @@ -8,8 +8,8 @@ "AUTO_DEVTOOLS": "Automatically connect to Devtools", "ASSET_BROWSER": "Asset Browser", "BRAND": "Brand", - "SHIGGYCORD": "ShiggyCold", - "SHIGGYCORD_URL": "ShiggyCold URL", + "SHIGGYCORD": "GoonCord", + "SHIGGYCORD_URL": "GoonCord URL", "BROWSER": "Browser", "BYTECODE": "Bytecode", "CANCEL": "Cancel", @@ -21,7 +21,7 @@ "CLEAR_DATA_SUCCESSFUL": "Cleared data for {name}", "CODEBERG": "Codeberg", "CODENAME": "Codename", - "COMMAND_DEBUG_DESC": "Send ShiggyCord debug info.", + "COMMAND_DEBUG_DESC": "Send GoonCord debug info.", "COMMAND_DEBUG_OPT_EPHEMERALLY": "Send debug info ephemerally.", "COMMAND_EVAL_DESC": "Evaluate JavaScript code.", "COMMAND_EVAL_OPT_ASYNC": "Whether to support 'await' in code. Must explicitly return for result (default: false)", @@ -67,9 +67,9 @@ "LABEL_EXTRACT_FONTS_FROM_THEME": "Extract font from theme", "LINKS": "Links", "LOAD_FROM_CUSTOM_URL": "Load from custom URL", - "LOAD_FROM_CUSTOM_URL_DEC": "Load ShiggyCord from a custom endpoint.", + "LOAD_FROM_CUSTOM_URL_DEC": "Load GoonCord from a custom endpoint.", "LOAD_REACT_DEVTOOLS": "Load React DevTools", - "SHIGGY_URL": "ShiggyCord URL", + "SHIGGY_URL": "GoonCord URL", "LOADER": "Loader", "MACHINE_ID": "Machine ID", "MANUFACTURER": "Manufacturer", @@ -91,7 +91,7 @@ "PLUGINS": "Plugins", "REFETCH": "Refetch", "RELOAD": "Reload", - "RELOAD_DISCORD": "Reshiggy your Discord", + "RELOAD_DISCORD": "ReGoon your Discord", "RELOAD_IN_NORMAL_MODE": "Reload in Normal Mode", "RELOAD_IN_NORMAL_MODE_DESC": "Safe mode currently enabled, tap to reload in normal mode", "RELOAD_IN_SAFE_MODE": "Reload in Safe Mode", @@ -120,7 +120,7 @@ "UH_OH": "Uh Oh", "UNINSTALL": "Uninstall", "UNINSTALL_TITLE": "Uninstall {title}", - "URL_PLACEHOLDER": "https://github.com/kmmiio99o/ShiggyCord", + "URL_PLACEHOLDER": "https://github.com/OTKUSteyler/GoonCord", "VERSION": "Version", "VERSIONS": "Versions" } From a56b432fba7823b53ad0f7fd3d09101e6f9bdfef Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:50:29 +0100 Subject: [PATCH 05/14] Update index.ts --- src/core/plugins/fixembed/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/plugins/fixembed/index.ts b/src/core/plugins/fixembed/index.ts index efda7f3..de6d673 100644 --- a/src/core/plugins/fixembed/index.ts +++ b/src/core/plugins/fixembed/index.ts @@ -42,19 +42,19 @@ function transformLinks(content: string, config: FixEmbedSettings): string { if (config.instagram) { result = result.replace( /https?:\/\/(?:www\.)?instagram\.com(\/[^\s]+)/gi, - "https://uuinstagram.com$1", + "https://kkinstagram.com$1", ); } // TikTok: Replace domain, keep path if (config.tiktok) { result = result.replace( /https?:\/\/(?:www\.)?tiktok\.com(\/[^\s]+)/gi, - "https://tnktok.com$1", + "https://tiktokez.com$1", ); // TikTok short links (vm.tiktok.com) result = result.replace( /https?:\/\/vm\.tiktok\.com\/([A-Za-z0-9]+)\/?/gi, - "https://vm.tnktok.com/$1", + "https://vm.tiktokez.com/$1", ); } // Reddit: Replace domain, keep path From 19d3493322520651ff37f4be609b2ac9a88d8281 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:56:03 +0100 Subject: [PATCH 06/14] Update build.mjs --- scripts/build.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build.mjs b/scripts/build.mjs index 9780a54..283d2d9 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -30,7 +30,7 @@ let context = null; const config = { entryPoints: ["src/entry.ts"], bundle: true, - outfile: "dist/shiggycord.js", + outfile: "dist/gooncord.js", format: "iife", splitting: false, // Enable minification by default for release builds (when a release-branch is provided). @@ -75,7 +75,7 @@ const config = { constModules: { globals: { "bunny-build-info": { - version: `"Jolly 1.4"`, + version: `"1.1.11"`, }, }, }, From 401165eb3448ff86e801ce0211d3018905271b36 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 01:59:46 +0100 Subject: [PATCH 07/14] Update index.ts --- src/core/ui/settings/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ui/settings/index.ts b/src/core/ui/settings/index.ts index c090a7e..bc9224e 100644 --- a/src/core/ui/settings/index.ts +++ b/src/core/ui/settings/index.ts @@ -11,7 +11,7 @@ export { shiggycordIcon }; export default function initSettings() { registerSection({ - name: "ShiggyCord", + name: "💦GoonCord💦", items: [ { key: "SHIGGYCORD", From 7f99346971de81eddfe39483c889d84bfdf68f36 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 02:04:24 +0100 Subject: [PATCH 08/14] Update default.json --- src/core/i18n/default.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/i18n/default.json b/src/core/i18n/default.json index cc1935c..24457ee 100644 --- a/src/core/i18n/default.json +++ b/src/core/i18n/default.json @@ -8,7 +8,7 @@ "AUTO_DEVTOOLS": "Automatically connect to Devtools", "ASSET_BROWSER": "Asset Browser", "BRAND": "Brand", - "SHIGGYCORD": "GoonCord", + "SHIGGYCORD": "💦GoonCord💦", "SHIGGYCORD_URL": "GoonCord URL", "BROWSER": "Browser", "BYTECODE": "Bytecode", From 68dc8238c3321845a50078ec09867bd12f9df8a0 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 02:05:08 +0100 Subject: [PATCH 09/14] Enhance debug info header with emoji --- src/core/commands/debug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/commands/debug.ts b/src/core/commands/debug.ts index a6ca820..5e565b7 100644 --- a/src/core/commands/debug.ts +++ b/src/core/commands/debug.ts @@ -20,7 +20,7 @@ export default () => execute([ephemeral], ctx) { const info = getDebugInfo(); const content = [ - "**GoonCord Debug Info**", + "**💦GoonCord Debug Info💦**", `> GoonCord: ${info.bunny.version} (${info.bunny.loader.name} ${info.bunny.loader.version})`, `> Discord: ${info.discord.version} (${info.discord.build})`, `> React: ${info.react.version} (RN ${info.react.nativeVersion})`, From b0e1180182cc45c5b9e999371b38c70586b52a42 Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 02:07:05 +0100 Subject: [PATCH 10/14] Add files via upload --- src/assets/icons/shiggy.png | Bin 1230 -> 21563 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/assets/icons/shiggy.png b/src/assets/icons/shiggy.png index abd0db21175a40b9922899f11ebc2b2ba981a914..dcffef610ab665e3f42b2caf182c7dea67eaa3e8 100644 GIT binary patch literal 21563 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 VYbWMo!M%os?g-!B7S literal 1230 zcmV;<1Tp)GP)=UJJ!dH&Nh(b>x;pdjO-Cx^&%ieK$hi? zm>YaqF9K2p6vh1D=taO^2bASo2n0j{kfEmrmp%j>6_91sBjy21dJ&L5U~F*oA%Fk^ zjtS7Ab?~wbhqpd&AP^7*peS^+F+8~Sncuh&kSf4WMg1~F38D`H#{^(#1N4VC;{2jT zKzabb6d6Fu(1)cb;HUswh{6zz0;ZQN0#XGOMV5`HSA;G_1{m7B5|AbUkD}(nwxr|R zmQ^4EA^`NuZ3zcGm4F4St_esH5EkGNU<~B}^7jVkPr&Yg;Z%OJIz&JLZc>BF8- z1oOPE$9mub2B}vpMg&9zkYUUJ5dy3w1ZeRQkRHI7pgyV?UW%G#t_)vZhzQsjpozx- z?IXq(Bmv0lODiD(y8~pRL87KnipRCBCs;vZa*}cEB87l-0RG05E;iEuB`CmdSgv}E zML+}qn@s9jHWeDeQHZqp7D?^_Whw1ij0B_#(2b?V7yvi}XyO;=K>~IGXnGV|M7(he0LFM?E+k-gfHHIdO@*nY?F9&E@i!+F zfaPe_o``^G0L@RdGa-F+0mCJUZA(|)D<@!QfD)boAgwRK;f=_`Z7Kng0BkB+5=h(y zbP19eAAcku1%MGyiv6++%P`!Eb^-n?Q3S*e=nt_pw6}k?_dj+11VjM9R-!v3HlX-X z44H6>LT^ziz<-R<6KumuKpFu12%=H4?0l{&xg8~6X2IqIB_+qs=b?g>$5j$}CkRLb z(5FcH%OfP+>7+L}14o1qwgIq&KtL*h;S_is16;2|8<5S;pMZ}7x(P51 z`DLfuYJhnH0qFu{(>V;V#mE3-gq8mX2>3W4Oz*d!{b@*3Uaxb27tWu6odI^cA}m4s zH`3pJBP6Wa4HFOn03|pMkk)BH`0$E=6aaD?!ry$vQ5n`YARz!ffB<0V@g)H%0PHa{ ze&WOcNT8w1l%>}K)UPFyx%pQmE7%izsqrH?UpV9M+1P+P2Z)wEinO60sQ2nfH#*O0Z{>(-{>w! zdW?X-0I&_IUa Date: Sat, 27 Dec 2025 02:08:45 +0100 Subject: [PATCH 11/14] Update index.tsx --- src/core/ui/settings/pages/General/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ui/settings/pages/General/index.tsx b/src/core/ui/settings/pages/General/index.tsx index 8a5bef0..9261fda 100644 --- a/src/core/ui/settings/pages/General/index.tsx +++ b/src/core/ui/settings/pages/General/index.tsx @@ -113,7 +113,7 @@ export default function General() { > } trailing={} /> From af232757356233f61c15ec4e1ba327ca7d21d0db Mon Sep 17 00:00:00 2001 From: OTKUSteyler <90369564+OTKUSteyler@users.noreply.github.com> Date: Sat, 27 Dec 2025 02:10:26 +0100 Subject: [PATCH 12/14] Update About.tsx --- src/core/ui/settings/pages/General/About.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ui/settings/pages/General/About.tsx b/src/core/ui/settings/pages/General/About.tsx index 55b5391..da19fcc 100644 --- a/src/core/ui/settings/pages/General/About.tsx +++ b/src/core/ui/settings/pages/General/About.tsx @@ -97,7 +97,7 @@ export default function About() { variant="text-md/medium" style={{ textAlign: "center", marginTop: 4 }} > - Jolly your discord client! + 💦Goon your discord client!💦 From 199ed9f8b21736309f80df3c0546bb224f8ab2d2 Mon Sep 17 00:00:00 2001 From: kmmiio99o Date: Sat, 27 Dec 2025 14:30:44 +0100 Subject: [PATCH 13/14] fix: Property 'WeakRef' doesn't exist --- scripts/build.mjs | 2 +- shims/weakref.js | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 shims/weakref.js diff --git a/scripts/build.mjs b/scripts/build.mjs index 9780a54..82297a5 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -50,7 +50,7 @@ const config = { window: "globalThis", __DEV__: JSON.stringify(releaseBranch !== "main"), }, - inject: ["./shims/asyncIteratorSymbol.js", "./shims/promiseAllSettled.js"], + inject: ["./shims/asyncIteratorSymbol.js", "./shims/promiseAllSettled.js", "./shims/weakref.js"], legalComments: "none", alias: { "!ShiggyCord-deps-shim!": "./shims/depsModule.ts", diff --git a/shims/weakref.js b/shims/weakref.js new file mode 100644 index 0000000..98cabf0 --- /dev/null +++ b/shims/weakref.js @@ -0,0 +1,128 @@ +// @ts-nocheck +/** + * WeakRef / FinalizationRegistry shim + * + * Purpose: + * - Provide a safe fallback when the runtime doesn't implement WeakRef or FinalizationRegistry. + * - This fallback avoids a ReferenceError and keeps code paths functional, but it does NOT + * emulate true weak-reference GC behavior. Use it only as a compatibility fallback. + * + */ + +let _shimWarned = false; + +function _warnOnce(msg) { + if (!_shimWarned) { + // keep this quiet by default; print only when fallback is actually used + try { + // Prefer console.warn when available + if (typeof console !== "undefined" && typeof console.warn === "function") { + console.warn(`[weakref-shim] ${msg}`); + } + } catch (_) {} + _shimWarned = true; + } +} + +/** + * WeakRef fallback + * - Keeps a strong reference to the target (so it will not be GC'd). + * - Implements the minimal `deref()` API. + */ +class WeakRefFallback { + constructor(value) { + // Keep a strong reference: this is *not* weak. + this.__value = value; + _warnOnce( + "WeakRef is not available in this runtime. Using a strong-reference fallback — memory usage/semantics may differ." + ); + } + + deref() { + return this.__value; + } +} + +/** + * FinalizationRegistry fallback + * - No-op registry: register/unregister do nothing. + * - Implement `cleanupSome` as a best-effort sync call when a callback is provided, + * but it cannot be tied to GC. + */ +class FinalizationRegistryFallback { + constructor(cleanupCallback) { + // store callback to allow optional manual invocation via cleanupSome + this.__cleanupCallback = typeof cleanupCallback === "function" ? cleanupCallback : null; + _warnOnce( + "FinalizationRegistry is not available in this runtime. Using a no-op fallback — finalizers will not run based on GC." + ); + } + + /** + * register(target, heldValue, unregisterToken?) + * - No-op in fallback. We keep no strong references here on purpose (can't emulate GC). + */ + register(_target /*, _heldValue, _unregisterToken */) { + // intentionally no-op + } + + /** + * unregister(unregisterToken) + * - No-op in fallback. + */ + unregister(_unregisterToken) { + // intentionally no-op + } + + /** + * cleanupSome(callback?) + * - If provided a callback or a stored cleanup callback exists, call it immediately. + * - This is NOT equivalent to real FinalizationRegistry cleanup; it's only a manual helper. + */ + cleanupSome(callback) { + const cb = typeof callback === "function" ? callback : this.__cleanupCallback; + if (typeof cb === "function") { + try { + cb(); + } catch (e) { + try { + if (typeof console !== "undefined" && typeof console.error === "function") { + console.error("[weakref-shim] error running cleanupSome callback:", e); + } + } catch (_) {} + } + } + } +} + +// If native implementations exist, prefer them; otherwise install fallbacks. +// We assign to globalThis so code using `WeakRef`/`FinalizationRegistry` globals doesn't crash. +const NativeWeakRef = + typeof globalThis !== "undefined" && typeof globalThis.WeakRef === "function" ? globalThis.WeakRef : undefined; + +const NativeFinalizationRegistry = + typeof globalThis !== "undefined" && typeof globalThis.FinalizationRegistry === "function" + ? globalThis.FinalizationRegistry + : undefined; + +const WeakRefImpl = NativeWeakRef ?? WeakRefFallback; +const FinalizationRegistryImpl = NativeFinalizationRegistry ?? FinalizationRegistryFallback; + +try { + if (typeof globalThis !== "undefined") { + if (typeof globalThis.WeakRef === "undefined") { + // Install fallback + globalThis.WeakRef = WeakRefImpl; + } + if (typeof globalThis.FinalizationRegistry === "undefined") { + globalThis.FinalizationRegistry = FinalizationRegistryImpl; + } + } +} catch (e) { + // Some embedder environments may forbid writing globals; ignore in that case. + _warnOnce("Unable to assign WeakRef/FinalizationRegistry to globalThis: " + (e && e.message)); +} + +// Export the implementations so the inject mechanism (or explicit imports) can reference them. +// Export names are sorted to satisfy lint rules that require sorted exports. +export { FinalizationRegistryImpl as FinalizationRegistry, WeakRefImpl as WeakRef }; From 3f0c22342afdb490672c1a4f41ca25fdc3ad55ea Mon Sep 17 00:00:00 2001 From: kmmiio99o Date: Sat, 27 Dec 2025 15:12:21 +0100 Subject: [PATCH 14/14] Merge two plugin pages for easier management --- src/core/ui/settings/index.ts | 11 +---- .../ui/settings/pages/Plugins/CorePlugins.tsx | 45 ------------------- src/core/ui/settings/pages/Plugins/index.tsx | 8 ++-- 3 files changed, 5 insertions(+), 59 deletions(-) delete mode 100644 src/core/ui/settings/pages/Plugins/CorePlugins.tsx diff --git a/src/core/ui/settings/index.ts b/src/core/ui/settings/index.ts index c090a7e..857d896 100644 --- a/src/core/ui/settings/index.ts +++ b/src/core/ui/settings/index.ts @@ -21,18 +21,9 @@ export default function initSettings() { useTrailing: () => `(${version})`, }, { - key: "CORE_PLUGINS", + key: "BUNNY_PLUGINS", title: () => Strings.PLUGINS, icon: findAssetId("ActivitiesIcon"), - render: () => import("@core/ui/settings/pages/Plugins/CorePlugins"), - }, - { - key: "BUNNY_PLUGINS", - title: () => "External Plugins", - icon: - findAssetId("DownloadIcon") ?? - findAssetId("LinkIcon") ?? - findAssetId("ActivitiesIcon"), render: () => import("@core/ui/settings/pages/Plugins"), }, { diff --git a/src/core/ui/settings/pages/Plugins/CorePlugins.tsx b/src/core/ui/settings/pages/Plugins/CorePlugins.tsx deleted file mode 100644 index c08e4c2..0000000 --- a/src/core/ui/settings/pages/Plugins/CorePlugins.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { React } from "@metro/common"; -import AddonPage from "@core/ui/components/AddonPage"; -import PluginCard from "@core/ui/settings/pages/Plugins/components/PluginCard"; -import { corePluginInstances, registeredPlugins } from "@lib/addons/plugins"; -import { UnifiedPluginModel } from "@core/ui/settings/pages/Plugins/models"; -import unifyBunnyPlugin from "@core/ui/settings/pages/Plugins/models/bunny"; -import { Strings } from "@core/i18n"; - -/** - * Core plugins settings page - * - * This page shows only the built-in core plugins. Core plugins are always - * installed (can't be uninstalled) and are registered in `corePluginInstances`. - * - * We reuse the existing `AddonPage` + `PluginCard` components and feed them - * the normalized `UnifiedPluginModel` objects produced by `unifyBunnyPlugin`. - */ - -export default function CorePlugins() { - return ( - - CardComponent={PluginCard} - title={Strings.PLUGINS} - searchKeywords={[ - "name", - "description", - (p) => - p.authors - ?.map((a: any) => (typeof a === "string" ? a : a.name)) - .join() || "", - ]} - // Provide simple sort options so the Search input renders round and a sort menu appears - sortOptions={{ - "Name (A-Z)": (a, b) => a.name.localeCompare(b.name), - "Name (Z-A)": (a, b) => b.name.localeCompare(a.name), - }} - // Only core plugins: map corePluginInstances -> registeredPlugins -> unify - items={[...corePluginInstances.keys()] - .map((id) => registeredPlugins.get(id)) - .filter((m): m is any => m !== undefined) - .map(unifyBunnyPlugin)} - ListHeaderComponent={() => null} - /> - ); -} diff --git a/src/core/ui/settings/pages/Plugins/index.tsx b/src/core/ui/settings/pages/Plugins/index.tsx index 2c2514b..97e3e68 100644 --- a/src/core/ui/settings/pages/Plugins/index.tsx +++ b/src/core/ui/settings/pages/Plugins/index.tsx @@ -702,7 +702,7 @@ export default function Plugins() { // Use the insertion order of pluginSettings so newly-installed plugins // (which add entries to pluginSettings) appear first. const installedBnIds = Object.keys(pluginSettings || {}) - .filter((id) => registeredPlugins.has(id) && !isCorePlugin(id)) + .filter((id) => registeredPlugins.has(id)) .slice() .reverse(); @@ -710,12 +710,12 @@ export default function Plugins() { .map((id) => registeredPlugins.get(id)!) .map(unifyBunnyPlugin); - // Merge lists: show Vendetta-managed plugins first (recent first), + // Merge lists: show Vendetta-managed plugins first, // then Bunny-installed externals (recent first). const allPlugins = [...vdPlugins, ...bnPlugins]; - // Filter out core plugins from the list - return allPlugins.filter((plugin) => !isCorePlugin(plugin.id)); + // Include core plugins in the list + return allPlugins; }} ListHeaderComponent={() => null} installAction={{