From 710a7538a3ef67644120261934d4b45e9d142b6c Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Sat, 27 Jun 2026 11:05:54 -0400 Subject: [PATCH] Feature Request: Fix Discord Links --- .gemini/styleguide.md | 20 +++++++++---------- .github/ISSUE_TEMPLATE/feature_request.yml | 14 ++++++------- .rules | 14 ++++++------- CONTRIBUTING.md | 2 +- .../vcNarratorCustom/index.tsx | 2 +- src/plugins/memberCount/index.tsx | 2 +- src/plugins/translate/settings.tsx | 6 +++--- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index 85e572468..ba42e5bff 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -96,7 +96,7 @@ Flag these and suggest the fix: **No comments.** Never add comments unless explicitly asked. However, preserve existing comments as they contain important context. ```typescript -// GOOD — early return, destructuring, inference, no comments +// GOOD - early return, destructuring, inference, no comments const getUser = (id: string) => { const user = UserStore.getUser(id); if (!user) return null; @@ -104,7 +104,7 @@ const getUser = (id: string) => { return `${username}#${discriminator}`; }; -// BAD — nested, verbose, unnecessary annotations +// BAD - nested, verbose, unnecessary annotations function getUser(id: string): string | null { // Get the user from the store const user = UserStore.getUser(id); @@ -172,8 +172,8 @@ className={classes(cl("wrapper"), someDiscordClass, isActive && cl("active"))} ## Settings -- `settings.store.key` — reactive, auto-persists (React components) -- `settings.plain.key` — non-reactive raw value (basically never use this, only for special cases) +- `settings.store.key` - reactive, auto-persists (React components) +- `settings.plain.key` - non-reactive raw value (basically never use this, only for special cases) --- @@ -274,7 +274,7 @@ Plugins that don't use patches don't require a Discord restart to apply. Their ` **Watch for stale closures and references.** If a plugin stores references to DOM nodes, channels, or users in module scope, check that they're nulled out in `stop()`. ```typescript -// GOOD — clean start/stop, no leaks +// GOOD - clean start/stop, no leaks start() { this.interval = setInterval(this.update, 5000); document.addEventListener("visibilitychange", this.onVisibilityChange); @@ -284,7 +284,7 @@ stop() { document.removeEventListener("visibilitychange", this.onVisibilityChange); } -// BAD — leaks interval and listener forever +// BAD - leaks interval and listener forever start() { setInterval(this.update, 5000); document.addEventListener("visibilitychange", this.onVisibilityChange); @@ -359,7 +359,7 @@ If a PR reimplements any of these, flag it. They already exist: ## Review Severity -1. **CRITICAL** — `any` types, hardcoded CDN/API URLs, direct DOM manipulation, security issues, massive overengineering/bloat, suspected AI slop (note it, but still review everything) -2. **HIGH** — Missing useEffect cleanup, forbidden React APIs, hardcoded class names, console logging statements, missing definePluginSettings, unnecessary abstractions -3. **MEDIUM** — Anti-patterns (`||` instead of `??`), utility reimplementations, commented-out code, bad description format, excessive comments -4. **LOW** — Style preferences, minor performance wins, organization +1. **CRITICAL** - `any` types, hardcoded CDN/API URLs, direct DOM manipulation, security issues, massive overengineering/bloat, suspected AI slop (note it, but still review everything) +2. **HIGH** - Missing useEffect cleanup, forbidden React APIs, hardcoded class names, console logging statements, missing definePluginSettings, unnecessary abstractions +3. **MEDIUM** - Anti-patterns (`||` instead of `??`), utility reimplementations, commented-out code, bad description format, excessive comments +4. **LOW** - Style preferences, minor performance wins, organization diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 2a8d59f98..99b39f583 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -7,9 +7,9 @@ body: - type: markdown attributes: value: | - This form is not for any of the following: - - Plugin requests — Go to our [Discord server](https://discord.gg/D9uwnFnqmd) for that - - Feature requests for plugins — Go to our [Discord server](https://discord.gg/D9uwnFnqmd) for that + This form is not for any of the following: + - Plugin requests - Go to our [Discord server](https://equicord.org/discord) for that + - Feature requests for plugins - Go to our [Discord server](https://equicord.org/discord) for that - type: textarea id: feature-description @@ -39,7 +39,7 @@ body: attributes: label: Request Agreement options: - - label: I've searched existing issues and this hasn't been suggested before - - label: This is a **core modification feature**, not a plugin request (those go in Discord) - - label: This feature would benefit most users, not just a specific use case - - label: I am willing to work on this myself + - label: I've searched existing issues and this hasn't been suggested before + - label: This is a **core modification feature**, not a plugin request (those go in Discord) + - label: This feature would benefit most users, not just a specific use case + - label: I am willing to work on this myself diff --git a/.rules b/.rules index 96dece78f..5be9f7ed7 100644 --- a/.rules +++ b/.rules @@ -160,9 +160,9 @@ Declarative fields auto-enable these. Imperative doesn't. - `group: true` for atomic multi-step rewrites. On any failure (no effect or throw), whole group rolls back. - `predicate: () => boolean` gates on runtime values. `fromBuild`/`toBuild` gate on Discord build numbers. Both apply per patch and per replacement. Never branch inside `replace`. - `noWarn: true` suppresses "had no effect" warning. Use only for intentionally optional replacements. -- `all: true` only when one anchor legitimately occurs across multiple modules. Intl keys resolve to one module — do NOT set `all` on intl-anchored patches. +- `all: true` only when one anchor legitimately occurs across multiple modules. Intl keys resolve to one module - do NOT set `all` on intl-anchored patches. - Never `try/catch` to silence a failing replacement. Fix the match. -- Never depend on argument names or object-key order. Use `arguments[i]` — minifiers rename params and reorder destructured keys. +- Never depend on argument names or object-key order. Use `arguments[i]` - minifiers rename params and reorder destructured keys. - Prefer multiple small patches over one with broad find and many replacements. - In DEV, failing replacements auto-diff 200 chars around the match site. Read it before retrying. - Never reference build flags literally inside `replace`. They only exist in Equicord's bundle. Interpolate outside: @@ -199,10 +199,10 @@ replace: "$self.exampleWrap({ children: $& })"; - Top level: lazy finders only. `findByPropsLazy`, `findByCodeLazy`, `findComponentByCodeLazy`, `findStoreLazy`, `findCssClassesLazy`, `getUserSettingLazy`, `proxyLazyWebpack`. - Direct `find(...)` only inside `start()` or runtime callbacks. -- Components: `findComponentByCodeLazy` (top level) or `findComponentByCode` (runtime). Never `findByProps*` for React components — `displayName` is mangled, prop shapes shift. `findByPropsLazy` stays correct for stores, utility modules, action-creator objects. `waitForComponent` is `@webpack/common` internal. +- Components: `findComponentByCodeLazy` (top level) or `findComponentByCode` (runtime). Never `findByProps*` for React components - `displayName` is mangled, prop shapes shift. `findByPropsLazy` stays correct for stores, utility modules, action-creator objects. `waitForComponent` is `@webpack/common` internal. - `proxyLazy` for same-tick destructuring. `proxyLazyWebpack(() => ...)` when the value depends on webpack. `makeLazy` for plain deferred values. - `mapMangledModuleLazy(code, mapping)` to extract multiple exports from one mangled module. `extractAndLoadChunksLazy([codes], matcher?)` to force-load a lazy chunk before a `find*`. -- Before `findStoreLazy("X")`, check `src/webpack/common/stores.ts` — many are already exported. +- Before `findStoreLazy("X")`, check `src/webpack/common/stores.ts` - many are already exported. - `@webpack/common` exports backed by `waitFor` (stores, `FluxDispatcher`, `Parser`, `Alerts`, hooks) are `undefined` until webpack ready. Reference inside functions, not at module top. - No `eagerPatches`, no `wreq(id)` brute forcing. @@ -228,7 +228,7 @@ replace: "$self.exampleWrap({ children: $& })"; - Static stylesheet: `import "./style.css"`. Runtime-toggleable: `import name from "./style.css?managed"` plus `enableStyle`, `disableStyle`, `toggleStyle`, `setStyleClassNames` from `@api/Styles`. - Managed CSS variable selectors use `[--varName]`. Runtime rewrites these via `setStyleClassNames` at enable/recompile time (NOT build time). Call `setStyleClassNames(style, classNames)` before `enableStyle(style)`. - Top-level selectors start with `.vc--`. Descendant element selectors like `.vc-foo button` allowed. -- No `:root` in plugin CSS — use a `.vc--root` wrapper or `documentElement.style.setProperty`. +- No `:root` in plugin CSS - use a `.vc--root` wrapper or `documentElement.style.setProperty`. - No `@import`. - Prefer Discord CSS vars like `var(--background-primary)` over literal colors. - Inline `style={{}}` only for dynamic per-render values. Use `Margins.top8` etc. for spacing, not inline `style`. @@ -238,7 +238,7 @@ replace: "$self.exampleWrap({ children: $& })"; - Desktop-only: folder suffix `.desktop`. Mixed-target with `native.ts` doesn't use the suffix. - `native.ts` next to `index.tsx`, OR `native/index.ts` for multi-file natives. Exports auto-register as IPC handlers via `~pluginNatives`. -- Handler first arg is `IpcMainInvokeEvent`. All other args are renderer-controlled and untrusted — validate type, length, content. Never throw raw `Error` (leaks main-process paths) — return `{ success: false, error: "..." }` or scrubbed message. +- Handler first arg is `IpcMainInvokeEvent`. All other args are renderer-controlled and untrusted - validate type, length, content. Never throw raw `Error` (leaks main-process paths) - return `{ success: false, error: "..." }` or scrubbed message. - Filesystem paths: `normalize` and assert `startsWith()`. Never `rm`/`readFile`/`writeFile` a renderer-supplied path without this guard. - Network: URL allowlist (regex or `url.origin`), streaming size cap, redirect-depth cap. - Subprocess: `spawn` with argv arrays. Never `exec` a renderer-derived string. Never `shell: true` with untrusted input. @@ -320,7 +320,7 @@ Pick one per event. Never two for the same thing. | --------------------------------------- | ---------------------------------------------------------------------------------- | | Transient feedback (<2s) | `showToast(msg, Toasts.Type.SUCCESS)` from `@webpack/common` | | Background happened, user may act later | `showNotification({ title, body })` from `@api/Notifications` | -| Urgent inline top-bar | `Notices.showNotice(msg, btnText, cb)` from `@api/Notices` (sparingly — blocks UI) | +| Urgent inline top-bar | `Notices.showNotice(msg, btnText, cb)` from `@api/Notices` (sparingly - blocks UI) | | Modal confirm | `Alerts.show({ title, body, onConfirm })` from `@webpack/common` | ## Use what exists diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 614c512c4..c00bd9f76 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,7 +50,7 @@ To keep Equicord stable, secure and maintainable, all plugins must follow these 1. No simple slash-command plugins (e.g. `/cat`). If applicable, create a [user-installable Discord app](https://discord.com/developers/docs/change-log#userinstallable-apps-preview) instead. 2. No simple text replacement plugins (the built-in TextReplace plugin already covers this). -3. No raw DOM manipulation — always use proper patches and React. +3. No raw DOM manipulation - always use proper patches and React. 4. No FakeDeafen or FakeMute functionality. 5. No StereoMic-related plugins. 6. No plugins that only hide or redesign UI elements (use CSS for that). This rule may be negotiable. diff --git a/src/equicordplugins/vcNarratorCustom/index.tsx b/src/equicordplugins/vcNarratorCustom/index.tsx index d7ececf6c..0d96cac38 100644 --- a/src/equicordplugins/vcNarratorCustom/index.tsx +++ b/src/equicordplugins/vcNarratorCustom/index.tsx @@ -1235,7 +1235,7 @@ export default definePlugin({ Note from example-git - Old TikTok-TTS API died, so I set up a new cloudflare worker. It's rate-limited and stricter than the old one by design — please don't abuse it so it can stay available for plugins like this. + Old TikTok-TTS API died, so I set up a new cloudflare worker. It's rate-limited and stricter than the old one by design - please don't abuse it so it can stay available for plugins like this. diff --git a/src/plugins/memberCount/index.tsx b/src/plugins/memberCount/index.tsx index 7f94cece4..2c7f6688b 100644 --- a/src/plugins/memberCount/index.tsx +++ b/src/plugins/memberCount/index.tsx @@ -61,7 +61,7 @@ export const cl = classNameFactory("vc-membercount-"); export default definePlugin({ name: "MemberCount", - description: "Shows the number of online members, total members, and users in voice channels on the server — in the member list and tooltip.", + description: "Shows the number of online members, total members, and users in voice channels on the server - in the member list and tooltip.", tags: ["Servers", "Utility"], authors: [Devs.Ven, Devs.Commandtechno, Devs.Apexo], settings, diff --git a/src/plugins/translate/settings.tsx b/src/plugins/translate/settings.tsx index 5c65c8d02..07ac42371 100644 --- a/src/plugins/translate/settings.tsx +++ b/src/plugins/translate/settings.tsx @@ -53,9 +53,9 @@ export const settings = definePluginSettings({ hidden: IS_WEB, options: [ { label: "Google Translate", value: "google", default: true }, - { label: "DeepL Free — API key required", value: "deepl" }, - { label: "DeepL Pro — API key required", value: "deepl-pro" }, - { label: "Kagi Translate — API key required", value: "kagi" } + { label: "DeepL Free - API key required", value: "deepl" }, + { label: "DeepL Pro - API key required", value: "deepl-pro" }, + { label: "Kagi Translate - API key required", value: "kagi" } ] as const, onChange: resetLanguageDefaults },