Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
thororen1234 2026-04-16 10:02:08 -04:00
commit 899a24db2c
No known key found for this signature in database
181 changed files with 1489 additions and 882 deletions

View file

@ -1,7 +1,7 @@
{
"name": "equicord",
"private": "true",
"version": "1.14.6.2",
"version": "1.14.7.0",
"description": "The other cutest Discord client mod",
"homepage": "https://github.com/Equicord/Equicord#readme",
"bugs": {
@ -54,47 +54,46 @@
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
"idb": "8.0.3",
"jsqr": "1.4.0",
"monaco-editor": "^0.54.0",
"monaco-editor": "^0.55.1",
"nanoid": "^5.1.6",
"native-file-system-adapter": "^3.0.1",
"usercss-meta": "^0.12.0",
"virtual-merge": "^1.0.1"
},
"devDependencies": {
"@electron/asar": "^4.0.1",
"@stylistic/eslint-plugin": "^5.6.0",
"@types/adm-zip": "^0.5.7",
"@types/chrome": "^0.1.30",
"@types/diff": "^7.0.2",
"@types/lodash": "^4.17.20",
"@types/node": "^24.10.1",
"@electron/asar": "^4.2.0",
"@stylistic/eslint-plugin": "^5.10.0",
"@types/chrome": "^0.1.40",
"@types/lodash": "^4.17.24",
"@types/node": "^25.6.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@types/yazl": "^3.3.0",
"@types/yazl": "^3.3.1",
"@vencord/discord-types": "link:packages/discord-types",
"diff": "^8.0.2",
"esbuild": "^0.27.0",
"eslint": "9.39.1",
"diff": "^9.0.0",
"esbuild": "^0.28.0",
"eslint": "10.2.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-simple-header": "^1.2.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unused-imports": "^4.3.0",
"eslint-plugin-simple-import-sort": "^13.0.0",
"eslint-plugin-unused-imports": "^4.4.1",
"highlight.js": "11.11.1",
"html-minifier-terser": "^7.2.0",
"moment": "^2.22.2",
"p-limit": "^7.3.0",
"puppeteer-core": "^24.30.0",
"standalone-electron-types": "^34.2.0",
"stylelint": "^16.25.0",
"stylelint-config-standard": "^39.0.1",
"puppeteer-core": "^24.41.0",
"standalone-electron-types": "^41.2.1",
"stylelint": "^17.8.0",
"stylelint-config-standard": "^40.0.0",
"svgo": "^4.0.1",
"ts-patch": "^3.3.0",
"ts-pattern": "^5.6.0",
"tsx": "^4.20.6",
"type-fest": "^5.2.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.47.0",
"typescript-transform-paths": "^3.5.5",
"ts-pattern": "^5.9.0",
"tsx": "^4.21.0",
"type-fest": "^5.5.0",
"typescript": "^6.0.2",
"typescript-eslint": "^8.58.2",
"typescript-transform-paths": "^3.5.6",
"zip-local": "^0.3.5"
},
"packageManager": "pnpm@10.33.0",
@ -125,4 +124,4 @@
"engines": {
"node": ">=18"
}
}
}

1848
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,7 @@ import { addMessagePopoverButton, removeMessagePopoverButton } from "@api/Messag
import { addNicknameIcon, removeNicknameIcon } from "@api/NicknameIcons";
import { Settings, SettingsStore } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { traceFunction } from "@debug/Tracer";
import { Logger } from "@utils/Logger";
import { onlyOnce } from "@utils/onlyOnce";
import { canonicalizeFind, canonicalizeReplacement } from "@utils/patches";
@ -39,7 +40,6 @@ import { patches } from "@webpack/patcher";
import Plugins from "~plugins";
export { Plugins as plugins };
import { traceFunction } from "../debug/Tracer";
import { addAudioProcessor, removeAudioProcessor } from "./AudioPlayer";
import { addChannelToolbarButton, addHeaderBarButton, removeChannelToolbarButton, removeHeaderBarButton } from "./HeaderBar";
import { addProfileCollection, removeProfileCollection } from "./ProfileCollections";

View file

