Merge branch 'dev' into tray-stuff

This commit is contained in:
thororen1234 2026-02-26 11:38:03 -05:00
commit 3f0263575c
No known key found for this signature in database
17 changed files with 81 additions and 44 deletions

View file

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

5
.rules
View file

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

View file

@ -1,7 +1,7 @@
{
"name": "equicord",
"private": "true",
"version": "1.14.2.1",
"version": "1.14.3.0",
"description": "The other cutest Discord client mod",
"homepage": "https://github.com/Equicord/Equicord#readme",
"bugs": {

View file

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

View file

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

View file

@ -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<Blob> {
return new Promise<Blob>((resolve, reject) => {
canvas.toBlob(blob => {

View file

@ -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 (
<Flex flexDirection="row" className="voice-user-buttons">
<Flex flexDirection="row" className={`voice-user-buttons ${positionClass}`}>
{settings.store.showChatButton && <UserChatButton user={user} />}
{settings.store.showMuteButton && <UserMuteButton user={user} />}
{settings.store.showDeafenButton && <UserDeafenButton user={user} />}

View file

@ -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" },
],
}
}, {

View file

@ -2,6 +2,15 @@
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;
}

View file

@ -87,7 +87,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)"
}
]

View file

@ -137,6 +137,28 @@ export default definePlugin({
],
predicate: () => settings.store.disableFade
},
{ // Disable fade animations for settings menu
find: '"data-mana-component":"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: {
@ -145,8 +167,7 @@ export default definePlugin({
},
predicate: () => settings.store.eagerLoad
},
{
// Settings cog context menu
{ // Settings cog context menu
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
replacement: [
{

View file

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

View file

@ -37,7 +37,7 @@ function toggleStreamerMode({ streamKey }: StreamEvent, value: boolean) {
export default definePlugin({
name: "StreamerModeOn",
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)

View file

@ -225,6 +225,7 @@ export const DeeplLanguages = {
"it": "Italian",
"ja": "Japanese",
"jv": "Javanese",
"ko": "Korean",
"pam": "Kapampangan",
"kk": "Kazakh",
"kmr": "Kurdish (Kurmanji)",

View file

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

View file

@ -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\?(\i\.\i|\d+?):(\i\.\i|\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",

View file

@ -466,7 +466,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
},
nin0dev: {
name: "nin0dev",
id: 886685857560539176n
id: 1395533040914141235n
},
Elvyra: {
name: "Elvyra",
@ -496,9 +496,9 @@ export const Devs = /* #__PURE__*/ Object.freeze({
name: "puv",
id: 469441552251355137n
},
Kodarru: {
name: "Kodarru",
id: 785227396218748949n
IcedMarina: {
name: "icedmarina",
id: 594406131670188042n
},
nakoyasha: {
name: "nakoyasha",