Feature Request: Fix Discord Links

This commit is contained in:
thororen1234 2026-06-27 11:05:54 -04:00
parent a6176945a5
commit 710a7538a3
No known key found for this signature in database
7 changed files with 30 additions and 30 deletions

View file

@ -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

View file

@ -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

14
.rules
View file

@ -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-<plugin>-`. Descendant element selectors like `.vc-foo button` allowed.
- No `:root` in plugin CSS — use a `.vc-<plugin>-root` wrapper or `documentElement.style.setProperty`.
- No `:root` in plugin CSS - use a `.vc-<plugin>-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(<allowed root>)`. 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

View file

@ -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.

View file

@ -1235,7 +1235,7 @@ export default definePlugin({
Note from example-git
</Forms.FormText>
<Forms.FormText className={cl("author-text")}>
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.
</Forms.FormText>
</div>
</div>

View file

@ -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,

View file

@ -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
},