@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { React, TextInput } from "@webpack/common";
import { React, TextInput, useState } from "@webpack/common";
interface TextInputProps {
/**
* WARNING: Changing this between renders will have no effect!
*/
value: string;
initialValue: string;
/**
* This will only be called if the new value passed validate()
*/
@ -41,13 +41,15 @@ interface TextInputProps {
* A very simple wrapper around Discord's TextInput that validates input and shows
* the user an error message and only calls your onChange when the input is valid
*/
export function CheckedTextInput({ value: initialValue, onChange, validate, placeholder }: TextInputProps) {
const [value, setValue] = React.useState(initialValue);
const [error, setError] = React.useState<string>();
export function CheckedTextInput({ initialValue, onChange, validate, placeholder }: TextInputProps) {
const [value, setValue] = useState(initialValue);
const [error, setError] = useState<string>();
function handleChange(v: string) {
setValue(v);
const res = validate(v);
if (res === true) {
setError(void 0);
onChange(v);

View file

@ -6,13 +6,13 @@
import { showNotice } from "@api/Notices";
import { isPluginEnabled, pluginRequiresRestart, startDependenciesRecursive, startPlugin, stopPlugin } from "@api/PluginManager";
import { Settings } from "@api/Settings";
import { CogWheel, InfoIcon } from "@components/Icons";
import { AddonCard } from "@components/settings/AddonCard";
import { classNameFactory } from "@utils/css";
import { Logger } from "@utils/Logger";
import { OptionType, Plugin } from "@utils/types";
import { React, showToast, Toasts } from "@webpack/common";
import { Settings } from "Vencord";
import { PluginMeta } from "~plugins";

View file

@ -60,5 +60,25 @@
}
.vc-plugin-modal-info {
display: flex;
gap: 1em;
justify-content: space-between;
align-items: start;
}
.vc-plugin-modal-tags {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-block: 8px 16px;
}
.vc-plugin-modal-tag {
align-items: center;
}
border: 1px solid var(--border-normal);
border-radius: 9999px;
display: flex;
justify-content: center;
padding: 6px 12px;
color: var(--text-default);
}

View file

@ -32,7 +32,7 @@ import { proxyLazy } from "@utils/lazy";
import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc";
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { OptionType, Plugin } from "@utils/types";
import { OptionType, Plugin, PluginTag } from "@utils/types";
import { User } from "@vencord/discord-types";
import { findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { Clickable, FluxDispatcher, React, Toasts, Tooltip, useEffect, useMemo, UserStore, UserSummaryItem, UserUtils, useState } from "@webpack/common";
@ -74,6 +74,16 @@ export function makeDummyUser(user: { username: string; id?: string; avatar?: st
return newUser;
}
function PluginTags({ tags }: { tags: PluginTag[]; }) {
return (
<div className={cl("tags")}>
{tags.map(tag => (
<div key={tag} className={cl("tag")}>{tag}</div>
))}
</div>
);
}
export default function PluginModal({ plugin, onRestartNeeded, onClose, transitionState }: PluginModalProps) {
const pluginSettings = useSettings([`plugins.${plugin.name}.*`]).plugins[plugin.name];
const hasSettings = Boolean(pluginSettings && plugin.options && !isObjectEmpty(plugin.options));
@ -167,6 +177,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
<div className={cl("header-content")}>
<BaseText size="lg" weight="semibold" className={cl("title")}>{plugin.name}</BaseText>
<BaseText size="sm" className={cl("description")}>{plugin.description}</BaseText>
{!!plugin.tags?.length && <PluginTags tags={plugin.tags} />}
{!!plugin.settingsAboutComponent && (
<div className={Margins.top8}>
<ErrorBoundary message="An error occurred while rendering this plugin's custom Info Component">

View file

@ -35,8 +35,9 @@ import { isTruthy } from "@utils/guards";
import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import { useAwaiter, useIntersection } from "@utils/react";
import { Alerts, lodash, Parser, React, Select, TextInput, Toasts, Tooltip, useCallback, useMemo, useState } from "@webpack/common";
import { useAwaiter, useCleanupEffect, useIntersection } from "@utils/react";
import { PluginTag, PluginTags } from "@utils/types";
import { Alerts, lodash, Parser, React, SearchableSelect, Select, TextInput, Toasts, Tooltip, useCallback, useMemo, useRef, useState } from "@webpack/common";
import { JSX } from "react";
import Plugins, { ExcludedPlugins, PluginMeta } from "~plugins";
@ -143,7 +144,8 @@ function ExcludedPluginsList({ search }: { search: string; }) {
export default function PluginSettings() {
const settings = useSettings();
const changes = React.useMemo(() => new ChangeList<string>(), []);
const changeRef = useRef<ChangeList<string>>(null);
const changes = changeRef.current ??= new ChangeList<string>();
React.useEffect(() => {
return () => {
@ -194,7 +196,7 @@ export default function PluginSettings() {
const hasUserPlugins = useMemo(() => !IS_STANDALONE && Object.values(PluginMeta).some(m => m.userPlugin), []);
const [searchValue, setSearchValue] = useState({ value: "", status: SearchStatus.ALL });
const [searchValue, setSearchValue] = useState({ value: "", tags: [] as PluginTag[], status: SearchStatus.ALL });
const [searchInput, setSearchInput] = useState("");
const debouncedSetSearch = useMemo(
@ -207,12 +209,9 @@ export default function PluginSettings() {
setSearchInput(query);
debouncedSetSearch(query);
}, [debouncedSetSearch]);
const onStatusChange = useCallback((status: SearchStatus) => {
setSearchValue(prev => ({ ...prev, status }));
}, []);
const pluginFilter = useCallback((plugin: typeof Plugins[keyof typeof Plugins], newPluginsSet: Set<string> | null) => {
const { status } = searchValue;
const { status, tags } = searchValue;
const enabled = isPluginEnabled(plugin.name);
switch (status) {
@ -239,12 +238,14 @@ export default function PluginSettings() {
break;
}
if (tags.length && tags.some(t => !plugin.tags?.includes(t))) return false;
if (!search.length) return true;
return (
plugin.name.toLowerCase().includes(search.replace(/\s+/g, "")) ||
plugin.description.toLowerCase().includes(search) ||
plugin.tags?.some(t => t.toLowerCase().includes(search))
plugin.searchTerms?.some(t => t.toLowerCase().includes(search))
);
}, [searchValue, search]);
@ -404,33 +405,47 @@ export default function PluginSettings() {
<HeadingTertiary className={classes(Margins.top20, Margins.bottom8)}>
Filters
</HeadingTertiary>
</HeadingTertiary>;
<div className={classes(Margins.bottom20, cl("filter-controls"))}>
<ErrorBoundary noop>
<TextInput autoFocus value={searchInput} placeholder="Search for a plugin..." onChange={onSearch} />
</ErrorBoundary>
<div>
<ErrorBoundary noop>
<Select
options={[
{ label: "Show All", value: SearchStatus.ALL, default: true },
{ label: "Show Enabled", value: SearchStatus.ENABLED },
{ label: "Show Disabled", value: SearchStatus.DISABLED },
{ label: "Show Equicord", value: SearchStatus.EQUICORD },
{ label: "Show Vencord", value: SearchStatus.VENCORD },
{ label: "Show New", value: SearchStatus.NEW },
hasUserPlugins && { label: "Show UserPlugins", value: SearchStatus.USER_PLUGINS },
{ label: "Show API Plugins", value: SearchStatus.API_PLUGINS },
].filter(isTruthy)}
serialize={String}
select={onStatusChange}
isSelected={v => v === searchValue.status}
closeOnSelect={true}
/>
</ErrorBoundary>
<ErrorBoundary noop>
<TextInput
inputClassName={cl("filter-control")}
placeholder="Search for a plugin..."
value={searchValue.value}
onChange={onSearch}
autoFocus
/>
</ErrorBoundary>
<ErrorBoundary noop>
<div className={classes(Margins.bottom20, Margins.top8, cl("filter-controls"))}>
<Select
options={[
{ label: "Show All", value: SearchStatus.ALL, default: true },
{ label: "Show Enabled", value: SearchStatus.ENABLED },
{ label: "Show Disabled", value: SearchStatus.DISABLED },
{ label: "Show Equicord", value: SearchStatus.EQUICORD },
{ label: "Show Vencord", value: SearchStatus.VENCORD },
{ label: "Show New", value: SearchStatus.NEW },
hasUserPlugins && { label: "Show UserPlugins", value: SearchStatus.USER_PLUGINS },
{ label: "Show API Plugins", value: SearchStatus.API_PLUGINS },
].filter(isTruthy)}
serialize={String}
select={status => setSearchValue(prev => ({ ...prev, status }))}
isSelected={v => v === searchValue.status}
closeOnSelect={true}
placeholder="Filter by Type"
/>
<SearchableSelect
options={PluginTags.map(tag => ({ label: tag, value: tag }))}
value={searchValue.tags}
onChange={tags => setSearchValue(prev => ({ ...prev, tags }))}
closeOnSelect={false}
placeholder="Filter by Tags"
multi
/>
</div>
</div>
</ErrorBoundary>
<HeadingTertiary className={Margins.top20}>Plugins</HeadingTertiary>
@ -456,6 +471,7 @@ export default function PluginSettings() {
<HeadingTertiary className={classes(Margins.top20, Margins.bottom8)}>
Required Plugins
</HeadingTertiary>
<div className={cl("grid")}>
{requiredPlugins.length
? requiredPlugins

View file

@ -45,7 +45,12 @@
display: grid;
height: 40px;
gap: 10px;
grid-template-columns: 1fr 150px;
grid-template-columns: 1fr 1fr;
align-items: center;
}
.vc-plugins-filter-control {
height: 40px;
}
.vc-plugins-dep-name {

View file

@ -137,7 +137,7 @@ function CloudTab() {
<div style={{ flex: 1 }}>
<CheckedTextInput
key={`backendUrl-${inputKey}`}
value={cloud.url}
initialValue={cloud.url}
onChange={async v => {
cloud.url = v;
cloud.authenticated = false;

View file

@ -9,8 +9,8 @@ import { canonicalizeMatch } from "@utils/patches";
import { ModuleFactory } from "@vencord/discord-types/webpack";
import * as Webpack from "@webpack";
import { wreq } from "@webpack";
import { AnyModuleFactory } from "@webpack/types";
import pLimit from "p-limit";
import { AnyModuleFactory } from "webpack";
function getWebpackChunkMap() {
const sym = Symbol();

View file

@ -34,7 +34,8 @@ export default definePlugin({
description: "Music Controls and Lyrics for multiple services ",
authors: [Devs.Ven, Devs.afn, Devs.KraXen72, Devs.Av32000, Devs.nin0dev, Devs.thororen, EquicordDevs.vmohammad, Devs.Joona],
settings,
tags: [
tags: ["Media", "Activity"],
searchTerms: [
// Spotify
"Spotify",
"SpotifyControls",

View file

@ -70,6 +70,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "AccountPanelServerProfile",
description: "Right click your account panel in the bottom left to view your profile in the current server",
tags: ["Appearance", "Servers"],
authors: [Devs.Nuckyz, Devs.relitrix],
settings,

View file

@ -51,6 +51,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "AlwaysAnimate",
description: "Animates anything that can be animated",
tags: ["Appearance", "Fun"],
authors: [Devs.FieryFlames],
settings,
patches: [

View file

@ -33,6 +33,7 @@ migratePluginSettings("AlwaysExpandRoles", "ShowAllRoles");
export default definePlugin({
name: "AlwaysExpandRoles",
description: "Always expands the role list in profile popouts",
tags: ["Appearance", "Roles"],
authors: [Devs.surgedevs],
isModified: true,
settings,

View file

@ -60,6 +60,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "AlwaysTrust",
description: "Removes the annoying untrusted domain and suspicious file popup",
tags: ["Utility"],
authors: [Devs.zt, Devs.Trwy],
isModified: true,
settings,

View file

@ -75,6 +75,7 @@ export default definePlugin({
name: "AnonymiseFileNames",
authors: [Devs.fawn],
description: "Anonymise uploaded file names",
tags: ["Privacy", "Utility"],
isModified: true,
settings,

View file

@ -157,6 +157,7 @@ function getImageAsset(type: AssetImageType, data: TrackData) {
export default definePlugin({
name: "AppleMusicRichPresence",
description: "Discord rich presence for your Apple Music!",
tags: ["Activity", "Media"],
authors: [Devs.RyanCaoDev],
hidden: !IS_MAC,
reporterTestable: ReporterTestable.None,

View file

@ -42,6 +42,7 @@ migratePluginSettings("WebRichPresence", "WebRichPresence (arRPC)");
export default definePlugin({
name: "WebRichPresence",
description: "Client plugin for arRPC to enable RPC on Discord Web (experimental)",
tags: ["Activity", "Utility"],
authors: [Devs.Ducko],
reporterTestable: ReporterTestable.None,
hidden: !IS_EQUIBOP && !IS_VESKTOP && !("legcord" in window),

View file

@ -48,6 +48,7 @@ migratePluginSettings("AutoDNDWhilePlaying", "StatusWhilePlaying");
export default definePlugin({
name: "AutoDNDWhilePlaying",
description: "Automatically updates your online status (online, idle, dnd) when launching games",
tags: ["Activity", "Utility"],
authors: [Devs.thororen],
isModified: true,
settings,

View file

@ -254,9 +254,9 @@ const GRID_STYLE_NAME = "vc-betterFolders-sidebar-grid";
export default definePlugin({
name: "BetterFolders",
description: "Shows server folders on dedicated sidebar and adds folder related improvements",
tags: ["Organisation", "Servers", "Appearance"],
authors: [Devs.juby, Devs.AutumnVN, Devs.Nuckyz],
isModified: true,
settings,
start() {
settings.store.nestedFolders = getNestedFolderMap();

View file

@ -24,6 +24,7 @@ export default definePlugin({
authors: [Devs.Ven],
description:
"Change GIF alt text from simply being 'GIF' to containing the gif tags / filename",
tags: ["Media", "Accessibility", "Customisation"],
patches: [
{
find: ".modalContext})};",

View file

@ -20,6 +20,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "BetterGifPicker",
description: "Makes the gif picker open the favourite category by default",
tags: ["Emotes", "Customisation"],
authors: [Devs.Samwich, EquicordDevs.justjxke],
isModified: true,
settings,

View file

@ -40,6 +40,7 @@ export default definePlugin({
name: "BetterNotesBox",
description: "Hide notes or disable spellcheck (Configure in settings!!)",
authors: [Devs.Ven],
tags: ["Customisation", "Utility"],
settings,
patches: [

View file

@ -90,6 +90,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "BetterRoleContext",
description: "Adds options to copy role color / edit role / view role icon when right clicking roles in the user profile",
tags: ["Roles", "Appearance"],
authors: [Devs.Ven, Devs.goodbee],
dependencies: ["UserSettingsAPI"],

View file

@ -40,6 +40,7 @@ export default definePlugin({
name: "BetterRoleDot",
authors: [Devs.Ven, Devs.AutumnVN],
description: "Copy role colour on RoleDot (accessibility setting) click. Also allows using both RoleDot and coloured names simultaneously",
tags: ["Roles", "Appearance"],
settings,
patches: [

View file

@ -56,7 +56,7 @@ export default definePlugin({
name: "BetterSessions",
description: "Enhances the sessions (devices) menu. Allows you to view exact timestamps, give each session a custom name, and receive notifications about new sessions.",
authors: [Devs.amia],
tags: ["Notifications", "Customisation", "Utility"],
settings: settings,
patches: [

View file

@ -7,13 +7,11 @@
.vc-betterSessions-rename-btn {
margin-left: 4px;
translate: 0 -2px;
width: fit-content;
}
.vc-betterSessions-new-btn {
margin-left: 4px;
translate: 0 -2px;
width: fit-content;
pointer-events: none;
padding: 1px 4px;
}

View file

@ -78,6 +78,7 @@ export default definePlugin({
name: "BetterSettings",
description: "Enhances your settings-menu-opening experience",
authors: [Devs.Kyuuhachi],
tags: ["Appearance", "Customisation", "Organisation"],
settings,
start() {

View file

@ -23,6 +23,7 @@ export default definePlugin({
name: "BetterUploadButton",
authors: [Devs.fawn, Devs.Ven],
description: "Upload with a single click, open menu with right click",
tags: ["Utility", "Shortcuts"],
patches: [
{
find: ".CHAT_INPUT_BUTTON_NOTIFICATION,",

View file

@ -89,6 +89,7 @@ export const userContextPatch: NavContextMenuPatchCallback = (children, { user }
export default definePlugin({
name: "BiggerStreamPreview",
description: "This plugin allows you to enlarge stream previews",
tags: ["Media", "Appearance"],
authors: [Devs.phil],
contextMenus: {
"user-context": userContextPatch,

View file

@ -43,6 +43,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "BlurNSFW",
description: "Blur attachments in NSFW channels until hovered",
tags: ["Privacy", "Appearance"],
authors: [Devs.Ven],
isModified: true,
settings,

View file

@ -111,6 +111,7 @@ migrateSettingsFromPlugin("CallTimer", "AllCallTimers", "showWithoutHover", "sho
export default definePlugin({
name: "CallTimer",
description: "Add call timers for all users in voice channels and in the connection status.",
tags: ["Voice", "Utility"],
authors: [Devs.Ven, EquicordDevs.MaxHerbold, Devs.D3SOX],
managedStyle: alignedChatInputFix,
settings,

View file

@ -35,6 +35,7 @@ export default definePlugin({
name: "CharacterCounter",
description: "Adds a character counter to the chat input",
authors: [Devs.thororen],
tags: ["Utility"],
settings,
patches: [
{

View file

@ -50,6 +50,7 @@ interface RuleSet {
export default definePlugin({
name: "ClearURLs",
description: "Automatically removes tracking elements from URLs you send",
tags: ["Privacy", "Utility"],
authors: [Devs.adryd, Devs.thororen],
rules: [] as RuleSet[],

View file

@ -29,6 +29,7 @@ export default definePlugin({
name: "ClientTheme",
authors: [Devs.Nuckyz],
description: "Recreation of the old client theme experiment. Add a color to your Discord client theme",
tags: ["Appearance", "Customisation"],
settings,
startAt: StartAt.DOMContentLoaded,

View file

@ -23,6 +23,7 @@ export default definePlugin({
name: "ColorSighted",
description: "Removes the colorblind-friendly icons from statuses, just like 2015-2017 Discord",
authors: [Devs.lewisakura],
tags: ["Appearance", "Accessibility"],
patches: [
{
find: "Masks.STATUS_ONLINE",

View file

@ -109,6 +109,7 @@ export default definePlugin({
name: "ConsoleJanitor",
description: "Disables annoying console messages/errors",
authors: [Devs.Nuckyz, Devs.sadan],
tags: ["Developers", "Console", "Utility"],
settings,
startAt: StartAt.Init,

View file

@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { loadLazyChunks } from "@debug/loadLazyChunks";
import { Devs } from "@utils/constants";
import { getCurrentChannel, getCurrentGuild } from "@utils/discord";
import { runtimeHashMessageKey } from "@utils/intlHash";
@ -28,7 +29,6 @@ import definePlugin, { PluginNative, StartAt } from "@utils/types";
import * as Webpack from "@webpack";
import { extract, filters, findAll, findModuleId, search } from "@webpack";
import * as Common from "@webpack/common";
import { loadLazyChunks } from "debug/loadLazyChunks";
import type { ComponentType } from "react";
const DESKTOP_ONLY = (f: string) => () => {
@ -245,6 +245,7 @@ export default definePlugin({
name: "ConsoleShortcuts",
description: "Adds shorter Aliases for many things on the window. Run `shortcutList` for a list.",
authors: [Devs.Ven],
tags: ["Developers", "Console", "Shortcuts", "Utility"],
startAt: StartAt.Init,
patches: [

View file

@ -51,6 +51,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "CopyEmojiMarkdown",
description: "Allows you to copy emojis as formatted string (<:blobcatcozy:1026533070955872337>)",
tags: ["Emotes", "Utility"],
authors: [Devs.HappyEnderman, Devs.Vishnya],
settings,

View file

@ -22,6 +22,7 @@ const CheckMarkIcon = () => {
export default definePlugin({
name: "CopyFileContents",
description: "Adds a button to text file attachments to copy their contents",
tags: ["Utility"],
authors: [Devs.Obsidian, Devs.Nuckyz],
patches: [
{

View file

@ -87,6 +87,7 @@ const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { t
export default definePlugin({
name: "CopyStickerLinks",
description: "Adds the ability to copy & open Sticker links",
tags: ["Emotes", "Utility"],
authors: [Devs.Ven, Devs.Byeoon],
contextMenus: {
"message": messageContextMenuPatch,

View file

@ -47,6 +47,7 @@ export default definePlugin({
name: "CopyUserURLs",
authors: [Devs.castdrian],
description: "Adds a 'Copy User URL' option to the user context menu.",
tags: ["Utility", "Friends"],
contextMenus: {
"user-context": UserContextMenuPatch
}

View file

@ -61,8 +61,8 @@ export default definePlugin({
name: "CrashHandler",
description: "Utility plugin for handling and possibly recovering from crashes without a restart",
authors: [Devs.Nuckyz],
tags: ["Utility", "Developers"],
enabledByDefault: true,
settings,
patches: [

View file

@ -12,6 +12,7 @@ export default definePlugin({
name: "CtrlEnterSend",
authors: [Devs.UlyssesZhan],
description: "Use Ctrl+Enter to send messages (customizable)",
tags: ["Shortcuts", "Chat"],
settings: definePluginSettings({
submitRule: {
description: "The way to send a message",

View file

@ -90,8 +90,9 @@ migratePluginSettings("CustomCommands", "MessageTags");
export default definePlugin({
name: "CustomCommands",
description: "Allows you to create custom slash commands / tags",
tags: ["MessageTags"],
searchTerms: ["MessageTags"],
authors: [Devs.Ven, Devs.Luna,],
tags: ["Commands", "Customisation", "Utility"],
settings,
async start() {

View file

@ -29,6 +29,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "CustomIdle",
description: "Allows you to set the time before Discord goes idle (or disable auto-idle)",
tags: ["Activity", "Customisation"],
authors: [Devs.newwares],
settings,
patches: [

View file

@ -215,6 +215,7 @@ export async function setRpc(disable?: boolean) {
export default definePlugin({
name: "CustomRPC",
description: "Add a fully customisable Rich Presence (Game status) to your Discord profile",
tags: ["Activity", "Customisation"],
authors: [Devs.captain, Devs.AutumnVN, Devs.nin0dev],
dependencies: ["UserSettingsAPI"],
// This plugin's patch is not important for functionality, so don't require a restart

View file

@ -170,6 +170,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "Dearrow",
description: "Makes YouTube embed titles and thumbnails less sensationalist, powered by Dearrow",
tags: ["Media", "Utility"],
authors: [Devs.Ven],
settings,

View file

@ -27,6 +27,7 @@ export interface AvatarDecoration {
export default definePlugin({
name: "Decor",
description: "Create and use your own custom avatar decorations, or pick your favorite from the presets.",
tags: ["Appearance", "Customisation"],
authors: [Devs.FieryFlames],
patches: [
// Patch MediaResolver to return correct URL for Decor avatar decorations

View file

@ -48,6 +48,7 @@ export const settings = definePluginSettings({
export default definePlugin({
name: "DevCompanion",
description: "Dev Companion Plugin. Please report anything not working or being weird (most likely its a bug) to sadan, either ping or dm, thanks!",
tags: ["Developers", "Utility"],
authors: [Devs.Ven, Devs.sadan],
reporterTestable: ReporterTestable.None,
isModified: true,

View file

@ -22,6 +22,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "DisableCallIdle",
description: "Disables automatically getting kicked from a DM voice call after 3 minutes and being moved to an AFK voice channel.",
tags: ["Voice", "Utility"],
authors: [Devs.Nuckyz],
patches: [
{

View file

@ -24,6 +24,7 @@ export default definePlugin({
name: "DontRoundMyTimestamps",
authors: [Devs.Lexi],
description: "Always rounds relative timestamps down, so 7.6y becomes 7y instead of 8y",
tags: ["Appearance", "Utility"],
start() {
moment.relativeTimeRounding(Math.floor);

View file

@ -37,6 +37,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "Experiments",
description: "Enable Access to Experiments & other dev-only features in Discord!",
tags: ["Developers", "Utility"],
authors: [
Devs.Megu,
Devs.Ven,
@ -70,6 +71,8 @@ export default definePlugin({
match: /(?<=children:\[)(?=null!=.{0,150}"Installation ID:)/,
replace: "$self.WarningCard(),"
},
// for some reason the installation id and copy buttons are on
// different lines so it looks stupid when the card above is added
{
match: /(?<=,marginBottom:16)(?=\},children:\[)/,
replace: ',flexDirection:"row",alignItems:"center"'

View file

@ -232,7 +232,7 @@ function CloneModal({ data }: { data: Sticker | Emoji; }) {
<>
<Heading className={Margins.top20}>Custom Name</Heading>
<CheckedTextInput
value={name}
initialValue={name}
onChange={v => {
data.name = v;
setName(v);
@ -411,7 +411,8 @@ migratePluginSettings("ExpressionCloner", "EmoteCloner");
export default definePlugin({
name: "ExpressionCloner",
description: "Allows you to clone Emotes & Stickers to your own server (right click them)",
tags: ["StickerCloner", "EmoteCloner", "EmojiCloner"],
tags: ["Emotes", "Servers"],
searchTerms: ["StickerCloner", "EmoteCloner", "EmojiCloner"],
authors: [Devs.Ven, Devs.Nuckyz],
contextMenus: {
"message": messageContextMenuPatch,

View file

@ -22,6 +22,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "F8Break",
description: "Pause the client when you press F8 with DevTools (+ breakpoints) open.",
tags: ["Developers", "Shortcuts"],
authors: [Devs.lewisakura],
start() {

View file

@ -180,6 +180,7 @@ export default definePlugin({
name: "FakeNitro",
authors: [Devs.Arjix, Devs.D3SOX, Devs.Ven, Devs.fawn, Devs.captain, Devs.Nuckyz, Devs.AutumnVN, Devs.sadan],
description: "Allows you to send fake emojis/stickers, use nitro themes, and stream in nitro quality",
tags: ["Emotes", "Appearance", "Customisation", "Chat"],
dependencies: ["MessageEventsAPI"],
settings,

View file

@ -200,6 +200,7 @@ function SettingsAboutComponent() {
export default definePlugin({
name: "FakeProfileThemes",
description: "Allows profile theming by hiding the colors in your bio thanks to invisible 3y3 encoding",
tags: ["Appearance", "Customisation"],
authors: [Devs.Alyxia, Devs.Remty],
patches: [
{

View file

@ -84,6 +84,7 @@ export default definePlugin({
name: "FavoriteGifSearch",
authors: [Devs.Aria],
description: "Adds a search bar to favorite gifs.",
tags: ["Media", "Customisation"],
patches: [
{

View file

@ -10,6 +10,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "FixCodeblockGap",
description: "Removes the gap between codeblocks and text below it",
tags: ["Appearance"],
authors: [Devs.Grzesiek11],
patches: [
{

View file

@ -24,6 +24,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "FixImagesQuality",
description: "Improves quality of images by loading them at their original resolution",
tags: ["Media", "Appearance"],
authors: [Devs.Nuckyz, Devs.Ven],
settings,

View file

@ -23,5 +23,6 @@ export default definePlugin({
name: "FixSpotifyEmbeds",
description: "Fixes spotify embeds being incredibly loud by letting you customise the volume",
authors: [Devs.Ven],
tags: ["Media", "Customisation"],
settings,
});

View file

@ -25,6 +25,7 @@ export default definePlugin({
name: "ForceOwnerCrown",
description: "Force the owner crown next to usernames even if the server is large.",
authors: [Devs.D3SOX, Devs.Nickyux],
tags: ["Roles", "Appearance", "Servers"],
patches: [
{
find: "#{intl::GUILD_OWNER}),children:",

View file

@ -26,6 +26,7 @@ const FriendInvites = findByPropsLazy("createFriendInvite");
export default definePlugin({
name: "FriendInvites",
description: "Create and manage friend invite links via slash commands (/create friend invite, /view friend invites, /revoke friend invites).",
tags: ["Friends", "Commands"],
authors: [Devs.afn, Devs.Dziurwa],
commands: [
{

View file

@ -23,6 +23,7 @@ const Section = findComponentByCodeLazy("headingVariant:", '"section"', "heading
export default definePlugin({
name: "FriendsSince",
description: "Shows when you became friends with someone in the user popout",
tags: ["Friends"],
authors: [Devs.Elvyra, Devs.Antti],
patches: [
// DM User Sidebar

View file

@ -81,6 +81,7 @@ migratePluginSettings("FullSearchContext", "SearchReply");
export default definePlugin({
name: "FullSearchContext",
description: "Makes the message context menu in message search results have all options you'd expect",
tags: ["Utility"],
authors: [Devs.Ven, Devs.Aria],
patches: [{

View file

@ -23,6 +23,7 @@ interface UserMentionComponentProps {
export default definePlugin({
name: "FullUserInChatbox",
description: "Makes the user mention in the chatbox have more functionalities, like left/right clicking",
tags: ["Shortcuts", "Utility"],
authors: [Devs.sadan],
patches: [

View file

@ -98,6 +98,7 @@ function GameActivityToggleButton({ iconForeground, hideTooltips, nameplate }: U
export default definePlugin({
name: "GameActivityToggle",
description: "Adds a button next to the mic and deafen button to toggle game activity.",
tags: ["Activity", "Shortcuts"],
authors: [Devs.Nuckyz, Devs.RuukuLada],
dependencies: ["UserSettingsAPI"],
settings,

View file

@ -26,6 +26,7 @@ import { ExpressionPickerStore } from "@webpack/common";
export default definePlugin({
name: "GifPaste",
description: "Makes picking a gif in the gif picker insert a link into the chatbox instead of instantly sending it",
tags: ["Media", "Chat"],
authors: [Devs.Ven],
patches: [{

View file

@ -152,6 +152,7 @@ function GreetMenu({ channel, message }: { message: Message, channel: Channel; }
export default definePlugin({
name: "GreetStickerPicker",
description: "Allows you to use any greet sticker instead of only the random one by right-clicking the 'Wave to say hi!' button",
tags: ["Emotes", "Customisation"],
authors: [Devs.Ven],
settings,

View file

@ -56,6 +56,7 @@ async function toggleHide(channelId: string, messageId: string) {
export default definePlugin({
name: "HideMedia",
description: "Hide attachments and embeds for individual messages via hover button",
tags: ["Chat", "Appearance"],
authors: [Devs.Ven],
dependencies: ["MessageUpdaterAPI"],

View file

@ -24,6 +24,7 @@ migratePluginSettings("IloveSpam", "iLoveSpam");
export default definePlugin({
name: "ILoveSpam",
description: "Do not hide messages from 'likely spammers'",
tags: ["Utility", "Chat"],
authors: [Devs.botato, Devs.Nyako],
patches: [
{

View file

@ -232,6 +232,7 @@ export default definePlugin({
name: "IgnoreActivities",
authors: [Devs.Nuckyz, Devs.Kylie],
description: "Ignore activities from showing up on your status ONLY. You can configure which ones are specifically ignored from the Registered Games and Activities tabs, or use the general settings below",
tags: ["Activity", "Privacy", "Customisation"],
dependencies: ["UserSettingsAPI"],
settings,

View file

@ -23,6 +23,7 @@ export default definePlugin({
name: "ImageFilename",
authors: [Devs.Ven],
description: "Display the file name of images & GIFs as a tooltip when hovering over them",
tags: ["Media", "Utility"],
settings,
patches: [

View file

@ -10,6 +10,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "ImageLink",
description: "Never hide image links in messages, even if it's the only content",
tags: ["Media", "Appearance"],
authors: [Devs.Kyuuhachi, Devs.Sqaaakoi],
patches: [

View file

@ -155,8 +155,9 @@ const imageContextMenuPatch: NavContextMenuPatchCallback = (children, props) =>
export default definePlugin({
name: "ImageZoom",
description: "Lets you zoom in to images and gifs. Use scroll wheel to zoom in and shift + scroll wheel to increase lens radius / size",
tags: ["Media", "Utility"],
authors: [Devs.Aria],
tags: ["ImageUtilities"],
searchTerms: ["ImageUtilities"],
managedStyle,

View file

@ -21,12 +21,25 @@ import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserAffinitiesStore, UserStore } from "@webpack/common";
import { Settings } from "Vencord";
const settings = definePluginSettings(
{
sortByAffinity: {
type: OptionType.BOOLEAN,
default: true,
description: "Whether to sort implicit relationships by their affinity to you.",
restartNeeded: true
},
}
);
export default definePlugin({
name: "ImplicitRelationships",
description: "Shows your implicit relationships in the Friends tab.",
tags: ["Friends", "Servers"],
authors: [Devs.Dolfies],
settings,
patches: [
// Counts header
{
@ -73,7 +86,7 @@ export default definePlugin({
{
find: "getRelationshipCounts(){",
replacement: {
predicate: () => Settings.plugins.ImplicitRelationships.sortByAffinity,
predicate: () => settings.store.sortByAffinity,
match: /\}\)\.sortBy\((.+?)\)\.value\(\)/,
replace: "}).sortBy(row => $self.wrapSort(($1), row)).value()"
}
@ -102,16 +115,6 @@ export default definePlugin({
},
}
],
settings: definePluginSettings(
{
sortByAffinity: {
type: OptionType.BOOLEAN,
default: true,
description: "Whether to sort implicit relationships by their affinity to you.",
restartNeeded: true
},
}
),
wrapSort(comparator: Function, row: any) {
return row.type === 5

View file

@ -60,6 +60,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "IrcColors",
description: "Makes username colors in chat unique, like in IRC clients",
tags: ["Appearance", "Customisation"],
authors: [Devs.Grzesiek11, Devs.jamesbt365],
settings,

View file

@ -43,6 +43,7 @@ let previousCache: PreviousChannel | undefined;
export default definePlugin({
name: "KeepCurrentChannel",
description: "Attempt to navigate to the channel you were in before switching accounts or loading Discord.",
tags: ["Utility", "Organisation"],
authors: [Devs.Nuckyz],
patches: [

View file

@ -186,6 +186,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "LastFMRichPresence",
description: "Little plugin for Last.fm rich presence",
tags: ["Activity", "Media"],
authors: [Devs.dzshn, Devs.RuiNtD, Devs.blahajZip, Devs.archeruwu],
settings,

View file

@ -57,6 +57,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "LoadingQuotes",
description: "Replace Discords loading quotes",
tags: ["Appearance", "Fun", "Customisation"],
authors: [Devs.Ven, Devs.KraXen72, Devs.UlyssesZhan],
settings,

View file

@ -62,6 +62,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.",
tags: ["Servers", "Utility"],
authors: [Devs.Ven, Devs.Commandtechno, Devs.Apexo],
settings,

View file

@ -48,6 +48,7 @@ function DefaultRoleIcon() {
export default definePlugin({
name: "MentionAvatars",
description: "Shows user avatars and role icons inside mentions",
tags: ["Appearance", "Customisation"],
authors: [Devs.Ven, Devs.SerStars],
patches: [{
// HEY THOR UPDATE SHOW ME YOUR NAME IF THIS SHIT CHANGES TY :)

View file

@ -577,6 +577,7 @@ async function executeAction(
export default definePlugin({
name: "MessageClickActions",
description: "Customize click actions on messages.",
tags: ["Chat", "Shortcuts"],
authors: [Devs.Ven, EquicordDevs.keircn, EquicordDevs.ZcraftElite, EquicordDevs.omaw],
isModified: true,

View file

@ -29,6 +29,7 @@ const DISCORD_KT_DELAY = 1471228928;
export default definePlugin({
name: "MessageLatency",
description: "Displays an indicator for messages that took ≥n seconds to send",
tags: ["Chat", "Utility"],
authors: [Devs.arHSM],
settings: definePluginSettings({

View file

@ -364,6 +364,7 @@ function AutomodEmbedAccessory(props: MessageEmbedProps): JSX.Element | null {
export default definePlugin({
name: "MessageLinkEmbeds",
description: "Adds a preview to messages that link another message",
tags: ["Chat", "Appearance"],
authors: [Devs.TheSun, Devs.Ven, Devs.RyanCaoDev],
dependencies: ["MessageAccessoriesAPI", "MessageUpdaterAPI", "UserSettingsAPI"],

View file

@ -417,6 +417,7 @@ export const settings = definePluginSettings({
export default definePlugin({
name: "MessageLogger",
description: "Temporarily logs deleted and edited messages.",
tags: ["Chat", "Utility"],
authors: [Devs.rushii, Devs.Ven, Devs.AutumnVN, Devs.Nickyux, Devs.Kyuuhachi, EquicordDevs.justjxke],
dependencies: ["MessageUpdaterAPI"],
isModified: true,

View file

@ -52,6 +52,7 @@ migratePluginSettings("MoreQuickReactions", "BetterQuickReact");
export default definePlugin({
name: "MoreQuickReactions",
description: "Improves the quick react buttons in the message context menu.",
tags: ["Emotes", "Reactions", "Customisation", "Shortcuts"],
authors: [Devs.Ven, Devs.Sqaaakoi, Devs.iamme],
isModified: true,
settings,

View file

@ -35,7 +35,7 @@ const UserUtils = findByPropsLazy("getGlobalName");
const ProfileListClasses = findCssClassesLazy("empty", "textContainer", "connectionIcon");
const TabBarClasses = findCssClassesLazy("tabPanelScroller", "tabBarPanel");
const MutualsListClasses = findCssClassesLazy("row", "icon", "name", "details");
const ExpandableList = findComponentByCodeLazy('action:"PRESS_SECTION"', "section");
const ExpandableList = findComponentByCodeLazy('action:"PRESS_SECTION"', '"section"');
function getGroupDMName(channel: Channel) {
return channel.name ||
@ -86,6 +86,7 @@ const IS_PATCHED = Symbol("MutualGroupDMs.Patched");
export default definePlugin({
name: "MutualGroupDMs",
description: "Shows mutual group dms in profiles",
tags: ["Friends", "Appearance"],
authors: [Devs.amia],
patches: [

View file

@ -151,7 +151,8 @@ function applyDefaultSettings(guildId: string | null) {
export default definePlugin({
name: "NewGuildSettings",
description: "Automatically mute new servers and change various other settings upon joining",
tags: ["MuteNewGuild", "mute", "server"],
tags: ["Servers", "Customisation"],
searchTerms: ["MuteNewGuild", "mute", "server"],
authors: [Devs.Glitch, Devs.Nuckyz, Devs.carince, Devs.Mopi, Devs.GabiRP],
isModified: true,
contextMenus: {

View file

@ -90,6 +90,7 @@ export default definePlugin({
name: "NoBlockedMessages",
description: "Hide all blocked/ignored messages from chat completely.",
authors: [Devs.rushii, Devs.Samu, Devs.jamesbt365, Devs.Elvyra, EquicordDevs.Etorix],
tags: ["Accessibility", "Chat"],
isModified: true,
settings,
patches: [

View file

@ -10,6 +10,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "DisableDeepLinks",
description: "Disables Discord's stupid deep linking feature which tries to force you to use their Desktop App",
tags: ["Utility"],
authors: [Devs.Ven],
required: true,

View file

@ -23,6 +23,7 @@ export default definePlugin({
name: "NoDevtoolsWarning",
description: "Disables the 'HOLD UP' banner in the console. As a side effect, also prevents Discord from hiding your token, which prevents random logouts.",
authors: [Devs.Ven],
tags: ["Developers", "Console"],
patches: [{
find: "setDevtoolsCallbacks",
replacement: {

View file

@ -22,6 +22,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "NoF1",
description: "Disables F1 help bind.",
tags: ["Utility"],
authors: [Devs.Cyn],
patches: [
{

View file

@ -11,6 +11,7 @@ export default definePlugin({
name: "NoMaskedUrlPaste",
authors: [Devs.CatNoir],
description: "Pasting a link while having text selected will not paste as masked URL",
tags: ["Chat", "Utility"],
patches: [
{
find: ".selection,preventEmojiSurrogates:",

View file

@ -21,7 +21,8 @@ export default definePlugin({
name: "NoMosaic",
authors: [Devs.AutumnVN],
description: "Removes Discord image mosaic",
tags: ["image", "mosaic", "media"],
tags: ["Media", "Appearance", "Chat"],
searchTerms: ["image", "mosaic", "media"],
settings,

View file

@ -22,6 +22,7 @@ import definePlugin from "@utils/types";
export default definePlugin({
name: "NoOnboardingDelay",
description: "Skips the slow and annoying onboarding delay",
tags: ["Utility", "Servers"],
authors: [Devs.nekohaxx],
patches: [
{

View file

@ -47,6 +47,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "NoPendingCount",
description: "Removes the ping count of incoming friend requests, message requests, and nitro offers.",
tags: ["Notifications", "Appearance"],
authors: [Devs.amia],
settings: settings,

View file

@ -23,6 +23,7 @@ import { UserStore } from "@webpack/common";
export default definePlugin({
name: "NoProfileThemes",
description: "Completely removes Nitro profile themes from everyone but yourself",
tags: ["Appearance"],
authors: [Devs.TheKodeToad],
patches: [
{

View file

@ -62,6 +62,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "NoReplyMention",
description: "Disables reply pings by default",
tags: ["Chat", "Notifications"],
authors: [Devs.DustyAngel47, Devs.rae, Devs.pylix, Devs.outfoxxed],
settings,

Some files were not shown because too many files have changed in this diff Show more