From bf799f79b6bd94dcd2c2520663fd4d4d53426d6e Mon Sep 17 00:00:00 2001 From: Jeongmin <89498338+seomin0610@users.noreply.github.com> Date: Sun, 22 Feb 2026 00:45:39 +0900 Subject: [PATCH 1/7] Translate: add Korean to DeepL language list (#4002) --- src/plugins/translate/languages.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/translate/languages.ts b/src/plugins/translate/languages.ts index 75b7f3ae3..1023983f8 100644 --- a/src/plugins/translate/languages.ts +++ b/src/plugins/translate/languages.ts @@ -225,6 +225,7 @@ export const DeeplLanguages = { "it": "Italian", "ja": "Japanese", "jv": "Javanese", + "ko": "Korean", "pam": "Kapampangan", "kk": "Kazakh", "kmr": "Kurdish (Kurmanji)", From 710c3916971d845edb9a7f2683a7df7421d7fe22 Mon Sep 17 00:00:00 2001 From: sadan4 <117494111+sadan4@users.noreply.github.com> Date: Tue, 24 Feb 2026 18:41:37 -0500 Subject: [PATCH 2/7] fix VolumeBooster & UserVoiceShow (#4003) --- src/plugins/userVoiceShow/index.tsx | 4 ++-- src/plugins/volumeBooster/index.ts | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/plugins/userVoiceShow/index.tsx b/src/plugins/userVoiceShow/index.tsx index 039982dd7..5a9a85add 100644 --- a/src/plugins/userVoiceShow/index.tsx +++ b/src/plugins/userVoiceShow/index.tsx @@ -59,8 +59,8 @@ export default definePlugin({ { find: "#{intl::USER_PROFILE_PRONOUNS}", replacement: { - match: /(\i).isVerifiedBot\(\)}\),/, - replace: "$&$self.VoiceChannelIndicator({userId:$1.id,isProfile:true})," + match: /(?<=children:\[\i," ",\i)(?=\])/, + replace: ",$self.VoiceChannelIndicator({userId:arguments[0]?.user?.id,isProfile:true})" }, predicate: () => settings.store.showInUserProfileModal }, diff --git a/src/plugins/volumeBooster/index.ts b/src/plugins/volumeBooster/index.ts index 81dcf6633..4ab0c332a 100644 --- a/src/plugins/volumeBooster/index.ts +++ b/src/plugins/volumeBooster/index.ts @@ -55,16 +55,21 @@ export default definePlugin({ patches: [ // Change the max volume for sliders to allow for values above 200 - ...[ - "#{intl::USER_VOLUME}", - "currentVolume:" - ].map(find => ({ - find, + { + find: "#{intl::USER_VOLUME}", replacement: { - match: /(?<=maxValue:)\i\.\i\?(\d+?):(\d+?)(?=,)/, - replace: (_, higherMaxVolume, minorMaxVolume) => `${higherMaxVolume}*$self.settings.store.multiplier` + match: /(?<=maxValue:)\i\.isPlatformEmbedded\?(\i\.\i):\i\.\i(?=,)/, + replace: (_, higherMaxVolume) => `${higherMaxVolume}*$self.settings.store.multiplier` } - })), + }, + // Change the max volume for sliders to allow for values above 200 + { + find: "currentVolume:", + replacement: { + match: /(?<=maxValue:)\i\.\i\?(\d+?):\d+?(?=,)/, + replace: (_, higherMaxVolume) => `${higherMaxVolume}*$self.settings.store.multiplier` + } + }, // Patches needed for web/vesktop { find: "streamSourceNode", From 0e7757666de22dd48d8b5fca3c127f2a13da0e98 Mon Sep 17 00:00:00 2001 From: KITFC Date: Thu, 26 Feb 2026 02:07:09 +0000 Subject: [PATCH 3/7] BetterSettings: fix "Disable Fade" feature (#4007) Closes #3970 Co-authored-by: V --- src/plugins/betterSettings/index.tsx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index 60398339b..697633392 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -126,6 +126,28 @@ export default definePlugin({ ], predicate: () => settings.store.disableFade }, + { // Disable fade animations for settings menu + find: "layer-modal", + replacement: [ + { + match: /(\i)\.animated\.div(?=,\{"data-mana-component":"layer-modal")/, + replace: '"div"' + }, + { + match: /(?<="data-mana-component":"layer-modal"[^}]*?)style:\i,/, + replace: "style:{}," + } + ], + predicate: () => settings.store.disableFade + }, + { // Disable initial and exit delay for settings menu + find: "headerId:void 0,headerIdIsManaged:!1", + replacement: { + match: /let (\i)=300/, + replace: "let $1=0" + }, + predicate: () => settings.store.disableFade + }, { // Load menu TOC eagerly find: "handleOpenSettingsContextMenu=", replacement: { @@ -134,8 +156,7 @@ export default definePlugin({ }, predicate: () => settings.store.eagerLoad }, - { - // Settings cog context menu + { // Settings cog context menu find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}", replacement: [ { From a6b624a77d900b28da7e2969632acbe0abe8f996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marina=20=F0=9F=A7=8A?= Date: Wed, 25 Feb 2026 20:20:05 -0700 Subject: [PATCH 4/7] not quite spring cleaning Co-Authored-By: Marina Co-Authored-By: prism Co-Authored-By: nin0 --- src/plugins/accountPanelServerProfile/index.tsx | 2 +- src/plugins/decor/index.tsx | 2 +- src/plugins/streamerModeOnStream/index.ts | 2 +- src/plugins/voiceDownload/index.tsx | 2 +- src/utils/constants.ts | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/accountPanelServerProfile/index.tsx b/src/plugins/accountPanelServerProfile/index.tsx index 48a402c62..f735ccbf7 100644 --- a/src/plugins/accountPanelServerProfile/index.tsx +++ b/src/plugins/accountPanelServerProfile/index.tsx @@ -79,7 +79,7 @@ export default definePlugin({ replace: "$&$self.onPopoutClose();" }, { - match: /ref:(\i),style:\i(?=.{0,250}#{intl::5fWB8U::raw})/, + match: /ref:(\i),style:\i(?=.{0,250}#{intl::USER_PROFILE_ACCOUNT_POPOUT_BUTTON_A11Y_LABEL})/, replace: "$&,onContextMenu:($self.grabRef($1),$self.openAccountPanelContextMenu)" } ] diff --git a/src/plugins/decor/index.tsx b/src/plugins/decor/index.tsx index fe3a5f2eb..de751a2f0 100644 --- a/src/plugins/decor/index.tsx +++ b/src/plugins/decor/index.tsx @@ -99,7 +99,7 @@ export default definePlugin({ ...[ '"Message Username"', // Messages "#{intl::COLLECTIBLES_NAMEPLATE_PREVIEW_A11Y}", // Nameplate preview - "#{intl::ayozFl::raw}", // Avatar preview + "#{intl::COLLECTIBLES_PROFILE_PREVIEW_A11Y}", // Avatar preview ].map(find => ({ find, replacement: { diff --git a/src/plugins/streamerModeOnStream/index.ts b/src/plugins/streamerModeOnStream/index.ts index 03b83f577..b92fb16b6 100644 --- a/src/plugins/streamerModeOnStream/index.ts +++ b/src/plugins/streamerModeOnStream/index.ts @@ -37,7 +37,7 @@ function toggleStreamerMode({ streamKey }: StreamEvent, value: boolean) { export default definePlugin({ name: "StreamerModeOnStream", description: "Automatically enables streamer mode when you start streaming in Discord", - authors: [Devs.Kodarru], + authors: [Devs.IcedMarina], flux: { STREAM_CREATE: d => toggleStreamerMode(d, true), STREAM_DELETE: d => toggleStreamerMode(d, false) diff --git a/src/plugins/voiceDownload/index.tsx b/src/plugins/voiceDownload/index.tsx index 19d0883f5..eac912e47 100644 --- a/src/plugins/voiceDownload/index.tsx +++ b/src/plugins/voiceDownload/index.tsx @@ -15,7 +15,7 @@ export default definePlugin({ authors: [Devs.puv], patches: [ { - find: "#{intl::LgCPMt::raw}", + find: "#{intl::VOICE_MESSAGES_PLAYBACK_RATE_LABEL}", replacement: { match: /(?<=onVolumeHide:\i\}\))/, replace: ",$self.renderDownload(arguments[0].src)" diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c5e34618c..c3b784716 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -447,7 +447,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({ }, nin0dev: { name: "nin0dev", - id: 886685857560539176n + id: 1395533040914141235n }, Elvyra: { name: "Elvyra", @@ -477,9 +477,9 @@ export const Devs = /* #__PURE__*/ Object.freeze({ name: "puv", id: 469441552251355137n }, - Kodarru: { - name: "Kodarru", - id: 785227396218748949n + IcedMarina: { + name: "icedmarina", + id: 594406131670188042n }, nakoyasha: { name: "nakoyasha", From 12da7a08fbbfe118ffdb293488745cc991c1c8a6 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Thu, 26 Feb 2026 04:29:47 +0100 Subject: [PATCH 5/7] bump to 1.14.3 --- package.json | 2 +- src/plugins/betterSettings/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1b3d7b5c6..252d66068 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.14.2", + "version": "1.14.3", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index 697633392..ab9fac425 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -127,7 +127,7 @@ export default definePlugin({ predicate: () => settings.store.disableFade }, { // Disable fade animations for settings menu - find: "layer-modal", + find: '"data-mana-component":"layer-modal"', replacement: [ { match: /(\i)\.animated\.div(?=,\{"data-mana-component":"layer-modal")/, From bf500c6993a59e64c5a45d2bef292d449bea16ed Mon Sep 17 00:00:00 2001 From: oma <57739965+Eazvy@users.noreply.github.com> Date: Thu, 26 Feb 2026 10:39:36 -0500 Subject: [PATCH 6/7] VoiceButtons change position of buttons (#838) * VoiceButtons: add button position setting * VoiceButtons: fix select setting defaults * Update settings.ts * bleh * Update settings.ts --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com> --- browser/VencordNativeStub.ts | 1 - src/VencordNative.ts | 1 - src/equicordplugins/voiceButtons/index.tsx | 6 +++++- src/equicordplugins/voiceButtons/settings.ts | 21 ++++++++++---------- src/equicordplugins/voiceButtons/styles.css | 11 +++++++++- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/browser/VencordNativeStub.ts b/browser/VencordNativeStub.ts index 139bcd972..46cba9d0c 100644 --- a/browser/VencordNativeStub.ts +++ b/browser/VencordNativeStub.ts @@ -139,6 +139,5 @@ window.VencordNative = { setUpdateState: NOOP, onCheckUpdates: NOOP, onRepair: NOOP, - onAbout: NOOP, }, }; diff --git a/src/VencordNative.ts b/src/VencordNative.ts index 7835e84c2..d13ce4dd7 100644 --- a/src/VencordNative.ts +++ b/src/VencordNative.ts @@ -102,7 +102,6 @@ export default { setUpdateState: (available: boolean) => ipcRenderer.send(IpcEvents.SET_TRAY_UPDATE_STATE, available), onCheckUpdates: (cb: () => void) => { ipcRenderer.on(IpcEvents.TRAY_CHECK_UPDATES, cb); }, onRepair: (cb: () => void) => { ipcRenderer.on(IpcEvents.TRAY_REPAIR, cb); }, - onAbout: (cb: () => void) => { ipcRenderer.on(IpcEvents.TRAY_ABOUT, cb); }, }, pluginHelpers: PluginHelpers diff --git a/src/equicordplugins/voiceButtons/index.tsx b/src/equicordplugins/voiceButtons/index.tsx index 91360e72f..a8b18c885 100644 --- a/src/equicordplugins/voiceButtons/index.tsx +++ b/src/equicordplugins/voiceButtons/index.tsx @@ -31,8 +31,12 @@ export default definePlugin({ ], renderButtons(user: User) { if (!user) return null; + const positionClass = settings.store.buttonPosition === "right" + ? "voice-user-buttons-right" + : "voice-user-buttons-left"; + return ( - + {settings.store.showChatButton && } {settings.store.showMuteButton && } {settings.store.showDeafenButton && } diff --git a/src/equicordplugins/voiceButtons/settings.ts b/src/equicordplugins/voiceButtons/settings.ts index fb0d4a435..e12cfe7cb 100644 --- a/src/equicordplugins/voiceButtons/settings.ts +++ b/src/equicordplugins/voiceButtons/settings.ts @@ -30,46 +30,47 @@ export const settings = definePluginSettings({ type: OptionType.BOOLEAN, default: true, description: "Toggles their soundboard upon clicking deafen button.", - restartNeeded: false, }, disableVideo: { type: OptionType.BOOLEAN, default: true, description: "Toggles their video upon clicking deafen button.", - restartNeeded: false, }, useServer: { type: OptionType.BOOLEAN, description: "Use server mute/deafen instead of local when you have permission.", default: false, - restartNeeded: false, }, serverSelf: { type: OptionType.BOOLEAN, description: "Deafen / Mute yourself on the server when using mute/deafen.", default: false, - restartNeeded: false, }, showButtonsSelf: { type: OptionType.SELECT, - default: "display", description: "Whether you want to display buttons for your own user. Same functionality as other button(s) except it'll open DMs panel and mute/deafen for yourself upon clicking button(s).", restartNeeded: true, options: [ - { label: "Display", value: "display" }, + { label: "Display", value: "display", default: true }, { label: "Hide", value: "hide" }, { label: "Disable", value: "disable" }, ], }, whichNameToShow: { type: OptionType.SELECT, - default: "both", description: "Choose whether to show nickname or username in tooltip.", - restartNeeded: false, options: [ + { label: "Both", value: "both", default: true }, { label: "Global Name", value: "global" }, - { label: "Default Username", value: "username" }, - { label: "Both", value: "both" }, + { label: "Username", value: "username" }, + ], + }, + buttonPosition: { + type: OptionType.SELECT, + description: "Choose where to place voice buttons in the voice user row.", + options: [ + { label: "Left", value: "left", default: true }, + { label: "Right", value: "right" }, ], } }, { diff --git a/src/equicordplugins/voiceButtons/styles.css b/src/equicordplugins/voiceButtons/styles.css index f6edc1113..56e1da52e 100644 --- a/src/equicordplugins/voiceButtons/styles.css +++ b/src/equicordplugins/voiceButtons/styles.css @@ -2,10 +2,19 @@ flex: none !important; } +.voice-user-buttons-left { + order: -1; +} + +.voice-user-buttons-right { + order: 1; + margin-left: 4px; +} + .voice-user-button-container { padding-right: 4px; } div[class*='list'][class*='collapsed'] .voice-user-buttons { display: none; -} \ No newline at end of file +} From 84378cbb8291550c17dbb932d40e5de991140e09 Mon Sep 17 00:00:00 2001 From: tralwdwd <79791517+tralwdwd@users.noreply.github.com> Date: Thu, 26 Feb 2026 15:56:35 +0000 Subject: [PATCH 7/7] fix(Quoter): errors when quoting users with no profile picture (#837) * fix(Quoter): errors when quoting users with no profile picture * apply an actual fix --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com> --- .gemini/styleguide.md | 3 ++- .rules | 5 +++-- src/equicordplugins/profileSets/utils/profile.ts | 2 +- src/equicordplugins/quoter/index.tsx | 6 +++--- src/equicordplugins/quoter/utils.tsx | 6 ------ 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index baa617b84..51258faee 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -51,6 +51,7 @@ export default definePlugin({ options: { myOption: { /* ... */ } } }); ``` **Prefer declarative APIs** over manual registration: + - `flux: { EVENT_NAME(data) {} }` not manual FluxDispatcher subscribe - `contextMenus: { "nav-id": fn }` not manual addContextMenuPatch - `chatBarButton: { render, icon }` not addChatBarButton @@ -81,7 +82,6 @@ Flag these and suggest the fix: | `cdn.discordapp.com/icons/...` | `IconUtils.getGuildIconURL(...)` | Same | | `cdn.discordapp.com/banners/...` | `IconUtils.getUserBannerURL(...)` | Same | | `cdn.discordapp.com/emojis/...` | `IconUtils.getEmojiURL(...)` | Same | -| `/assets/*.png` default avatars | `IconUtils.getDefaultAvatarURL(id)` | Same | | `/api/v9/...` or `/users/@me` | `Constants.Endpoints.*` or `RestAPI` | Endpoints change | | `@api/Styles` for classNameFactory | `@utils/css` | `@api/Styles` is deprecated | | `any` for Discord objects | Import from `@vencord/discord-types` | Type safety | @@ -361,6 +361,7 @@ If a PR reimplements any of these, flag it. They already exist: **@api/Commands:** `sendBotMessage`, `findOption` **@webpack/common:** + - Stores: `UserStore`, `GuildStore`, `ChannelStore`, `GuildMemberStore`, `SelectedChannelStore`, `SelectedGuildStore`, `PresenceStore`, `RelationshipStore`, `MessageStore`, `EmojiStore`, `ThemeStore`, `PermissionStore`, `VoiceStateStore`, 30+ more - Actions: `RestAPI`, `FluxDispatcher`, `MessageActions`, `NavigationRouter`, `ChannelRouter`, `ChannelActionCreators`, `SettingsRouter` - Utils: `Constants` (`.Endpoints`), `SnowflakeUtils`, `Parser`, `PermissionsBits`, `moment`, `lodash`, `IconUtils`, `ColorUtils`, `ImageUtils`, `DateUtils`, `UsernameUtils`, `DisplayProfileUtils` diff --git a/.rules b/.rules index 1a0363222..061408c20 100644 --- a/.rules +++ b/.rules @@ -102,6 +102,7 @@ ### Patch Examples **Clean replacement:** + ```js find: "#{intl::PIN_MESSAGE}),icon:" match: /#{intl::PIN_MESSAGE}\)/ @@ -109,6 +110,7 @@ replace: "$self.getPinLabel(arguments[0]))" ``` **Appending:** + ```js find: "#{intl::VIEW_AS_ROLES_MENTIONS_WARNING}" match: /#{intl::VIEW_AS_ROLES_MENTIONS_WARNING}.{0,100}(?=])/ @@ -116,6 +118,7 @@ replace: "$&,$self.renderTooltip(arguments[0].guild)" ``` **Wrapping:** + ```js find: "#{intl::THREE_USERS_TYPING}" match: /(?<="aria-atomic":!0,children:)\i/ @@ -168,7 +171,6 @@ Use `definePluginSettings` from `@api/Settings`, not inline settings object. From `@webpack/common`. **NEVER** hardcode `cdn.discordapp.com` URLs. - `IconUtils.getUserAvatarURL(user, canAnimate?, size?)` -- `IconUtils.getDefaultAvatarURL(id)` - `IconUtils.getUserBannerURL({ id, banner, canAnimate?, size })` - `IconUtils.getGuildIconURL({ id, icon, size?, canAnimate? })` - `IconUtils.getGuildBannerURL(guild, canAnimate?)` @@ -208,4 +210,3 @@ From `@webpack/common`. **NEVER** hardcode `cdn.discordapp.com` URLs. - `"/api/v9"`, `"/users/@me"` ⟹ `Constants.Endpoints` or `RestAPI` - `console.log/warn/error` ⟹ `Logger` from `@utils/Logger` - `` `${a} ${b}` `` for class names ⟹ `classes(a, b)` from `@utils/misc` -- `"/assets/*.png"` for default avatars ⟹ `IconUtils.getDefaultAvatarURL(id)` diff --git a/src/equicordplugins/profileSets/utils/profile.ts b/src/equicordplugins/profileSets/utils/profile.ts index 5b7a7bbc7..148081443 100644 --- a/src/equicordplugins/profileSets/utils/profile.ts +++ b/src/equicordplugins/profileSets/utils/profile.ts @@ -281,7 +281,7 @@ function resolvePendingAvatar(pendingChanges: PendingChanges | null): ImageInput function normalizeImageValue(value: unknown): string | null { if (typeof value === "string") return value; if (value && typeof value === "object" && "imageUri" in value) { - const { imageUri } = value as { imageUri: unknown }; + const { imageUri } = value as { imageUri: unknown; }; return typeof imageUri === "string" ? imageUri : null; } return null; diff --git a/src/equicordplugins/quoter/index.tsx b/src/equicordplugins/quoter/index.tsx index f8389de73..95825e3c1 100644 --- a/src/equicordplugins/quoter/index.tsx +++ b/src/equicordplugins/quoter/index.tsx @@ -12,11 +12,11 @@ import { getCurrentChannel } from "@utils/discord"; import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import definePlugin, { OptionType } from "@utils/types"; import { Message } from "@vencord/discord-types"; -import { Button, Menu, TextInput, UploadHandler, useEffect, useState } from "@webpack/common"; +import { Button, IconUtils, Menu, TextInput, UploadHandler, useEffect, useState } from "@webpack/common"; import { QuoteIcon } from "./components/QuoteIcon"; import { QuoteFont } from "./types"; -import { createQuoteImage, ensureFontLoaded, generateFileNamePreview, getFileExtension, getMimeType, resetFontLoading, sizeUpgrade } from "./utils"; +import { createQuoteImage, ensureFontLoaded, generateFileNamePreview, getFileExtension, getMimeType, resetFontLoading } from "./utils"; const settings = definePluginSettings({ quoteFont: { @@ -105,7 +105,7 @@ function QuoteModal({ message, ...props }: ModalProps & { message: Message; }) { const generateImage = async () => { const image = await createQuoteImage({ - avatarUrl: sizeUpgrade(message.author.getAvatarURL()), + avatarUrl: IconUtils.getUserAvatarURL(message.author, true, 512), quote: message.content, grayScale: gray, author: message.author, diff --git a/src/equicordplugins/quoter/utils.tsx b/src/equicordplugins/quoter/utils.tsx index d963967ff..8ff9ae5bf 100644 --- a/src/equicordplugins/quoter/utils.tsx +++ b/src/equicordplugins/quoter/utils.tsx @@ -21,12 +21,6 @@ interface CustomEmojiToken { animated: boolean; } -export function sizeUpgrade(url: string): string { - const u = new URL(url); - u.searchParams.set("size", "512"); - return u.toString(); -} - export function canvasToBlob(canvas: HTMLCanvasElement): Promise { return new Promise((resolve, reject) => { canvas.toBlob(blob => {