├── .gitattributes ├── packages ├── discord-types │ ├── .npmignore │ ├── src │ │ ├── modules │ │ │ └── index.d.ts │ │ ├── common │ │ │ ├── messages │ │ │ │ ├── index.d.ts │ │ │ │ ├── Sticker.d.ts │ │ │ │ └── Emoji.d.ts │ │ │ ├── index.d.ts │ │ │ ├── Record.d.ts │ │ │ ├── Application.d.ts │ │ │ ├── GuildMember.d.ts │ │ │ ├── Role.d.ts │ │ │ └── Activity.d.ts │ │ ├── stores │ │ │ ├── WindowStore.d.ts │ │ │ ├── GuildStore.d.ts │ │ │ ├── TypingStore.d.ts │ │ │ ├── GuildRoleStore.d.ts │ │ │ ├── AuthenticationStore.d.ts │ │ │ ├── UserStore.d.ts │ │ │ ├── StreamerModeStore.d.ts │ │ │ ├── SelectedGuildStore.d.ts │ │ │ ├── StickersStore.d.ts │ │ │ ├── ThemeStore.d.ts │ │ │ ├── MessageStore.d.ts │ │ │ ├── SelectedChannelStore.d.ts │ │ │ ├── RelationshipStore.d.ts │ │ │ ├── ChannelStore.d.ts │ │ │ ├── GuildMemberStore.d.ts │ │ │ └── DraftStore.d.ts │ │ ├── index.d.ts │ │ ├── classes.d.ts │ │ └── flux.d.ts │ ├── enums │ │ ├── misc.ts │ │ ├── index.ts │ │ ├── channel.ts │ │ ├── activity.ts │ │ └── commands.ts │ ├── CONTRIBUTING.md │ └── package.json └── vencord-types │ ├── .npmignore │ ├── .gitignore │ ├── HOW2PUB.md │ ├── index.d.ts │ ├── README.md │ ├── package.json │ └── globals.d.ts ├── pnpm-workspace.yaml ├── .npmrc ├── browser ├── icon.png ├── content.js ├── Vencord.ts ├── monacoWin.html ├── modifyResponseHeaders.json ├── monaco.ts ├── background.js ├── userscript.meta.js └── manifestv2.json ├── src ├── components │ ├── iconStyles.css │ ├── Divider.css │ ├── settings │ │ ├── tabs │ │ │ ├── plugins │ │ │ │ ├── PluginModal.css │ │ │ │ ├── LinkIconButton.css │ │ │ │ ├── components │ │ │ │ │ ├── styles.css │ │ │ │ │ └── ComponentSetting.tsx │ │ │ │ └── ContributorModal.css │ │ │ ├── index.ts │ │ │ ├── vencord │ │ │ │ └── DonateButton.tsx │ │ │ └── themes │ │ │ │ └── styles.css │ │ ├── index.ts │ │ ├── QuickAction.css │ │ ├── PluginBadge.tsx │ │ └── QuickAction.tsx │ ├── BaseText.css │ ├── ErrorCard.css │ ├── Span.tsx │ ├── Paragraph.tsx │ ├── css.ts │ ├── FormSwitch.css │ ├── Divider.tsx │ ├── CodeBlock.tsx │ ├── Grid.tsx │ ├── index.ts │ ├── Heading.css │ ├── handleComponentFailed.ts │ ├── ErrorCard.tsx │ └── Switch.css ├── plugins │ ├── replyTimestamp │ │ ├── style.css │ │ └── README.md │ ├── fakeProfileThemes │ │ └── index.css │ ├── gameActivityToggle │ │ └── style.css │ ├── alwaysExpandRoles │ │ └── README.md │ ├── experiments │ │ └── hideBugReport.css │ ├── shikiCodeblocks.desktop │ │ ├── devicon.css │ │ ├── previewExample.tsx │ │ ├── utils │ │ │ ├── color.ts │ │ │ └── createStyle.ts │ │ └── hooks │ │ │ └── useCopyCooldown.ts │ ├── messageLogger │ │ ├── deleteStyleOverlay.css │ │ ├── deleteStyleText.css │ │ └── messageLogger.css │ ├── noMaskedUrlPaste │ │ ├── README.md │ │ └── index.ts │ ├── callTimer │ │ └── alignedChatInputFix.css │ ├── stickerPaste │ │ ├── README.md │ │ └── index.ts │ ├── mutualGroupDMs │ │ └── style.css │ ├── fixImagesQuality │ │ ├── README.md │ │ └── index.ts │ ├── imageLink │ │ ├── README.md │ │ └── index.ts │ ├── userMessagesPronouns │ │ └── README.md │ ├── showTimeoutDuration │ │ ├── styles.css │ │ └── README.md │ ├── favGifSearch │ │ └── README.md │ ├── quickMention │ │ └── README.md │ ├── copyFileContents │ │ ├── README.md │ │ └── style.css │ ├── notificationVolume │ │ ├── README.md │ │ └── index.ts │ ├── platformIndicators │ │ └── style.css │ ├── friendsSince │ │ └── README.md │ ├── copyStickerLinks │ │ └── README.MD │ ├── imageFilename │ │ └── README.md │ ├── openInApp │ │ ├── README.md │ │ └── native.ts │ ├── pictureInPicture │ │ └── styles.css │ ├── previewMessage │ │ └── README.md │ ├── replaceGoogleSearch │ │ └── README.md │ ├── quickReply │ │ └── README.md │ ├── typingTweaks │ │ └── style.css │ ├── fullSearchContext │ │ └── README.md │ ├── unlockedAvatarZoom │ │ ├── README.md │ │ └── index.ts │ ├── betterSessions │ │ ├── styles.css │ │ ├── README.md │ │ ├── components │ │ │ └── RenameButton.tsx │ │ └── types.ts │ ├── dearrow │ │ ├── README.md │ │ └── styles.css │ ├── pauseInvitesForever │ │ └── README.md │ ├── fixYoutubeEmbeds.desktop │ │ ├── README.md │ │ ├── index.ts │ │ └── native.ts │ ├── whoReacted │ │ └── README.md │ ├── autoDndWhilePlaying.discordDesktop │ │ └── README.md │ ├── hideAttachments │ │ └── styles.css │ ├── messageClickActions │ │ └── README.md │ ├── _api │ │ ├── badges │ │ │ └── fixDiscordBadgePadding.css │ │ ├── memberListDecorators │ │ │ └── style.css │ │ ├── messageDecorations │ │ │ └── style.css │ │ ├── chatButtons.ts │ │ ├── dynamicImageModalApi.ts │ │ └── messageAccessories.ts │ ├── betterRoleContext │ │ └── README.md │ ├── validReply │ │ └── README.md │ ├── customidle │ │ └── README.md │ ├── mentionAvatars │ │ ├── README.md │ │ └── styles.css │ ├── consoleJanitor │ │ └── README.md │ ├── showMeYourName │ │ └── styles.css │ ├── copyEmojiMarkdown │ │ └── README.md │ ├── voiceDownload │ │ └── style.css │ ├── readAllNotificationsButton │ │ └── style.css │ ├── onePingPerDM │ │ └── README.md │ ├── noUnblockToJump │ │ ├── README.md │ │ └── index.ts │ ├── accountPanelServerProfile │ │ └── README.md │ ├── youtubeAdblock.desktop │ │ ├── README.md │ │ ├── index.ts │ │ └── native.ts │ ├── fullUserInChatbox │ │ └── README.md │ ├── userVoiceShow │ │ ├── README.md │ │ └── style.css │ ├── betterSettings │ │ └── README.md │ ├── showConnections │ │ └── styles.css │ ├── clientTheme │ │ ├── README.md │ │ ├── clientTheme.css │ │ └── index.tsx │ ├── typingIndicator │ │ └── style.css │ ├── vencordToolbox │ │ └── index.css │ ├── betterFolders │ │ ├── README.md │ │ └── style.css │ ├── favEmojiFirst │ │ └── README.md │ ├── imageZoom │ │ ├── README.md │ │ ├── styles.css │ │ ├── constants.ts │ │ └── utils │ │ │ └── waitFor.ts │ ├── plainFolderIcon │ │ └── style.css │ ├── spotifyControls │ │ ├── hoverOnly.css │ │ └── SeekBar.ts │ ├── volumeBooster │ │ └── README.md │ ├── serverInfo │ │ ├── README.md │ │ └── index.tsx │ ├── sortFriendRequests │ │ └── styles.css │ ├── memberCount │ │ ├── CircleIcon.tsx │ │ └── style.css │ ├── xsOverlay │ │ ├── native.ts │ │ └── README.md │ ├── implicitRelationships │ │ └── README.md │ ├── permissionFreeWill │ │ └── README.md │ ├── superReactionTweaks │ │ └── README.md │ ├── clearURLs │ │ └── README.md │ ├── seeSummaries │ │ └── README.md │ ├── appleMusic.desktop │ │ └── README.md │ ├── consoleShortcuts │ │ └── native.ts │ ├── pinDms │ │ ├── constants.ts │ │ └── styles.css │ ├── decor │ │ ├── lib │ │ │ ├── utils │ │ │ │ └── decoration.ts │ │ │ └── constants.ts │ │ ├── ui │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ ├── Grid.tsx │ │ │ │ ├── DecorationGridCreate.tsx │ │ │ │ ├── DecorationGridNone.tsx │ │ │ │ ├── DecorDecorationGridDecoration.tsx │ │ │ │ └── index.ts │ │ └── README.md │ ├── noTypingAnimation │ │ └── index.ts │ ├── betterGifPicker │ │ └── index.ts │ ├── ignoreActivities │ │ └── README.md │ ├── noDeepLinks.web │ │ └── index.ts │ ├── showHiddenThings │ │ └── README.md │ ├── ircColors │ │ └── README.md │ ├── translate │ │ ├── styles.css │ │ └── native.ts │ ├── sendTimestamps │ │ └── styles.css │ ├── normalizeMessageLinks │ │ └── index.ts │ ├── voiceMessages │ │ ├── native.ts │ │ ├── utils.ts │ │ ├── styles.css │ │ └── settings.ts │ ├── fixSpotifyEmbeds.desktop │ │ └── index.ts │ ├── messageLatency │ │ └── README.md │ ├── themeAttributes │ │ └── README.md │ ├── biggerStreamPreview │ │ └── webpack │ │ │ └── stores.ts │ ├── webScreenShareFixes.web │ │ └── index.ts │ ├── noF1 │ │ └── index.ts │ ├── noOnboardingDelay │ │ └── index.ts │ ├── dontRoundMyTimestamps │ │ └── index.ts │ ├── secretRingTone │ │ └── index.ts │ ├── iLoveSpam │ │ └── index.ts │ ├── loadingQuotes │ │ └── quotes.txt │ └── noDevtoolsWarning │ │ └── index.ts ├── api │ ├── ChatButton.css │ ├── Commands │ │ └── types.ts │ ├── Notifications │ │ └── index.ts │ └── MessageUpdater.ts ├── utils │ ├── clipboard.ts │ ├── css.ts │ ├── web-metadata.ts │ ├── mergeDefaults.ts │ ├── localStorage.ts │ ├── margins.ts │ ├── native.ts │ ├── guards.ts │ ├── cspViolations.ts │ ├── lazyReact.tsx │ ├── onlyOnce.ts │ └── dependencies.ts ├── shared │ ├── vencordUserAgent.ts │ └── debounce.ts ├── nativeModules.d.ts ├── webpack │ ├── common │ │ ├── userSettings.ts │ │ ├── classes.ts │ │ └── index.ts │ ├── index.ts │ └── types.ts └── main │ └── updater │ └── index.ts ├── .github ├── ISSUE_TEMPLATE │ ├── developer-banner.png │ ├── config.yml │ └── blank.yml └── workflows │ ├── codeberg-mirror.yml │ └── test.yml ├── scripts ├── header-new.txt ├── header-old.txt ├── checkNodeVersion.js ├── build │ ├── module │ │ └── style.js │ └── inject │ │ └── react.mjs ├── suppressExperimentalWarnings.js └── utils.mjs ├── .vscode ├── extensions.json ├── tasks.json ├── settings.json └── launch.json ├── .editorconfig ├── .stylelintrc.json ├── .gitignore ├── README.md └── CODE_OF_CONDUCT.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /packages/discord-types/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - packages/* 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | package-manager-strict=false 3 | -------------------------------------------------------------------------------- /browser/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kauht/venkord/HEAD/browser/icon.png -------------------------------------------------------------------------------- /packages/discord-types/src/modules/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./CloudUpload"; 2 | -------------------------------------------------------------------------------- /packages/vencord-types/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | prepare.ts 3 | .gitignore 4 | HOW2PUB.md 5 | -------------------------------------------------------------------------------- /src/components/iconStyles.css: -------------------------------------------------------------------------------- 1 | .vc-owner-crown-icon { 2 | color: var(--status-warning); 3 | } -------------------------------------------------------------------------------- /src/plugins/replyTimestamp/style.css: -------------------------------------------------------------------------------- 1 | .vc-reply-timestamp { 2 | margin-right: 0.25em; 3 | } 4 | -------------------------------------------------------------------------------- /src/plugins/fakeProfileThemes/index.css: -------------------------------------------------------------------------------- 1 | .vc-fpt-preview * { 2 | pointer-events: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/api/ChatButton.css: -------------------------------------------------------------------------------- 1 | .vc-chatbar-button { 2 | display: flex; 3 | align-items: center; 4 | } 5 | -------------------------------------------------------------------------------- /src/plugins/gameActivityToggle/style.css: -------------------------------------------------------------------------------- 1 | [class^="panels"] [class^="avatarWrapper_"] { 2 | min-width: 0; 3 | } -------------------------------------------------------------------------------- /src/plugins/alwaysExpandRoles/README.md: -------------------------------------------------------------------------------- 1 | # Always Expand Roles 2 | 3 | Always expands the role list in profile popouts 4 | -------------------------------------------------------------------------------- /src/plugins/experiments/hideBugReport.css: -------------------------------------------------------------------------------- 1 | #staff-help-popout-staff-help-bug-reporter { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /packages/discord-types/enums/misc.ts: -------------------------------------------------------------------------------- 1 | export const enum CloudUploadPlatform { 2 | REACT_NATIVE = 0, 3 | WEB = 1, 4 | } 5 | -------------------------------------------------------------------------------- /packages/vencord-types/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.*ignore 3 | !package.json 4 | !*.md 5 | !prepare.ts 6 | !index.d.ts 7 | !globals.d.ts 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/developer-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kauht/venkord/HEAD/.github/ISSUE_TEMPLATE/developer-banner.png -------------------------------------------------------------------------------- /scripts/header-new.txt: -------------------------------------------------------------------------------- 1 | Vencord, a Discord client mod 2 | Copyright (c) {year} {author} 3 | SPDX-License-Identifier: GPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /src/plugins/shikiCodeblocks.desktop/devicon.css: -------------------------------------------------------------------------------- 1 | @import url("https://cdn.jsdelivr.net/gh/devicons/devicon@v2.10.1/devicon.min.css"); 2 | -------------------------------------------------------------------------------- /src/plugins/messageLogger/deleteStyleOverlay.css: -------------------------------------------------------------------------------- 1 | .messagelogger-deleted { 2 | background-color: hsl(var(--red-430-hsl, 0 85% 61%) / 15%) !important; 3 | } -------------------------------------------------------------------------------- /src/plugins/noMaskedUrlPaste/README.md: -------------------------------------------------------------------------------- 1 | # NoMaskedUrlPaste 2 | 3 | Pasting a link while you have text selected will NOT paste your link as a masked link. 4 | -------------------------------------------------------------------------------- /packages/discord-types/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Hint: https://docs.discord.food is an incredible resource and allows you to copy paste complete enums and interfaces 2 | -------------------------------------------------------------------------------- /packages/vencord-types/HOW2PUB.md: -------------------------------------------------------------------------------- 1 | # How to publish 2 | 3 | 1. run `pnpm generateTypes` in the project root 4 | 2. bump package.json version 5 | 3. npm publish 6 | -------------------------------------------------------------------------------- /src/components/Divider.css: -------------------------------------------------------------------------------- 1 | .vc-divider { 2 | height: 1px; 3 | width: 100%; 4 | border: none; 5 | border-top: 1px solid var(--border-subtle); 6 | } -------------------------------------------------------------------------------- /src/plugins/callTimer/alignedChatInputFix.css: -------------------------------------------------------------------------------- 1 | [class*="panels"] [class*="inner_"], 2 | [class*="rtcConnectionStatus_"] { 3 | height: fit-content !important; 4 | } -------------------------------------------------------------------------------- /src/plugins/stickerPaste/README.md: -------------------------------------------------------------------------------- 1 | # StickerPaste 2 | 3 | Makes picking a sticker in the sticker picker insert it into the chatbox instead of instantly sending. 4 | -------------------------------------------------------------------------------- /src/plugins/mutualGroupDMs/style.css: -------------------------------------------------------------------------------- 1 | .vc-mutual-gdms-modal-tab-bar { 2 | gap: 0; 3 | } 4 | 5 | .vc-mutual-gdms-modal-v2-tab-bar { 6 | --space-xl: 16px; 7 | } 8 | -------------------------------------------------------------------------------- /src/components/settings/tabs/plugins/PluginModal.css: -------------------------------------------------------------------------------- 1 | .vc-plugin-modal-info { 2 | align-items: center; 3 | } 4 | 5 | .vc-plugin-modal-description { 6 | flex-grow: 1; 7 | } 8 | -------------------------------------------------------------------------------- /packages/discord-types/enums/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./activity"; 2 | export * from "./channel"; 3 | export * from "./commands"; 4 | export * from "./messages"; 5 | export * from "./misc"; 6 | -------------------------------------------------------------------------------- /packages/vencord-types/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | /// 4 | /// 5 | /// 6 | -------------------------------------------------------------------------------- /src/plugins/fixImagesQuality/README.md: -------------------------------------------------------------------------------- 1 | # Fix Images Quality 2 | 3 | Improves quality of images in chat by forcing png format. 4 | 5 | This plugin does not change how others see your images! 6 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/messages/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./Commands"; 2 | export * from "./Message"; 3 | export * from "./Embed"; 4 | export * from "./Emoji"; 5 | export * from "./Sticker"; 6 | -------------------------------------------------------------------------------- /src/plugins/imageLink/README.md: -------------------------------------------------------------------------------- 1 | # ImageLink 2 | 3 | If a message consists of only a link to an image, Discord hides the link and shows only the image embed. This plugin makes the link show regardless. 4 | -------------------------------------------------------------------------------- /src/plugins/userMessagesPronouns/README.md: -------------------------------------------------------------------------------- 1 | User Messages Pronouns 2 | 3 | Adds pronouns to chat user messages 4 | 5 | ![](https://github.com/user-attachments/assets/34dc373d-faf4-4420-b49b-08b2647baa3b) 6 | -------------------------------------------------------------------------------- /src/plugins/showTimeoutDuration/styles.css: -------------------------------------------------------------------------------- 1 | .vc-std-wrapper { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .vc-std-wrapper [class*="communicationDisabled"] { 7 | margin-right: 0; 8 | } 9 | -------------------------------------------------------------------------------- /src/plugins/favGifSearch/README.md: -------------------------------------------------------------------------------- 1 | # FavoriteGifSearch 2 | 3 | Adds a search bar to favorite gifs. 4 | 5 | ![Screenshot](https://github.com/Vendicated/Vencord/assets/45497981/19552adc-d921-4153-976e-e9361dc8fdaf) 6 | -------------------------------------------------------------------------------- /src/plugins/quickMention/README.md: -------------------------------------------------------------------------------- 1 | # QuickMention 2 | 3 | Adds a mention icon to the messages action bar 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/55940580/82d3fec7-4196-4917-b3c2-6e652b2aff9e) 6 | -------------------------------------------------------------------------------- /src/plugins/copyFileContents/README.md: -------------------------------------------------------------------------------- 1 | # CopyFileContents 2 | 3 | Adds a button to text file attachments to copy their contents. 4 | 5 | ![](https://github.com/user-attachments/assets/b1a0f6f4-106f-4953-94d9-4c5ef5810bca) 6 | -------------------------------------------------------------------------------- /src/plugins/notificationVolume/README.md: -------------------------------------------------------------------------------- 1 | # NotificationVolume 2 | 3 | Set a separate volume for notifications and in-app sounds (e.g. messages, call sound, mute/unmute) helping your ears stay healthy for many years to come. 4 | -------------------------------------------------------------------------------- /src/plugins/platformIndicators/style.css: -------------------------------------------------------------------------------- 1 | .vc-platform-indicator { 2 | display: inline-flex; 3 | justify-content: center; 4 | align-items: center; 5 | vertical-align: top; 6 | position: relative; 7 | } 8 | -------------------------------------------------------------------------------- /packages/vencord-types/README.md: -------------------------------------------------------------------------------- 1 | # Vencord Types 2 | 3 | Typings for Vencord's api, published to npm 4 | 5 | ```sh 6 | npm i @vencord/types 7 | 8 | yarn add @vencord/types 9 | 10 | pnpm add @vencord/types 11 | ``` 12 | -------------------------------------------------------------------------------- /src/plugins/friendsSince/README.md: -------------------------------------------------------------------------------- 1 | # FriendsSince 2 | 3 | Shows when you became friends with someone in the user popout 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/45497981/bb258188-ab48-4c4d-9858-1e90ba41e926) 6 | -------------------------------------------------------------------------------- /src/plugins/copyStickerLinks/README.MD: -------------------------------------------------------------------------------- 1 | # CopyStickerLinks 2 | 3 | Adds "Copy Link" and "Open Link" options to the context menu of stickers! 4 | 5 | ![](https://github.com/user-attachments/assets/a0982d5c-ab83-458b-9ca3-834803e0782e) 6 | -------------------------------------------------------------------------------- /src/plugins/imageFilename/README.md: -------------------------------------------------------------------------------- 1 | # ImageFilename 2 | 3 | Display the file name of images & GIFs as a tooltip when hovering over them 4 | 5 | ![](https://github.com/user-attachments/assets/44583f17-506f-4913-b85c-513eee77b645) 6 | -------------------------------------------------------------------------------- /src/plugins/replyTimestamp/README.md: -------------------------------------------------------------------------------- 1 | # ReplyTimestamp 2 | 3 | Shows timestamps on the previews of replied-to messages. Pretty simple. 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/1547062/62e2b67a-e567-4c7a-884d-4640f897f7e0) 6 | -------------------------------------------------------------------------------- /src/plugins/copyFileContents/style.css: -------------------------------------------------------------------------------- 1 | .vc-cfc-button { 2 | color: var(--interactive-normal); 3 | cursor: pointer; 4 | padding-left: 4px; 5 | } 6 | 7 | .vc-cfc-button:hover { 8 | color: var(--interactive-hover); 9 | } 10 | -------------------------------------------------------------------------------- /src/plugins/openInApp/README.md: -------------------------------------------------------------------------------- 1 | # OpenInApp 2 | 3 | Open links in their respective apps instead of your browser 4 | 5 | ## Currently supports: 6 | 7 | - Spotify 8 | - Steam 9 | - EpicGames 10 | - Tidal 11 | - Apple Music (iTunes) 12 | -------------------------------------------------------------------------------- /src/plugins/pictureInPicture/styles.css: -------------------------------------------------------------------------------- 1 | .vc-pip-button { 2 | color: var(--interactive-normal); 3 | } 4 | 5 | .vc-pip-button:hover { 6 | background-color: var(--background-modifier-hover); 7 | color: var(--interactive-hover); 8 | } 9 | -------------------------------------------------------------------------------- /src/plugins/previewMessage/README.md: -------------------------------------------------------------------------------- 1 | # PreviewMessage 2 | 3 | Lets you preview your message before sending it. 4 | 5 | ![the plugin in action](https://github.com/Vendicated/Vencord/assets/45497981/3ce32860-e5cd-4ea2-bdab-e121f1703579) 6 | 7 | -------------------------------------------------------------------------------- /src/plugins/replaceGoogleSearch/README.md: -------------------------------------------------------------------------------- 1 | # ReplaceGoogleSearch 2 | 3 | Replaces the Google search with different Engines 4 | 5 | ![Visualization](https://github.com/Vendicated/Vencord/assets/61953774/8b8158d2-0407-4d7b-9dff-a8b9bdc1a122) 6 | -------------------------------------------------------------------------------- /src/plugins/quickReply/README.md: -------------------------------------------------------------------------------- 1 | # QuickReply 2 | 3 | Reply to (ctrl + up/down) and edit (ctrl + shift + up/down) messages via keybinds 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/55940580/df79a27a-6529-4c70-8870-3c17d3637e4f) 6 | 7 | -------------------------------------------------------------------------------- /src/plugins/typingTweaks/style.css: -------------------------------------------------------------------------------- 1 | .vc-typing-user { 2 | cursor: pointer; 3 | 4 | [class^="wrapper"] { 5 | display: inline-block; 6 | margin-right: 0.25em; 7 | vertical-align: -4px; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/plugins/fullSearchContext/README.md: -------------------------------------------------------------------------------- 1 | # FullSearchContext 2 | 3 | Makes the message context menu in message search results have all options you'd expect. 4 | 5 | ![](https://github.com/user-attachments/assets/472d1327-3935-44c7-b7c4-0978b5348550) 6 | -------------------------------------------------------------------------------- /src/plugins/unlockedAvatarZoom/README.md: -------------------------------------------------------------------------------- 1 | # UnlockedAvatarZoom 2 | 3 | Allows you to zoom in further in the image crop tool when changing your avatar 4 | 5 | ![](https://raw.githubusercontent.com/Vencord/plugin-assets/main/UnlockedAvatarZoom/demo.avif) 6 | -------------------------------------------------------------------------------- /src/components/BaseText.css: -------------------------------------------------------------------------------- 1 | .vc-text-base { 2 | font-family: var(--font-primary); 3 | color: var(--text-default); 4 | line-height: normal; 5 | 6 | /* Discord puts an insane default margin on p tags, so reset that here */ 7 | margin: 0; 8 | } -------------------------------------------------------------------------------- /src/plugins/betterSessions/styles.css: -------------------------------------------------------------------------------- 1 | .vc-betterSessions-footer-buttons { 2 | display: flex; 3 | gap: 0.5em; 4 | align-items: center; 5 | } 6 | 7 | .vc-betterSessions-rename-btn { 8 | margin-left: 4px; 9 | translate: 0 -2px; 10 | } -------------------------------------------------------------------------------- /src/plugins/dearrow/README.md: -------------------------------------------------------------------------------- 1 | # Dearrow 2 | 3 | Makes YouTube embed titles and thumbnails less sensationalist, powered by [Dearrow](https://dearrow.ajay.app/) 4 | 5 | https://github.com/Vendicated/Vencord/assets/45497981/7bf81108-102d-47c5-8ba5-357db4db1283 6 | -------------------------------------------------------------------------------- /src/plugins/pauseInvitesForever/README.md: -------------------------------------------------------------------------------- 1 | # PauseInvitesForever 2 | 3 | Adds a button to the Security Actions modal to to pause invites indefinitely. 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/47677887/e5ba40a3-cb08-462a-8615-fb74dd54c790) 6 | -------------------------------------------------------------------------------- /src/plugins/fixYoutubeEmbeds.desktop/README.md: -------------------------------------------------------------------------------- 1 | # FixYoutubeEmbeds 2 | 3 | Bypasses youtube videos being blocked from display on Discord (for example by UMG) 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/45497981/7a5fdcaa-217c-4c63-acae-f0d6af2f79be) 6 | -------------------------------------------------------------------------------- /src/plugins/whoReacted/README.md: -------------------------------------------------------------------------------- 1 | # WhoReacted 2 | 3 | Next to each reaction, display each user's avatar. Each avatar can be clicked and will open the profile. 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/57493648/97fec9e8-396f-4f5e-916e-1ec21445113d) 6 | -------------------------------------------------------------------------------- /src/plugins/autoDndWhilePlaying.discordDesktop/README.md: -------------------------------------------------------------------------------- 1 | # AutoDNDWhilePlaying 2 | 3 | This plugin automatically updates your online status (online, idle, dnd) when launching games. 4 | 5 | It will change your status back to the prior status when the game is closed. 6 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/WindowStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export class WindowStore extends FluxStore { 4 | isElementFullScreen(): boolean; 5 | isFocused(): boolean; 6 | windowSize(): Record<"width" | "height", number>; 7 | } 8 | -------------------------------------------------------------------------------- /src/plugins/hideAttachments/styles.css: -------------------------------------------------------------------------------- 1 | .vc-hideAttachments-accessory { 2 | color: var(--text-muted); 3 | margin-top: 0.5em; 4 | font-style: italic; 5 | font-weight: 400; 6 | } 7 | 8 | .vc-hideAttachments-no-content { 9 | margin-top: 0; 10 | } 11 | -------------------------------------------------------------------------------- /src/plugins/messageClickActions/README.md: -------------------------------------------------------------------------------- 1 | # MessageClickActions 2 | 3 | Allows you to double click to edit/reply to a message or delete it if you hold the backspace key 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/55940580/6885aca2-4021-4910-b636-bb40f877a816) 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "EditorConfig.EditorConfig", 5 | "GregorBiswanger.json2ts", 6 | "stylelint.vscode-stylelint", 7 | "Vendicated.vencord-companion" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/plugins/_api/badges/fixDiscordBadgePadding.css: -------------------------------------------------------------------------------- 1 | /* the profile popout badge container(s) */ 2 | [class*="profile_"] [class*="tags_"] [class*="container_"] { 3 | /* Discord has gap set to 2px instead of 1px, which causes the 12th badge to wrap to a new line. */ 4 | gap: 1px; 5 | } -------------------------------------------------------------------------------- /src/plugins/betterRoleContext/README.md: -------------------------------------------------------------------------------- 1 | # BetterRoleContext 2 | 3 | Adds options to copy role color, edit role and view role icon when right clicking roles in the user profile 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/45497981/354220a4-09f3-4c5f-a28e-4b19ca775190) 6 | 7 | -------------------------------------------------------------------------------- /src/plugins/validReply/README.md: -------------------------------------------------------------------------------- 1 | # ValidReply 2 | 3 | Fixes referenced (replied to) messages showing as "Message could not be loaded". 4 | 5 | Hover the text to load the message! 6 | 7 | ![](https://github.com/Vendicated/Vencord/assets/45801973/d3286acf-e822-4b7f-a4e7-8ced18f581af) 8 | -------------------------------------------------------------------------------- /src/plugins/customidle/README.md: -------------------------------------------------------------------------------- 1 | # CustomIdle 2 | 3 | Lets you change the time until your status gets automatically set to idle. You can also prevent idling altogether. 4 | 5 | ![Plugin Configuration](https://github.com/Vendicated/Vencord/assets/45801973/4e5259b2-18e0-42e5-b69f-efc672ce1e0b) 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/GuildStore.d.ts: -------------------------------------------------------------------------------- 1 | import { Guild, FluxStore } from ".."; 2 | 3 | export class GuildStore extends FluxStore { 4 | getGuild(guildId: string): Guild; 5 | getGuildCount(): number; 6 | getGuilds(): Record; 7 | getGuildIds(): string[]; 8 | } 9 | -------------------------------------------------------------------------------- /src/plugins/mentionAvatars/README.md: -------------------------------------------------------------------------------- 1 | # MentionAvatars 2 | 3 | Shows user avatars and role icons inside mentions 4 | 5 | ![](https://github.com/user-attachments/assets/fc76ea47-5e19-4063-a592-c57785a75cc7) 6 | ![](https://github.com/user-attachments/assets/76c4c3d9-7cde-42db-ba84-903cbb40c163) 7 | -------------------------------------------------------------------------------- /src/components/ErrorCard.css: -------------------------------------------------------------------------------- 1 | .vc-error-card { 2 | padding: 2em; 3 | background-color: #e7828430; 4 | border: 1px solid #e78284; 5 | border-radius: 5px; 6 | color: var(--text-default, white); 7 | 8 | & a:hover { 9 | text-decoration: underline; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/plugins/consoleJanitor/README.md: -------------------------------------------------------------------------------- 1 | # ConsoleJanitor 2 | 3 | Disables annoying console messages/errors. This plugin mainly removes errors/warnings that happen all the time and Discord logger messages. 4 | 5 | One of the disabled messages is the "Window state not initialized" warning, for example. 6 | -------------------------------------------------------------------------------- /src/plugins/showMeYourName/styles.css: -------------------------------------------------------------------------------- 1 | .vc-smyn-suffix { 2 | color: var(--text-muted); 3 | -webkit-text-fill-color: initial; 4 | isolation: isolate; 5 | } 6 | 7 | .vc-smyn-suffix::before { 8 | content: "("; 9 | } 10 | 11 | .vc-smyn-suffix::after { 12 | content: ")"; 13 | } 14 | -------------------------------------------------------------------------------- /src/plugins/copyEmojiMarkdown/README.md: -------------------------------------------------------------------------------- 1 | # CopyEmojiMarkdown 2 | 3 | Allows you to copy emojis as formatted string. Custom emojis will be copied as `<:trolley:1024751352028602449>`, default emojis as `🛒` 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/45497981/417f345a-7031-4fe7-8e42-e238870cd547) 6 | -------------------------------------------------------------------------------- /src/plugins/betterSessions/README.md: -------------------------------------------------------------------------------- 1 | # BetterSessions 2 | 3 | Enhances the sessions (devices) menu. Allows you to view exact timestamps, give each session a custom name, and receive notifications about new sessions. 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/9750071/4a44b617-bb8f-4dcb-93f1-b7d2575ed3d8) 6 | -------------------------------------------------------------------------------- /src/plugins/voiceDownload/style.css: -------------------------------------------------------------------------------- 1 | .vc-voice-download { 2 | width: 24px; 3 | height: 24px; 4 | color: var(--interactive-normal); 5 | margin-left: 12px; 6 | cursor: pointer; 7 | position: relative; 8 | } 9 | 10 | .vc-voice-download:hover { 11 | color: var(--interactive-active); 12 | } 13 | -------------------------------------------------------------------------------- /src/plugins/dearrow/styles.css: -------------------------------------------------------------------------------- 1 | .vc-dearrow-toggle-off .vc-dearrow-icon { 2 | filter: grayscale(1); 3 | } 4 | 5 | .vc-dearrow-toggle-on, .vc-dearrow-toggle-off { 6 | all: unset; 7 | display: inline; 8 | cursor: pointer; 9 | position: absolute; 10 | top: 0.75rem; 11 | right: 0.75rem; 12 | } 13 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./Activity"; 2 | export * from "./Application"; 3 | export * from "./Channel"; 4 | export * from "./Guild"; 5 | export * from "./GuildMember"; 6 | export * from "./messages"; 7 | export * from "./Role"; 8 | export * from "./User"; 9 | export * from "./Record"; 10 | -------------------------------------------------------------------------------- /src/plugins/readAllNotificationsButton/style.css: -------------------------------------------------------------------------------- 1 | .vc-ranb-button { 2 | color: var(--interactive-normal); 3 | padding: 0 0.5em; 4 | width: 100%; 5 | font-size: 14px; 6 | white-space: nowrap; 7 | box-sizing: border-box; 8 | } 9 | 10 | .vc-ranb-button:hover { 11 | color: var(--interactive-active); 12 | } -------------------------------------------------------------------------------- /src/components/settings/tabs/plugins/LinkIconButton.css: -------------------------------------------------------------------------------- 1 | .vc-settings-modal-link-icon { 2 | height: 32px; 3 | width: 32px; 4 | border-radius: 50%; 5 | border: 4px solid var(--background-base-lowest); 6 | box-sizing: border-box 7 | } 8 | 9 | .vc-settings-modal-links { 10 | display: flex; 11 | gap: 0.2em; 12 | } -------------------------------------------------------------------------------- /src/plugins/onePingPerDM/README.md: -------------------------------------------------------------------------------- 1 | # OnePingPerDM 2 | If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping. Read the messages to reset the limit 3 | 4 | ## Purpose 5 | - Prevents ping audio spam in DMs 6 | - Be able to distinguish more than one ping as multiple users 7 | - Be less annoyed while gaming 8 | -------------------------------------------------------------------------------- /src/plugins/noUnblockToJump/README.md: -------------------------------------------------------------------------------- 1 | # No Unblock To Jump 2 | 3 | Removes the popup preventing you to jump to a message from a blocked/ignored user or likely spammer (eg: in search results) 4 | 5 | ![A modal popup telling you to unblock a user to jump their message](https://github.com/user-attachments/assets/0e4b859d-f3b3-4101-9a83-829afb473d1e) 6 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/TypingStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export class TypingStore extends FluxStore { 4 | /** 5 | * returns a map of user ids to timeout ids 6 | */ 7 | getTypingUsers(channelId: string): Record; 8 | isTyping(channelId: string, userId: string): boolean; 9 | } 10 | -------------------------------------------------------------------------------- /src/plugins/_api/memberListDecorators/style.css: -------------------------------------------------------------------------------- 1 | .vc-member-list-decorators-wrapper { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | gap: 0.25em; 6 | } 7 | 8 | .vc-member-list-decorators-wrapper:not(:empty) { 9 | /* Margin to match default Discord decorators */ 10 | margin-left: 0.25em; 11 | } 12 | -------------------------------------------------------------------------------- /packages/discord-types/src/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./common"; 2 | export * from "./classes"; 3 | export * from "./components"; 4 | export * from "./flux"; 5 | export * from "./fluxEvents"; 6 | export * from "./menu"; 7 | export * from "./modules"; 8 | export * from "./stores"; 9 | export * from "./utils"; 10 | export * as Webpack from "../webpack"; 11 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard", 3 | "rules": { 4 | "selector-class-pattern": [ 5 | "^[a-z][a-zA-Z0-9]*(-[a-z0-9][a-zA-Z0-9]*)*$", 6 | { 7 | "message": "Expected class selector to be kebab-case with camelCase segments" 8 | } 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/plugins/accountPanelServerProfile/README.md: -------------------------------------------------------------------------------- 1 | # AccountPanelServerProfile 2 | 3 | Right click your account panel in the bottom left to view your profile in the current server 4 | 5 | ![](https://github.com/user-attachments/assets/3228497d-488f-479c-93d2-a32ccdb08f0f) 6 | 7 | ![](https://github.com/user-attachments/assets/6fc45363-d95f-4810-812f-2f9fb28b41b5) 8 | -------------------------------------------------------------------------------- /src/utils/clipboard.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export function copyToClipboard(text: string): Promise { 8 | return IS_DISCORD_DESKTOP ? DiscordNative.clipboard.copy(text) : navigator.clipboard.writeText(text); 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | 4 | *.exe 5 | vencord_installer 6 | 7 | .idea 8 | .DS_Store 9 | 10 | yarn.lock 11 | bun.lock 12 | package-lock.json 13 | 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | lerna-debug.log* 19 | .pnpm-debug.log* 20 | *.tsbuildinfo 21 | 22 | src/userplugins 23 | 24 | ExtensionCache/ 25 | /settings 26 | -------------------------------------------------------------------------------- /src/plugins/youtubeAdblock.desktop/README.md: -------------------------------------------------------------------------------- 1 | # WatchTogetherAdblock 2 | 3 | Block ads in YouTube embeds and the WatchTogether activity via AdGuard 4 | 5 | Note that this only works for yourself, other users in the activity will still see ads. 6 | 7 | Powered by a modified version of [Adguard's BlockYoutubeAdsShortcut](https://github.com/AdguardTeam/BlockYouTubeAdsShortcut) 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Vencord Support Server 4 | url: https://discord.gg/D9uwnFnqmd 5 | about: If you need help regarding Vencord, please join our support server! 6 | - name: Vencord Installer 7 | url: https://github.com/Vencord/Installer 8 | about: You can find the Vencord Installer here 9 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/GuildRoleStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore, Role } from ".."; 2 | 3 | // TODO: add the rest of the methods for GuildRoleStore 4 | export class GuildRoleStore extends FluxStore { 5 | getRole(guildId: string, roleId: string): Role; 6 | getSortedRoles(guildId: string): Role[]; 7 | getRolesSnapshot(guildId: string): Record; 8 | } 9 | -------------------------------------------------------------------------------- /src/plugins/fullUserInChatbox/README.md: -------------------------------------------------------------------------------- 1 | # Full User In Chatbox 2 | 3 | Adds the full user mention to the textbox 4 | 5 | Adds the avatar if you have mentioned avatars enabled 6 | 7 | Provides the full context menu to make it easy to access the users profile, and other common actions 8 | 9 | https://github.com/user-attachments/assets/cd9edb33-99c8-4c8d-b669-8cddd05f4b45 10 | -------------------------------------------------------------------------------- /src/plugins/messageLogger/deleteStyleText.css: -------------------------------------------------------------------------------- 1 | .messagelogger-deleted { 2 | --text-default: var(--status-danger, #f04747); 3 | --interactive-normal: var(--status-danger, #f04747); 4 | --text-muted: var(--status-danger, #f04747); 5 | --embed-title: var(--red-460, #be3535); 6 | --text-link: var(--red-460, #be3535); 7 | --header-primary: var(--red-460, #be3535); 8 | } 9 | -------------------------------------------------------------------------------- /src/plugins/userVoiceShow/README.md: -------------------------------------------------------------------------------- 1 | # User Voice Show 2 | 3 | Shows an indicator when a user is in a Voice Channel 4 | 5 | ![a preview of the indicator in the user profile](https://github.com/user-attachments/assets/48f825e4-fad5-40d7-bb4f-41d5e595aae0) 6 | 7 | ![a preview of the indicator in the member list](https://github.com/user-attachments/assets/51be081d-7bbb-45c5-8533-d565228e50c1) 8 | -------------------------------------------------------------------------------- /src/plugins/betterSettings/README.md: -------------------------------------------------------------------------------- 1 | # BetterSettings 2 | 3 | Improves Discord's Settings via multiple (toggleable) changes: 4 | - makes opening settings much faster 5 | - removes the scuffed transition animation 6 | - organises the settings cog context menu into categories 7 | 8 | ![](https://github.com/Vendicated/Vencord/assets/45497981/e8d67a95-3909-4be5-8281-8cf9d2f1c30e) 9 | 10 | -------------------------------------------------------------------------------- /src/plugins/showConnections/styles.css: -------------------------------------------------------------------------------- 1 | .vc-user-connection { 2 | all: unset; 3 | display: inline-block; 4 | cursor: pointer; 5 | } 6 | 7 | .vc-sc-tooltip { 8 | display: inline-flex; 9 | gap: 0.25em; 10 | align-items: center; 11 | } 12 | 13 | .vc-sc-connection-name { 14 | word-break: break-all; 15 | } 16 | 17 | .vc-sc-tooltip-icon { 18 | min-width: 16px; 19 | } 20 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/AuthenticationStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export class AuthenticationStore extends FluxStore { 4 | /** 5 | * Gets the id of the current user 6 | */ 7 | getId(): string; 8 | 9 | // This Store has a lot more methods related to everything Auth, but they really should 10 | // not be needed, so they are not typed 11 | } 12 | -------------------------------------------------------------------------------- /src/plugins/clientTheme/README.md: -------------------------------------------------------------------------------- 1 | # Client Theme 2 | 3 | Revival of the old client theme experiment (The one that came before the sucky one that we actually got) 4 | 5 | ![the ClientTheme theme colour picker](https://user-images.githubusercontent.com/37855219/230238053-e90b7098-373a-459a-bb8c-c24e82f69270.png) 6 | 7 | https://github.com/Vendicated/Vencord/assets/45497981/6c1bcb3b-e0c7-4a02-b0b8-c4c5cd954f38 8 | -------------------------------------------------------------------------------- /src/utils/css.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export function createAndAppendStyle(id: string, target = document.documentElement) { 8 | const style = document.createElement("style"); 9 | style.id = id; 10 | target.append(style); 11 | return style; 12 | } 13 | -------------------------------------------------------------------------------- /src/plugins/typingIndicator/style.css: -------------------------------------------------------------------------------- 1 | .vc-typing-indicator { 2 | display: flex; 3 | align-items: center; 4 | height: 20px; 5 | } 6 | 7 | .vc-typing-indicator-avatars { 8 | margin-left: 6px; 9 | } 10 | 11 | .vc-typing-indicator-dots { 12 | margin-left: 6px; 13 | height: 16px; 14 | display: flex; 15 | align-items: center; 16 | z-index: 0; 17 | cursor: pointer; 18 | } 19 | -------------------------------------------------------------------------------- /src/plugins/vencordToolbox/index.css: -------------------------------------------------------------------------------- 1 | .vc-toolbox-btn, 2 | .vc-toolbox-icon { 3 | -webkit-app-region: no-drag; 4 | } 5 | 6 | .vc-toolbox-icon { 7 | color: var(--interactive-normal); 8 | } 9 | 10 | .vc-toolbox-btn[class*="selected"] .vc-toolbox-icon { 11 | color: var(--interactive-active); 12 | } 13 | 14 | .vc-toolbox-btn:hover .vc-toolbox-icon { 15 | color: var(--interactive-hover); 16 | } 17 | -------------------------------------------------------------------------------- /packages/discord-types/enums/channel.ts: -------------------------------------------------------------------------------- 1 | export const enum ChannelType { 2 | GUILD_TEXT = 0, 3 | DM = 1, 4 | GUILD_VOICE = 2, 5 | GROUP_DM = 3, 6 | GUILD_CATEGORY = 4, 7 | GUILD_ANNOUNCEMENT = 5, 8 | ANNOUNCEMENT_THREAD = 10, 9 | PUBLIC_THREAD = 11, 10 | PRIVATE_THREAD = 12, 11 | GUILD_STAGE_VOICE = 13, 12 | GUILD_DIRECTORY = 14, 13 | GUILD_FORUM = 15, 14 | GUILD_MEDIA = 16 15 | } -------------------------------------------------------------------------------- /src/components/settings/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export * from "../Switch"; 8 | export * from "./AddonCard"; 9 | export * from "./DonateButton"; 10 | export * from "./PluginBadge"; 11 | export * from "./QuickAction"; 12 | export * from "./SpecialCard"; 13 | export * from "./tabs"; 14 | -------------------------------------------------------------------------------- /src/shared/vencordUserAgent.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import gitHash from "~git-hash"; 8 | import gitRemote from "~git-remote"; 9 | 10 | export { gitHash, gitRemote }; 11 | 12 | export const VENCORD_USER_AGENT = `Vencord/${gitHash}${gitRemote ? ` (https://github.com/${gitRemote})` : ""}`; 13 | -------------------------------------------------------------------------------- /src/plugins/betterFolders/README.md: -------------------------------------------------------------------------------- 1 | # Better Folders 2 | 3 | Better Folders offers a variety of options to improve your folder experience 4 | 5 | Always show the folder icon, regardless of if the folder is open or not 6 | 7 | Only have one folder open at a time 8 | 9 | Open folders in a sidebar: 10 | 11 | ![A folder open in a separate sidebar](https://github.com/user-attachments/assets/432d3146-8091-4bae-9c1e-c19046c72947) 12 | -------------------------------------------------------------------------------- /src/plugins/favEmojiFirst/README.md: -------------------------------------------------------------------------------- 1 | # FavoriteEmojiFirst 2 | 3 | Puts your favorite emoji first in the emoji autocomplete. 4 | 5 | ![a screenshot of the favourite emojis section](https://github.com/Vendicated/Vencord/assets/45497981/419c8c16-1afc-46e0-9cc2-20b9c3489711) 6 | ![a comparison of the emoji picker before and after enabling this plugin](https://github.com/Vendicated/Vencord/assets/45497981/4f57626d-cfc6-4155-a47c-2eac191231bb) 7 | -------------------------------------------------------------------------------- /src/plugins/imageZoom/README.md: -------------------------------------------------------------------------------- 1 | # ImageZoom 2 | 3 | Lets you zoom in to images and gifs. Use scroll wheel to zoom in and shift + scroll wheel to increase lens radius / size 4 | 5 | ![the plugin in action](https://github.com/Vendicated/Vencord/assets/45497981/408cd77d-c5f4-40bc-8de2-f977a31b3e5f) 6 | ![the context menu options offered by the plugin](https://github.com/Vendicated/Vencord/assets/45497981/3bede636-f1ce-493f-af46-788b920cb81c) 7 | -------------------------------------------------------------------------------- /src/nativeModules.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | /// 8 | 9 | declare module "~pluginNatives" { 10 | const pluginNatives: Record unknown>>; 11 | export default pluginNatives; 12 | } 13 | -------------------------------------------------------------------------------- /src/plugins/plainFolderIcon/style.css: -------------------------------------------------------------------------------- 1 | .vc-plainFolderIcon-plain { 2 | /* Without this, they are a bit laggier */ 3 | transition: none !important; 4 | 5 | /* Don't show the mini guild icons */ 6 | transform: translateZ(0); 7 | 8 | /* The new icons are fully transparent. Add a sane default to match the old behavior */ 9 | background-color: color-mix(in oklab, var(--custom-folder-color, var(--bg-brand)) 40%, transparent); 10 | } 11 | -------------------------------------------------------------------------------- /src/plugins/showTimeoutDuration/README.md: -------------------------------------------------------------------------------- 1 | # ShowTimeoutDuration 2 | 3 | Displays how much longer a user's timeout will last. 4 | Either in the timeout icon tooltip, or next to it, configurable via settings! 5 | 6 | ![indicator in tooltip](https://github.com/Vendicated/Vencord/assets/45497981/606588a3-2646-40d9-8800-b6307f650136) 7 | 8 | ![indicator next to timeout icon](https://github.com/Vendicated/Vencord/assets/45497981/ab9d2101-0fdc-4143-9310-9488f056eeee) 9 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/UserStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore, User } from ".."; 2 | 3 | export class UserStore extends FluxStore { 4 | filter(filter: (user: User) => boolean, sort?: boolean): Record; 5 | findByTag(username: string, discriminator: string): User; 6 | forEach(action: (user: User) => void): void; 7 | getCurrentUser(): User; 8 | getUser(userId: string): User; 9 | getUsers(): Record; 10 | } 11 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/StreamerModeStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from "@vencord/discord-types"; 2 | 3 | export class StreamerModeStore extends FluxStore { 4 | get autoToggle(): boolean; 5 | get disableNotifications(): boolean; 6 | get disableSounds(): boolean; 7 | get enableContentProtection(): boolean; 8 | get enabled(): boolean; 9 | get hideInstantInvites(): boolean; 10 | get hidePersonalInformation(): boolean; 11 | } 12 | -------------------------------------------------------------------------------- /src/plugins/spotifyControls/hoverOnly.css: -------------------------------------------------------------------------------- 1 | .vc-spotify-button-row { 2 | height: 0; 3 | opacity: 0; 4 | pointer-events: none; 5 | transition: 0.2s; 6 | transition-property: height; 7 | } 8 | 9 | #vc-spotify-player:hover .vc-spotify-button-row { 10 | opacity: 1; 11 | height: 32px; 12 | pointer-events: auto; 13 | 14 | /* only transition opacity on show to prevent clipping */ 15 | transition-property: height, opacity; 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/volumeBooster/README.md: -------------------------------------------------------------------------------- 1 | # Volume Booster 2 | 3 | Allows you to boost the volume over 200% on desktop and over 100% on other clients. 4 | 5 | Works on users, bots, and streams! 6 | 7 | ![the volume being moved up to 270% on vesktop](https://github.com/user-attachments/assets/793e012e-c069-4fa4-a3d5-61c2f55edd3e) 8 | 9 | ![the volume being moved up to 297% on a stream](https://github.com/user-attachments/assets/77463eb9-2537-4821-a3ab-82f60633ccbc) 10 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/Record.d.ts: -------------------------------------------------------------------------------- 1 | type Updater = (value: any) => any; 2 | 3 | /** 4 | * Common Record class extended by various Discord data structures, like User, Channel, Guild, etc. 5 | */ 6 | export class DiscordRecord { 7 | toJS(): Record; 8 | 9 | set(key: string, value: any): this; 10 | merge(data: Record): this; 11 | update(key: string, defaultValueOrUpdater: Updater | any, updater?: Updater): this; 12 | } 13 | -------------------------------------------------------------------------------- /src/api/Commands/types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Command } from "@vencord/discord-types"; 8 | export { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType } from "@vencord/discord-types/enums"; 9 | 10 | export interface VencordCommand extends Command { 11 | isVencordCommand?: boolean; 12 | } 13 | -------------------------------------------------------------------------------- /packages/discord-types/src/classes.d.ts: -------------------------------------------------------------------------------- 1 | export interface ButtonWrapperClasses { 2 | hoverScale: string; 3 | buttonWrapper: string; 4 | button: string; 5 | iconMask: string; 6 | buttonContent: string; 7 | icon: string; 8 | pulseIcon: string; 9 | pulseButton: string; 10 | notificationDot: string; 11 | sparkleContainer: string; 12 | sparkleStar: string; 13 | sparklePlus: string; 14 | sparkle: string; 15 | active: string; 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/serverInfo/README.md: -------------------------------------------------------------------------------- 1 | # ServerInfo 2 | 3 | Allows you to view info about servers and see friends and blocked users 4 | 5 | ![](https://github.com/Vendicated/Vencord/assets/45497981/a49783b5-e8fc-41d8-968f-58600e9f6580) 6 | ![](https://github.com/Vendicated/Vencord/assets/45497981/5efc158a-e671-4196-a15a-77edf79a2630) 7 | ![Available as "Server Profile" option in the server context menu](https://github.com/Vendicated/Vencord/assets/45497981/f43be943-6dc4-4232-9709-fbeb382d8e54) 8 | -------------------------------------------------------------------------------- /src/plugins/sortFriendRequests/styles.css: -------------------------------------------------------------------------------- 1 | .vc-sortFriendRequests-wrapper { 2 | display: flex; 3 | flex-direction: row; 4 | justify-content: space-between; 5 | align-items: center; 6 | width: 100%; 7 | margin-right: 0.5em; 8 | } 9 | 10 | .vc-sortFriendRequests-tooltip { 11 | max-width: none; 12 | white-space: nowrap; 13 | } 14 | 15 | .vc-sortFriendRequests-date { 16 | color: var(--text-muted); 17 | font-family: var(--font-code); 18 | } 19 | -------------------------------------------------------------------------------- /src/plugins/mentionAvatars/styles.css: -------------------------------------------------------------------------------- 1 | .vc-mentionAvatars-icon { 2 | vertical-align: middle; 3 | width: 1em !important; /* insane discord sets width: 100% in channel topic */ 4 | height: 1em; 5 | margin: 0 4px 0.2rem 2px; 6 | box-sizing: border-box; 7 | } 8 | 9 | .vc-mentionAvatars-role-icon { 10 | margin: 0 2px 0.2rem 4px; 11 | } 12 | 13 | /** don't display inside the ServerInfo modal owner mention */ 14 | .vc-gp-owner .vc-mentionAvatars-icon { 15 | display: none; 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/memberCount/CircleIcon.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export function CircleIcon({ className }: { className?: string; }) { 8 | return ( 9 | 10 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/plugins/xsOverlay/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { createSocket, Socket } from "dgram"; 8 | 9 | let xsoSocket: Socket; 10 | 11 | export function sendToOverlay(_, data: any) { 12 | data.messageType = data.type; 13 | const json = JSON.stringify(data); 14 | xsoSocket ??= createSocket("udp4"); 15 | xsoSocket.send(json, 42069, "127.0.0.1"); 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/fixYoutubeEmbeds.desktop/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "FixYoutubeEmbeds", 12 | description: "Bypasses youtube videos being blocked from display on Discord (for example by UMG)", 13 | authors: [Devs.coolelectronics] 14 | }); 15 | -------------------------------------------------------------------------------- /src/plugins/shikiCodeblocks.desktop/previewExample.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable simple-header/header */ 2 | import React from "react"; 3 | 4 | const handleClick = async () => 5 | console.log((await import("@utils/clipboard")).copyToClipboard("\u200b")); 6 | 7 | export const Example: React.FC<{ 8 | real: boolean, 9 | shigged?: number, 10 | }> = ({ real, shigged }) => <> 11 |

{`Shigg${real ? `ies${shigged === 0x1B ? "t" : ""}` : "y"}`}

12 | 13 | ; 14 | -------------------------------------------------------------------------------- /src/webpack/common/userSettings.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { findLazy } from "@webpack"; 8 | 9 | export const UserSettingsActionCreators = { 10 | FrecencyUserSettingsActionCreators: findLazy(m => m.ProtoClass?.typeName?.endsWith(".FrecencyUserSettings")), 11 | PreloadedUserSettingsActionCreators: findLazy(m => m.ProtoClass?.typeName?.endsWith(".PreloadedUserSettings")), 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/Span.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { BaseText, type BaseTextProps } from "./BaseText"; 8 | 9 | export type SpanProps = BaseTextProps<"span">; 10 | 11 | export function Span({ children, ...restProps }: SpanProps) { 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/plugins/_api/messageDecorations/style.css: -------------------------------------------------------------------------------- 1 | .vc-message-decorations-wrapper { 2 | display: inline-flex; 3 | align-items: center; 4 | justify-content: center; 5 | gap: 0.25em; 6 | } 7 | 8 | .vc-message-decorations-wrapper:not(:empty) { 9 | /* Margin to match default Discord decorators */ 10 | margin-left: 0.25em; 11 | 12 | /* Align vertically */ 13 | position: relative; 14 | vertical-align: top; 15 | top: 0.1rem; 16 | height: calc(1rem + 4px); 17 | max-height: calc(1rem + 4px) 18 | } 19 | -------------------------------------------------------------------------------- /src/components/Paragraph.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { BaseText, type BaseTextProps } from "./BaseText"; 8 | 9 | export type ParagraphProps = BaseTextProps<"p">; 10 | 11 | export function Paragraph({ children, ...restProps }: ParagraphProps) { 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/plugins/implicitRelationships/README.md: -------------------------------------------------------------------------------- 1 | # ImplicitRelationships 2 | 3 | Shows your implicit relationships in the Friends tab. 4 | 5 | Implicit relationships on Discord are people with whom you've frecently interacted and don't have a relationship with. Even though Discord thinks you should be friends with them, you haven't added them as friends! 6 | 7 | ![](https://camo.githubusercontent.com/6927161ee0c933f7ef6d61f243cca3e6ea4c8db9d1becd8cbf73c45e1bd0d127/68747470733a2f2f692e646f6c66692e65732f7055447859464662674d2e706e673f6b65793d736e3950343936416c32444c7072) 8 | -------------------------------------------------------------------------------- /src/plugins/permissionFreeWill/README.md: -------------------------------------------------------------------------------- 1 | # PermissionFreeWill 2 | 3 | Removes the client-side restrictions that prevent editing channel permissions, such as permission lockouts ("Pretty sure 4 | you don't want to do this") and onboarding requirements ("Making this change will make your server incompatible [...]") 5 | 6 | ## Warning 7 | 8 | This plugin will let you create permissions in servers that **WILL** lock you out of channels until an administrator 9 | can resolve it for you. Please be careful with the overwrites you are making and check carefully. 10 | -------------------------------------------------------------------------------- /src/plugins/superReactionTweaks/README.md: -------------------------------------------------------------------------------- 1 | # Super Reaction Tweaks 2 | 3 | This plugin applies configurable various tweaks to super reactions. 4 | 5 | ![Screenshot](https://user-images.githubusercontent.com/22851444/281598795-58f07116-9f95-4f64-940b-23a5499f2302.png) 6 | 7 | ## Features: 8 | 9 | **Super React By Default** - The reaction picker will default to super reactions instead of normal reactions. 10 | 11 | **Super Reaction Play Limit** - Allows you to decide how many super reaction animations can play at once, including removing the limit entirely. 12 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/SelectedGuildStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export interface SelectedGuildState { 4 | selectedGuildTimestampMillis: Record; 5 | selectedGuildId: string | null; 6 | lastSelectedGuildId: string | null; 7 | } 8 | 9 | export class SelectedGuildStore extends FluxStore { 10 | getGuildId(): string | null; 11 | getLastSelectedGuildId(): string | null; 12 | getLastSelectedTimestamp(guildId: string): number | null; 13 | getState(): SelectedGuildState | undefined; 14 | } 15 | -------------------------------------------------------------------------------- /src/components/css.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { createAndAppendStyle } from "@utils/css"; 8 | 9 | import { generateTextCss } from "./BaseText"; 10 | import { generateMarginCss } from "./margins"; 11 | 12 | export function addVencordUiStyles() { 13 | createAndAppendStyle("vencord-text", document.head).textContent = generateTextCss(); 14 | createAndAppendStyle("vencord-margins").textContent = generateMarginCss(); 15 | } 16 | -------------------------------------------------------------------------------- /src/plugins/youtubeAdblock.desktop/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | // The entire code of this plugin can be found in native.ts 11 | export default definePlugin({ 12 | name: "YoutubeAdblock", 13 | description: "Block ads in YouTube embeds and the WatchTogether activity via AdGuard", 14 | authors: [Devs.ImLvna, Devs.Ven], 15 | }); 16 | -------------------------------------------------------------------------------- /src/plugins/clearURLs/README.md: -------------------------------------------------------------------------------- 1 | # ClearURLs 2 | 3 | Automatically removes tracking elements from URLs you send. 4 | 5 | Uses data from the [ClearURLs browser extension](https://clearurls.xyz/). 6 | 7 | ## Example 8 | 9 | **Before:** `https://www.amazon.com/dp/exampleProduct/ref=sxin_0_pb?__mk_de_DE=ÅMÅŽÕÑ&keywords=tea&pd_rd_i=exampleProduct&pd_rd_r=8d39e4cd-1e4f-43db-b6e7-72e969a84aa5&pd_rd_w=1pcKM&pd_rd_wg=hYrNl&pf_rd_p=50bbfd25-5ef7-41a2-68d6-74d854b30e30&pf_rd_r=0GMWD0YYKA7XFGX55ADP&qid=1517757263&rnid=2914120011` 10 | 11 | **After:** `https://www.amazon.com/dp/exampleProduct/` 12 | -------------------------------------------------------------------------------- /src/plugins/seeSummaries/README.md: -------------------------------------------------------------------------------- 1 | # Summaries 2 | 3 | Enables Discord's experimental Summaries feature on every server, displaying AI generated summaries of conversations. 4 | 5 | Read more about summaries in the [official Discord help article](https://support.discord.com/hc/en-us/articles/12926016807575-In-Channel-Conversation-Summaries)! 6 | 7 | Note that this plugin can't fetch old summaries, it can only display ones created while your Discord is running with the plugin enabled. 8 | 9 | ![](https://github.com/Vendicated/Vencord/assets/45497981/bd931b0c-2e85-4c10-9f7c-8ba01eb55745) 10 | -------------------------------------------------------------------------------- /src/components/FormSwitch.css: -------------------------------------------------------------------------------- 1 | .vc-form-switch-wrapper { 2 | margin-bottom: 20px; 3 | cursor: pointer; 4 | } 5 | 6 | .vc-form-switch { 7 | display: flex; 8 | width: 100%; 9 | 10 | > :last-child { 11 | margin-left: auto; 12 | } 13 | } 14 | 15 | .vc-form-switch-disabled { 16 | opacity: 0.5; 17 | pointer-events: none; 18 | cursor: not-allowed; 19 | } 20 | 21 | .vc-form-switch-text { 22 | display: flex; 23 | flex-direction: column; 24 | justify-content: center; 25 | gap: 8px; 26 | } 27 | 28 | .vc-form-switch-border { 29 | margin-top: 20px; 30 | } -------------------------------------------------------------------------------- /src/plugins/appleMusic.desktop/README.md: -------------------------------------------------------------------------------- 1 | # AppleMusicRichPresence 2 | 3 | This plugin enables Discord rich presence for your Apple Music! (This only works on macOS with the Music app.) 4 | 5 | ![Screenshot of the activity in Discord](https://github.com/Vendicated/Vencord/assets/70191398/1f811090-ab5f-4060-a9ee-d0ac44a1d3c0) 6 | 7 | ## Configuration 8 | 9 | For the customizable activity format strings, you can use several special strings to include track data in activities! `{name}` is replaced with the track name; `{artist}` is replaced with the artist(s)' name(s); and `{album}` is replaced with the album name. 10 | -------------------------------------------------------------------------------- /src/components/Divider.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import "./Divider.css"; 8 | 9 | import { classes } from "@utils/misc"; 10 | import type { ComponentPropsWithoutRef } from "react"; 11 | 12 | export type DividerProps = ComponentPropsWithoutRef<"hr">; 13 | 14 | export function Divider({ className, ...restProps }: DividerProps) { 15 | return ( 16 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/utils/web-metadata.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export let EXTENSION_BASE_URL: string; 8 | export let EXTENSION_VERSION: string; 9 | 10 | if (IS_EXTENSION) { 11 | const listener = (e: MessageEvent) => { 12 | if (e.data?.type === "vencord:meta") { 13 | ({ EXTENSION_BASE_URL, EXTENSION_VERSION } = e.data.meta); 14 | window.removeEventListener("message", listener); 15 | } 16 | }; 17 | 18 | window.addEventListener("message", listener); 19 | } 20 | -------------------------------------------------------------------------------- /src/plugins/consoleShortcuts/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { IpcMainInvokeEvent } from "electron"; 8 | 9 | export function initDevtoolsOpenEagerLoad(e: IpcMainInvokeEvent) { 10 | const handleDevtoolsOpened = () => e.sender.executeJavaScript("Vencord.Plugins.plugins.ConsoleShortcuts.eagerLoad(true)"); 11 | 12 | if (e.sender.isDevToolsOpened()) 13 | handleDevtoolsOpened(); 14 | else 15 | e.sender.once("devtools-opened", () => handleDevtoolsOpened()); 16 | } 17 | -------------------------------------------------------------------------------- /src/plugins/xsOverlay/README.md: -------------------------------------------------------------------------------- 1 | # XSOverlay Notifier 2 | 3 | Sends Discord messages to [XSOverlay](https://store.steampowered.com/app/1173510/XSOverlay/) for easier viewing while using VR. 4 | 5 | ## Preview 6 | 7 | ![Resulting notification inside XSOverlay](https://github.com/Vendicated/Vencord/assets/24845294/205d2055-bb4a-44e4-b7e3-265391bccd40) 8 | 9 | ![Test notification inside XSOverlay](https://github.com/user-attachments/assets/d3b0c387-1d67-4697-a470-d4a927e228f4) 10 | 11 | ## Usage 12 | - Enable this plugin 13 | - Set port and plugin settings as desired (defaults should work fine) 14 | - Open SteamVR and XSOverlay 15 | -------------------------------------------------------------------------------- /src/plugins/betterFolders/style.css: -------------------------------------------------------------------------------- 1 | .vc-betterFolders-sidebar { 2 | grid-area: betterFoldersSidebar 3 | } 4 | 5 | /* These area names need to be hardcoded. Only betterFoldersSidebar is added by the plugin. */ 6 | .vc-betterFolders-sidebar-grid { 7 | /* stylelint-disable-next-line value-keyword-case */ 8 | grid-template-columns: [start] min-content [guildsEnd] min-content [sidebarEnd] min-content [channelsEnd] 1fr [end]; 9 | grid-template-areas: 10 | "titleBar titleBar titleBar titleBar" 11 | "guildsList betterFoldersSidebar notice notice" 12 | "guildsList betterFoldersSidebar channelsList page"; 13 | } -------------------------------------------------------------------------------- /src/plugins/clientTheme/clientTheme.css: -------------------------------------------------------------------------------- 1 | .vc-clientTheme-settings { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | .vc-clientTheme-container { 7 | display: flex; 8 | flex-direction: row; 9 | justify-content: space-between; 10 | } 11 | 12 | .vc-clientTheme-labels { 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: flex-start; 16 | } 17 | 18 | .vc-clientTheme-container [class^="swatch"] { 19 | border: thin solid var(--input-border) !important; 20 | } 21 | 22 | .vc-clientTheme-buttons-container { 23 | margin-top: 16px; 24 | display: flex; 25 | gap: 4px; 26 | } 27 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/StickersStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore, GuildSticker, PremiumStickerPack, Sticker } from ".."; 2 | 3 | export type StickerGuildMap = Map; 4 | 5 | export class StickersStore extends FluxStore { 6 | getAllGuildStickers(): StickerGuildMap; 7 | getRawStickersByGuild(): StickerGuildMap; 8 | getPremiumPacks(): PremiumStickerPack[]; 9 | 10 | getStickerById(id: string): Sticker | undefined; 11 | getStickerPack(id: string): PremiumStickerPack | undefined; 12 | getStickersByGuildId(guildId: string): Sticker[] | undefined; 13 | 14 | isPremiumPack(id: string): boolean; 15 | } 16 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/ThemeStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export type ThemePreference = "dark" | "light" | "unknown"; 4 | export type SystemTheme = "dark" | "light"; 5 | export type Theme = "light" | "dark" | "darker" | "midnight"; 6 | 7 | export interface ThemeState { 8 | theme: Theme; 9 | status: 0 | 1; 10 | preferences: Record; 11 | } 12 | export class ThemeStore extends FluxStore { 13 | get theme(): Theme; 14 | get darkSidebar(): boolean; 15 | get systemTheme(): SystemTheme; 16 | themePreferenceForSystemTheme(preference: ThemePreference): Theme; 17 | getState(): ThemeState; 18 | } 19 | -------------------------------------------------------------------------------- /src/components/CodeBlock.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { findByPropsLazy } from "@webpack"; 8 | import { Parser } from "@webpack/common"; 9 | 10 | const CodeContainerClasses = findByPropsLazy("markup", "codeContainer"); 11 | 12 | /** 13 | * Renders code in a Discord codeblock 14 | */ 15 | export function CodeBlock(props: { content?: string, lang: string; }) { 16 | return ( 17 |
18 | {Parser.defaultRules.codeBlock.react(props, null, {})} 19 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/plugins/pinDms/constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export const DEFAULT_CHUNK_SIZE = 256; 8 | export const DEFAULT_COLOR = 10070709; 9 | 10 | export const SWATCHES = [ 11 | 1752220, 12 | 3066993, 13 | 3447003, 14 | 10181046, 15 | 15277667, 16 | 15844367, 17 | 15105570, 18 | 15158332, 19 | 9807270, 20 | 6323595, 21 | 22 | 1146986, 23 | 2067276, 24 | 2123412, 25 | 7419530, 26 | 11342935, 27 | 12745742, 28 | 11027200, 29 | 10038562, 30 | 9936031, 31 | 5533306 32 | ]; 33 | -------------------------------------------------------------------------------- /src/plugins/decor/lib/utils/decoration.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { AvatarDecoration } from "@plugins/decor"; 8 | import { Decoration } from "@plugins/decor/lib/api"; 9 | import { SKU_ID } from "@plugins/decor/lib/constants"; 10 | 11 | export function decorationToAsset(decoration: Decoration) { 12 | return `${decoration.animated ? "a_" : ""}${decoration.hash}`; 13 | } 14 | 15 | export function decorationToAvatarDecoration(decoration: Decoration): AvatarDecoration { 16 | return { asset: decorationToAsset(decoration), skuId: SKU_ID }; 17 | } 18 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/Application.d.ts: -------------------------------------------------------------------------------- 1 | import { User } from "./User"; 2 | 3 | export interface Application { 4 | id: string; 5 | name: string; 6 | description?: string | null; 7 | type: number | null; 8 | icon: string | null | undefined; 9 | is_discoverable: boolean; 10 | is_monetized: boolean; 11 | is_verified: boolean; 12 | bot?: User; 13 | deeplink_uri?: string; 14 | flags?: number; 15 | privacy_policy_url?: string; 16 | terms_of_service_url?: string; 17 | install_params?: ApplicationInstallParams; 18 | } 19 | 20 | export interface ApplicationInstallParams { 21 | permissions: string | null; 22 | scopes: string[]; 23 | } 24 | -------------------------------------------------------------------------------- /src/plugins/imageZoom/styles.css: -------------------------------------------------------------------------------- 1 | .vc-imgzoom-lens { 2 | position: absolute; 3 | inset: 0; 4 | z-index: 9999; 5 | border: 2px solid grey; 6 | border-radius: 50%; 7 | overflow: hidden; 8 | cursor: none; 9 | box-shadow: inset 0 0 10px 2px grey; 10 | filter: drop-shadow(0 0 2px grey); 11 | pointer-events: none; 12 | 13 | /* negate the border offsetting the lens */ 14 | margin: -2px; 15 | } 16 | 17 | .vc-imgzoom-square { 18 | border-radius: 0; 19 | } 20 | 21 | .vc-imgzoom-nearest-neighbor > .vc-imgzoom-image { 22 | image-rendering: pixelated; 23 | 24 | /* https://googlechrome.github.io/samples/image-rendering-pixelated/index.html */ 25 | } 26 | -------------------------------------------------------------------------------- /src/plugins/fixImagesQuality/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "FixImagesQuality", 12 | description: "Improves quality of images in chat by forcing png format", 13 | authors: [Devs.Nuckyz], 14 | patches: [ 15 | { 16 | find: ".handleImageLoad)", 17 | replacement: { 18 | match: /(?<=\i=)"webp"/, 19 | replace: '"png"' 20 | } 21 | } 22 | ] 23 | }); 24 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build", 8 | "type": "shell", 9 | "command": "pnpm build", 10 | "group": { 11 | "kind": "build", 12 | "isDefault": true 13 | } 14 | }, 15 | { 16 | "label": "Watch", 17 | "type": "shell", 18 | "command": "pnpm watch", 19 | "problemMatcher": [], 20 | "group": { 21 | "kind": "build" 22 | } 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /packages/discord-types/src/stores/MessageStore.d.ts: -------------------------------------------------------------------------------- 1 | import { MessageJSON, FluxStore, Message } from ".."; 2 | 3 | export class MessageStore extends FluxStore { 4 | getMessage(channelId: string, messageId: string): Message; 5 | /** @returns This return object is fucking huge; I'll type it later. */ 6 | getMessages(channelId: string): unknown; 7 | getRawMessages(channelId: string): Record; 8 | hasCurrentUserSentMessage(channelId: string): boolean; 9 | hasPresent(channelId: string): boolean; 10 | isLoadingMessages(channelId: string): boolean; 11 | jumpedMessageId(channelId: string): string | undefined; 12 | whenReady(channelId: string, callback: () => void): void; 13 | } 14 | -------------------------------------------------------------------------------- /src/plugins/noTypingAnimation/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "NoTypingAnimation", 12 | authors: [Devs.AutumnVN], 13 | description: "Disables the CPU-intensive typing dots animation", 14 | patches: [ 15 | { 16 | find: "dotCycle", 17 | replacement: { 18 | match: /focused:(\i)/g, 19 | replace: (_, focused) => `_focused:${focused}=false` 20 | } 21 | } 22 | ] 23 | }); 24 | -------------------------------------------------------------------------------- /browser/content.js: -------------------------------------------------------------------------------- 1 | if (typeof browser === "undefined") { 2 | var browser = chrome; 3 | } 4 | 5 | const style = document.createElement("link"); 6 | style.type = "text/css"; 7 | style.rel = "stylesheet"; 8 | style.href = browser.runtime.getURL("dist/Vencord.css"); 9 | 10 | document.addEventListener( 11 | "DOMContentLoaded", 12 | () => { 13 | document.body.insertAdjacentElement("afterend", style); 14 | window.postMessage({ 15 | type: "vencord:meta", 16 | meta: { 17 | EXTENSION_VERSION: browser.runtime.getManifest().version, 18 | EXTENSION_BASE_URL: browser.runtime.getURL(""), 19 | } 20 | }); 21 | }, 22 | { once: true } 23 | ); 24 | -------------------------------------------------------------------------------- /src/plugins/decor/ui/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { classNameFactory } from "@api/Styles"; 8 | import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack"; 9 | 10 | export const cl = classNameFactory("vc-decor-"); 11 | export const DecorationModalStyles = findByPropsLazy("modalPreview", "modalCloseButton", "spinner", "modal"); 12 | 13 | export const requireAvatarDecorationModal = extractAndLoadChunksLazy(["initialSelectedDecoration:", /initialSelectedDecoration:\i,.{0,300}Promise\.all/]); 14 | export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]); 15 | -------------------------------------------------------------------------------- /src/plugins/betterGifPicker/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "BetterGifPicker", 12 | description: "Makes the gif picker open the favourite category by default", 13 | authors: [Devs.Samwich], 14 | patches: [ 15 | { 16 | find: '"state",{resultType:', 17 | replacement: [{ 18 | match: /(?<="state",{resultType:)null/, 19 | replace: '"Favorites"' 20 | }] 21 | } 22 | ] 23 | }); 24 | -------------------------------------------------------------------------------- /packages/discord-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vencord/discord-types", 3 | "author": "Vencord Contributors", 4 | "private": false, 5 | "description": "Typescript definitions for the webpack modules of the Discord Web app", 6 | "version": "1.0.0", 7 | "license": "LGPL-3.0-or-later", 8 | "types": "src/index.d.ts", 9 | "type": "module", 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Vendicated/Vencord.git", 13 | "directory": "packages/discord-types" 14 | }, 15 | "dependencies": { 16 | "moment": "^2.22.2", 17 | "type-fest": "^4.41.0" 18 | }, 19 | "peerDependencies": { 20 | "@types/react": "^19.0.10" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/utils/mergeDefaults.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | /** 8 | * Recursively merges defaults into an object and returns the same object 9 | * @param obj Object 10 | * @param defaults Defaults 11 | * @returns obj 12 | */ 13 | export function mergeDefaults(obj: T, defaults: T): T { 14 | for (const key in defaults) { 15 | const v = defaults[key]; 16 | if (typeof v === "object" && !Array.isArray(v)) { 17 | obj[key] ??= {} as any; 18 | mergeDefaults(obj[key], v); 19 | } else { 20 | obj[key] ??= v; 21 | } 22 | } 23 | return obj; 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll.eslint": "explicit" 5 | }, 6 | "[typescript]": { 7 | "editor.defaultFormatter": "vscode.typescript-language-features" 8 | }, 9 | "[typescriptreact]": { 10 | "editor.defaultFormatter": "vscode.typescript-language-features" 11 | }, 12 | "javascript.format.semicolons": "insert", 13 | "typescript.format.semicolons": "insert", 14 | "typescript.preferences.quoteStyle": "double", 15 | "javascript.preferences.quoteStyle": "double", 16 | 17 | "gitlens.remotes": [ 18 | { 19 | "domain": "codeberg.org", 20 | "type": "Gitea" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/plugins/ignoreActivities/README.md: -------------------------------------------------------------------------------- 1 | # IgnoreActivities 2 | 3 | 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. 4 | 5 | ![](https://github.com/user-attachments/assets/f0c19060-0ecf-4f1c-8165-a5aa40143c82) 6 | 7 | ![](https://github.com/user-attachments/assets/73c3fa7a-5b90-41ee-a4d6-91fa76458b74) 8 | 9 | ![](https://github.com/user-attachments/assets/1ab3fe73-3911-48d1-8a08-e976af614b41) 10 | 11 | The activity stays showing as a detected game even if ignored, differently from the stock Toggle Detection button from Discord: 12 | 13 | ![](https://github.com/user-attachments/assets/08ea60c3-3a31-42de-ae4c-7535fbf1b45a) 14 | -------------------------------------------------------------------------------- /packages/discord-types/enums/activity.ts: -------------------------------------------------------------------------------- 1 | export const enum ActivityType { 2 | PLAYING = 0, 3 | STREAMING = 1, 4 | LISTENING = 2, 5 | WATCHING = 3, 6 | CUSTOM_STATUS = 4, 7 | COMPETING = 5, 8 | HANG_STATUS = 6 9 | } 10 | 11 | export const enum ActivityFlags { 12 | INSTANCE = 1 << 0, 13 | JOIN = 1 << 1, 14 | /** @deprecated */ 15 | SPECTATE = 1 << 2, 16 | /** @deprecated */ 17 | JOIN_REQUEST = 1 << 3, 18 | SYNC = 1 << 4, 19 | PLAY = 1 << 5, 20 | PARTY_PRIVACY_FRIENDS = 1 << 6, 21 | PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7, 22 | EMBEDDED = 1 << 8, 23 | CONTEXTLESS = 1 << 9 24 | } 25 | 26 | export const enum ActivityStatusDisplayType { 27 | NAME = 0, 28 | STATE = 1, 29 | DETAILS = 2 30 | } 31 | -------------------------------------------------------------------------------- /src/plugins/_api/chatButtons.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "ChatInputButtonAPI", 12 | description: "API to add buttons to the chat input", 13 | authors: [Devs.Ven], 14 | 15 | patches: [ 16 | { 17 | find: '"sticker")', 18 | replacement: { 19 | match: /(?<=className:.{0,20}\.buttons.{0,50}children:)(\i)/, 20 | replace: "Vencord.Api.ChatButtons._injectButtons($1,arguments[0])" 21 | } 22 | } 23 | ] 24 | }); 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vencord Fork with nsfwGateBypass Plugin 2 | 3 | A custom Vencord fork including the recently removed nsfwGateBypass plugin. 4 | 5 | ## Requirements 6 | - [Git](https://git-scm.com/downloads/win) 7 | - [Node.js](https://nodejs.org/en/download) 8 | - [PNPM package manager](https://pnpm.io/installation) 9 | 10 | ## Installation 11 | ```bash 12 | git clone https://github.com/kauht/venkord 13 | ``` 14 | 15 | ```bash 16 | cd venkord 17 | ``` 18 | 19 | ```bash 20 | pnpm install 21 | ``` 22 | 23 | ```bash 24 | pnpm build 25 | ``` 26 | OR ``pnpm buildWeb`` if you are building for web 27 | 28 | ```bash 29 | pnpm inject 30 | ``` 31 | 32 | ## Support 33 | For assistance or questions, contact me through my discord server at https://discord.gg/WVMHUgrgeH or add me @kauht. 34 | -------------------------------------------------------------------------------- /packages/discord-types/enums/commands.ts: -------------------------------------------------------------------------------- 1 | export const enum ApplicationCommandOptionType { 2 | SUB_COMMAND = 1, 3 | SUB_COMMAND_GROUP = 2, 4 | STRING = 3, 5 | INTEGER = 4, 6 | BOOLEAN = 5, 7 | USER = 6, 8 | CHANNEL = 7, 9 | ROLE = 8, 10 | MENTIONABLE = 9, 11 | NUMBER = 10, 12 | ATTACHMENT = 11, 13 | } 14 | 15 | export const enum ApplicationCommandInputType { 16 | BUILT_IN = 0, 17 | BUILT_IN_TEXT = 1, 18 | BUILT_IN_INTEGRATION = 2, 19 | BOT = 3, 20 | PLACEHOLDER = 4, 21 | } 22 | 23 | export const enum ApplicationCommandType { 24 | CHAT_INPUT = 1, 25 | USER = 2, 26 | MESSAGE = 3, 27 | } 28 | 29 | export const enum ApplicationIntegrationType { 30 | GUILD_INSTALL = 0, 31 | USER_INSTALL = 1 32 | } 33 | -------------------------------------------------------------------------------- /src/plugins/decor/lib/constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export const BASE_URL = "https://decor.fieryflames.dev"; 8 | export const API_URL = BASE_URL + "/api"; 9 | export const AUTHORIZE_URL = API_URL + "/authorize"; 10 | export const CDN_URL = "https://ugc.decor.fieryflames.dev"; 11 | export const CLIENT_ID = "1096966363416899624"; 12 | export const SKU_ID = "100101099111114"; // decor in ascii numbers 13 | export const RAW_SKU_ID = "11497119"; // raw in ascii numbers 14 | export const GUILD_ID = "1096357702931841148"; 15 | export const INVITE_KEY = "dXp2SdxDcP"; 16 | export const DECORATION_FETCH_COOLDOWN = 1000 * 60 * 60 * 4; // 4 hours 17 | -------------------------------------------------------------------------------- /.github/workflows/codeberg-mirror.yml: -------------------------------------------------------------------------------- 1 | name: Sync to Codeberg 2 | concurrency: 3 | group: ${{ github.ref }} 4 | cancel-in-progress: true 5 | on: 6 | push: 7 | workflow_dispatch: 8 | schedule: 9 | - cron: "0 */6 * * *" 10 | 11 | jobs: 12 | codeberg: 13 | if: github.repository == 'Vendicated/Vencord' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | - uses: pixta-dev/repository-mirroring-action@674e65a7d483ca28dafaacba0d07351bdcc8bd75 # v1.1.1 20 | with: 21 | target_repo_url: "git@codeberg.org:Vee/cord.git" 22 | ssh_private_key: ${{ secrets.CODEBERG_SSH_PRIVATE_KEY }} 23 | -------------------------------------------------------------------------------- /src/components/Grid.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { CSSProperties, JSX } from "react"; 8 | 9 | interface Props { 10 | columns: number; 11 | gap?: string; 12 | inline?: boolean; 13 | } 14 | 15 | export function Grid(props: Props & JSX.IntrinsicElements["div"]) { 16 | const style: CSSProperties = { 17 | display: props.inline ? "inline-grid" : "grid", 18 | gridTemplateColumns: `repeat(${props.columns}, 1fr)`, 19 | gap: props.gap, 20 | ...props.style 21 | }; 22 | 23 | return ( 24 |
25 | {props.children} 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/plugins/stickerPaste/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "StickerPaste", 12 | description: "Makes picking a sticker in the sticker picker insert it into the chatbox instead of instantly sending", 13 | authors: [Devs.ImBanana], 14 | 15 | patches: [ 16 | { 17 | find: ".stickers,previewSticker:", 18 | replacement: { 19 | match: /if\(\i\.\i\.getUploadCount/, 20 | replace: "return true;$&", 21 | } 22 | } 23 | ] 24 | }); 25 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/SelectedChannelStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export class SelectedChannelStore extends FluxStore { 4 | getChannelId(guildId?: string | null): string; 5 | getVoiceChannelId(): string | undefined; 6 | getCurrentlySelectedChannelId(guildId?: string): string | undefined; 7 | getMostRecentSelectedTextChannelId(guildId: string): string | undefined; 8 | getLastSelectedChannelId(guildId?: string): string; 9 | // yes this returns a string 10 | getLastSelectedChannels(guildId?: string): string; 11 | 12 | /** If you follow an announcement channel, this will return whichever channel you chose as destination */ 13 | getLastChannelFollowingDestination(): { guildId?: string; channelId?: string; } | undefined; 14 | } 15 | -------------------------------------------------------------------------------- /src/plugins/noMaskedUrlPaste/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants.js"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "NoMaskedUrlPaste", 12 | authors: [Devs.CatNoir], 13 | description: "Pasting a link while having text selected will not paste as masked URL", 14 | patches: [ 15 | { 16 | find: ".selection,preventEmojiSurrogates:", 17 | replacement: { 18 | match: /if\(null!=\i.selection&&\i.\i.isExpanded\(\i.selection\)\)/, 19 | replace: "if(false)" 20 | } 21 | } 22 | ], 23 | }); 24 | -------------------------------------------------------------------------------- /src/components/settings/tabs/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import "./styles.css"; 8 | 9 | export * from "./BaseTab"; 10 | export { default as PatchHelperTab } from "./patchHelper"; 11 | export { default as PluginsTab } from "./plugins"; 12 | export { openContributorModal } from "./plugins/ContributorModal"; 13 | export { openPluginModal } from "./plugins/PluginModal"; 14 | export { default as BackupAndRestoreTab } from "./sync/BackupAndRestoreTab"; 15 | export { default as CloudTab } from "./sync/CloudTab"; 16 | export { default as ThemesTab } from "./themes"; 17 | export { default as UpdaterTab } from "./updater"; 18 | export { default as VencordTab } from "./vencord"; 19 | -------------------------------------------------------------------------------- /src/plugins/noDeepLinks.web/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "DisableDeepLinks", 12 | description: "Disables Discord's stupid deep linking feature which tries to force you to use their Desktop App", 13 | authors: [Devs.Ven], 14 | required: true, 15 | 16 | noop: () => { }, 17 | 18 | patches: [{ 19 | find: /\.openNativeAppModal\(.{0,50}?\.DEEP_LINK/, 20 | replacement: { 21 | match: /\i\.\i\.openNativeAppModal/, 22 | replace: "$self.noop", 23 | } 24 | }] 25 | }); 26 | -------------------------------------------------------------------------------- /src/components/settings/tabs/plugins/components/styles.css: -------------------------------------------------------------------------------- 1 | .vc-plugins-setting-section { 2 | display: flex; 3 | flex-direction: column; 4 | gap: 0.5em; 5 | } 6 | 7 | .vc-plugins-setting-content { 8 | display: flex; 9 | flex-direction: column; 10 | gap: 0.5em; 11 | } 12 | 13 | .vc-plugins-setting-inline { 14 | flex-direction: row; 15 | align-items: center; 16 | justify-content: space-between; 17 | } 18 | 19 | .vc-plugins-setting-label { 20 | display: flex; 21 | flex-direction: column; 22 | gap: 0.25em; 23 | } 24 | 25 | .vc-plugins-setting-title { 26 | color: var(--header-primary); 27 | } 28 | 29 | .vc-plugins-setting-description { 30 | color: var(--header-secondary); 31 | } 32 | 33 | .vc-plugins-setting-error { 34 | color: var(--text-danger); 35 | } 36 | -------------------------------------------------------------------------------- /scripts/header-old.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) {year} {author} 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | -------------------------------------------------------------------------------- /src/components/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | export * from "./BaseText"; 8 | export * from "./Button"; 9 | export * from "./Card"; 10 | export * from "./CheckedTextInput"; 11 | export * from "./CodeBlock"; 12 | export * from "./Divider"; 13 | export { default as ErrorBoundary } from "./ErrorBoundary"; 14 | export * from "./ErrorCard"; 15 | export * from "./Flex"; 16 | export * from "./FormSwitch"; 17 | export * from "./Grid"; 18 | export * from "./Heading"; 19 | export * from "./Heart"; 20 | export * from "./Icons"; 21 | export * from "./Link"; 22 | export * from "./margins"; 23 | export * from "./Paragraph"; 24 | export * from "./settings"; 25 | export * from "./Span"; 26 | export * from "./Switch"; 27 | -------------------------------------------------------------------------------- /src/plugins/showHiddenThings/README.md: -------------------------------------------------------------------------------- 1 | # ShowHiddenThings 2 | 3 | Displays various hidden & moderator-only things regardless of permissions. 4 | 5 | ## Features 6 | 7 | - Show member timeout icons in chat 8 | ![](https://github.com/Vendicated/Vencord/assets/47677887/75e1f6ba-8921-4188-9c2d-c9c3f9d07101) 9 | 10 | - Show the invites paused tooltip in the server list 11 | ![](https://github.com/Vendicated/Vencord/assets/47677887/b6a923d2-ac55-40d9-b4f8-fa6fc117148b) 12 | 13 | - Show the member mod view context menu item in all servers 14 | 15 | ![](https://github.com/Vendicated/Vencord/assets/47677887/3dac95dd-841c-4c15-ad87-2db7bd1e4dab) 16 | 17 | - Disable filters in Server Discovery search that hide servers that don't meet discovery criteria 18 | 19 | - Disable filters in Server Discovery search that hide NSFW & disallowed servers 20 | -------------------------------------------------------------------------------- /src/plugins/imageLink/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "ImageLink", 12 | description: "Never hide image links in messages, even if it's the only content", 13 | authors: [Devs.Kyuuhachi, Devs.Sqaaakoi], 14 | 15 | patches: [ 16 | { 17 | find: "unknownUserMentionPlaceholder:", 18 | replacement: { 19 | // SimpleEmbedTypes.has(embed.type) && isEmbedInline(embed) 20 | match: /\i\.has\(\i\.type\)&&\(0,\i\.\i\)\(\i\)/, 21 | replace: "false", 22 | } 23 | } 24 | ] 25 | }); 26 | -------------------------------------------------------------------------------- /src/plugins/ircColors/README.md: -------------------------------------------------------------------------------- 1 | # IrcColors 2 | 3 | Makes username colors in chat unique, like in IRC clients 4 | 5 | ![Chat with IrcColors and Compact++ enabled](https://github.com/Vendicated/Vencord/assets/33988779/88e05c0b-a60a-4d10-949e-8b46e1d7226c) 6 | 7 | Improves chat readability by assigning every user an unique nickname color, 8 | making distinguishing between different users easier. Inspired by the feature 9 | in many IRC clients, such as HexChat or WeeChat. 10 | 11 | Keep in mind this overrides role colors in chat, so if you wish to know 12 | someone's role color without checking their profile, enable the role dot: go to 13 | **User Settings**, **Accessibility** and switch **Role Colors** to **Show role 14 | colors next to names**. 15 | 16 | Created for use with the [Compact++](https://gitlab.com/Grzesiek11/compactplusplus-discord-theme) 17 | theme. 18 | -------------------------------------------------------------------------------- /src/plugins/translate/styles.css: -------------------------------------------------------------------------------- 1 | .vc-trans-modal-content { 2 | padding: 1em; 3 | } 4 | 5 | .vc-trans-modal-header { 6 | place-content: center space-between; 7 | } 8 | 9 | .vc-trans-modal-title { 10 | margin: 0; 11 | } 12 | 13 | .vc-trans-accessory { 14 | color: var(--text-muted); 15 | margin-top: 0.5em; 16 | font-style: italic; 17 | font-weight: 400; 18 | line-height: 1.2rem; 19 | white-space: break-spaces; 20 | } 21 | 22 | .vc-trans-accessory-icon { 23 | margin-right: 0.25em; 24 | } 25 | 26 | .vc-trans-dismiss { 27 | all: unset; 28 | cursor: pointer; 29 | color: var(--text-link); 30 | } 31 | 32 | .vc-trans-dismiss:is(:hover, :focus) { 33 | text-decoration: underline; 34 | } 35 | 36 | .vc-trans-auto-translate { 37 | color: var(--green-360); 38 | } 39 | 40 | .vc-trans-chat-button { 41 | scale: 1.085; 42 | } 43 | -------------------------------------------------------------------------------- /src/plugins/_api/dynamicImageModalApi.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | 11 | export default definePlugin({ 12 | name: "DynamicImageModalAPI", 13 | authors: [Devs.sadan, Devs.Nuckyz], 14 | description: "Allows you to omit either width or height when opening an image modal", 15 | patches: [ 16 | { 17 | find: ".dimensionlessImage,", 18 | replacement: { 19 | // widthAndHeightPassed = w != null && w !== 0 && h == null || h === 0 20 | match: /(?<=\i=)(null!=\i&&0!==\i)&&(null!=\i&&0!==\i)/, 21 | replace: "($1)||($2)" 22 | } 23 | } 24 | ] 25 | }); 26 | -------------------------------------------------------------------------------- /src/plugins/sendTimestamps/styles.css: -------------------------------------------------------------------------------- 1 | .vc-st-date-picker { 2 | background-color: var(--input-background); 3 | color: var(--text-default); 4 | width: 95%; 5 | padding: 8px 8px 8px 12px; 6 | margin: 1em 0; 7 | outline: none; 8 | border: 1px solid var(--input-background); 9 | border-radius: 4px; 10 | font-weight: 500; 11 | font-style: inherit; 12 | font-size: 100%; 13 | } 14 | 15 | .vc-st-format-select { 16 | margin-bottom: 1em; 17 | 18 | --border-subtle: transparent; 19 | } 20 | 21 | .vc-st-format-label { 22 | --border-subtle: transparent; 23 | } 24 | 25 | .vc-st-modal-header { 26 | place-content: center space-between; 27 | } 28 | 29 | .vc-st-modal-title { 30 | margin: 0; 31 | } 32 | 33 | .vc-st-modal-close-button { 34 | padding: 0; 35 | } 36 | 37 | .vc-st-preview-text { 38 | margin-bottom: 1em; 39 | } 40 | -------------------------------------------------------------------------------- /src/api/Notifications/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export * from "./Notifications"; 20 | -------------------------------------------------------------------------------- /src/plugins/normalizeMessageLinks/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "NormalizeMessageLinks", 12 | description: "Strip canary/ptb from message links", 13 | authors: [Devs.bb010g], 14 | patches: [ 15 | { 16 | find: "#{intl::COPY_MESSAGE_LINK}", 17 | replacement: { 18 | match: /\.concat\(location\.host\)/, 19 | replace: ".concat($self.normalizeHost(location.host))", 20 | }, 21 | }, 22 | ], 23 | normalizeHost(host: string) { 24 | return host.replace(/(^|\b)(canary\.|ptb\.)(discord.com)$/, "$1$3"); 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /src/utils/localStorage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export const { localStorage } = window; 20 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Our community is welcoming to everyone, regardless of their characteristics. 4 | 5 | As such, we expect you to treat everyone with respect and contribute to an open and welcoming community. 6 | 7 | DO 8 | - have empathy and be nice to others 9 | - be respectful of differing opinions, even if you disagree 10 | - give and accept constructive criticism 11 | 12 | DON'T 13 | - use offensive or derogatory language 14 | - troll or spam 15 | - personally attack or harass others 16 | 17 | Repetitive violations of these guidelines might get your access to the repository restricted. 18 | 19 | If you feel like a user is violating these guidelines or feel treated unfairly, please refrain from vigilantism 20 | and instead report the issue to a moderator! The best way is joining our [official Discord community](https://vencord.dev/discord) 21 | and opening a modmail ticket. 22 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/GuildMember.d.ts: -------------------------------------------------------------------------------- 1 | export interface GuildMember { 2 | avatar: string | undefined; 3 | avatarDecoration: string | undefined; 4 | banner: string | undefined; 5 | bio: string; 6 | colorRoleId: string | undefined; 7 | colorString: string; 8 | colorStrings: { 9 | primaryColor: string | undefined; 10 | secondaryColor: string | undefined; 11 | tertiaryColor: string | undefined; 12 | }; 13 | communicationDisabledUntil: string | undefined; 14 | flags: number; 15 | fullProfileLoadedTimestamp: number; 16 | guildId: string; 17 | highestRoleId: string; 18 | hoistRoleId: string; 19 | iconRoleId: string; 20 | isPending: boolean | undefined; 21 | joinedAt: string | undefined; 22 | nick: string | undefined; 23 | premiumSince: string | undefined; 24 | roles: string[]; 25 | userId: string; 26 | } 27 | -------------------------------------------------------------------------------- /src/plugins/youtubeAdblock.desktop/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { RendererSettings } from "@main/settings"; 8 | import { app } from "electron"; 9 | import adguard from "file://adguard.js?minify"; 10 | 11 | app.on("browser-window-created", (_, win) => { 12 | win.webContents.on("frame-created", (_, { frame }) => { 13 | frame?.once("dom-ready", () => { 14 | if (!RendererSettings.store.plugins?.YoutubeAdblock?.enabled) return; 15 | 16 | if (frame.url.includes("youtube.com/embed/")) { 17 | frame.executeJavaScript(adguard); 18 | } else if (frame.parent?.url.includes("youtube.com/embed/")) { 19 | frame.parent.executeJavaScript(adguard); 20 | } 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /browser/Vencord.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import "./VencordNativeStub"; 20 | 21 | export * from "../src/Vencord"; 22 | -------------------------------------------------------------------------------- /packages/discord-types/src/flux.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from "./stores/FluxStore"; 2 | 3 | export class FluxEmitter { 4 | constructor(); 5 | 6 | changeSentinel: number; 7 | changedStores: Set; 8 | isBatchEmitting: boolean; 9 | isDispatching: boolean; 10 | isPaused: boolean; 11 | pauseTimer: NodeJS.Timeout | null; 12 | reactChangedStores: Set; 13 | 14 | batched(batch: (...args: any[]) => void): void; 15 | destroy(): void; 16 | emit(): void; 17 | emitNonReactOnce(): void; 18 | emitReactOnce(): void; 19 | getChangeSentinel(): number; 20 | getIsPaused(): boolean; 21 | injectBatchEmitChanges(batch: (...args: any[]) => void): void; 22 | markChanged(store: FluxStore): void; 23 | pause(): void; 24 | resume(): void; 25 | } 26 | 27 | export interface Flux { 28 | Store: typeof FluxStore; 29 | Emitter: FluxEmitter; 30 | } 31 | -------------------------------------------------------------------------------- /src/plugins/imageZoom/constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export const ELEMENT_ID = "vc-imgzoom-magnify-modal"; 20 | -------------------------------------------------------------------------------- /src/plugins/voiceMessages/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { app } from "electron"; 8 | import { readFile } from "fs/promises"; 9 | import { basename, normalize } from "path"; 10 | 11 | export async function readRecording(_, filePath: string) { 12 | filePath = normalize(filePath); 13 | const filename = basename(filePath); 14 | const discordBaseDirWithTrailingSlash = normalize(app.getPath("userData") + "/"); 15 | console.log(filename, discordBaseDirWithTrailingSlash, filePath); 16 | if (filename !== "recording.ogg" || !filePath.startsWith(discordBaseDirWithTrailingSlash)) return null; 17 | 18 | try { 19 | const buf = await readFile(filePath); 20 | return new Uint8Array(buf.buffer); 21 | } catch { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/RelationshipStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export class RelationshipStore extends FluxStore { 4 | getFriendIDs(): string[]; 5 | getIgnoredIDs(): string[]; 6 | getBlockedIDs(): string[]; 7 | 8 | getPendingCount(): number; 9 | getRelationshipCount(): number; 10 | 11 | /** Related to friend nicknames. */ 12 | getNickname(userId: string): string; 13 | /** @returns Enum value from constants.RelationshipTypes */ 14 | getRelationshipType(userId: string): number; 15 | isFriend(userId: string): boolean; 16 | isBlocked(userId: string): boolean; 17 | isIgnored(userId: string): boolean; 18 | /** 19 | * @see {@link isBlocked} 20 | * @see {@link isIgnored} 21 | */ 22 | isBlockedOrIgnored(userId: string): boolean; 23 | getSince(userId: string): string; 24 | 25 | getMutableRelationships(): Map; 26 | } 27 | -------------------------------------------------------------------------------- /src/components/settings/tabs/vencord/DonateButton.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import DonateButton from "@components/settings/DonateButton"; 8 | import BadgeAPI from "@plugins/_api/badges"; 9 | import { DONOR_ROLE_ID, VENCORD_GUILD_ID } from "@utils/constants"; 10 | import { Button, GuildMemberStore } from "@webpack/common"; 11 | 12 | export const isDonor = (userId: string) => !!( 13 | BadgeAPI.getDonorBadges(userId)?.length > 0 14 | || GuildMemberStore?.getMember(VENCORD_GUILD_ID, userId)?.roles.includes(DONOR_ROLE_ID) 15 | ); 16 | 17 | export function DonateButtonComponent() { 18 | return ( 19 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/updater/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | if (!IS_UPDATER_DISABLED) 20 | require(IS_STANDALONE ? "./http" : "./git"); 21 | -------------------------------------------------------------------------------- /src/plugins/userVoiceShow/style.css: -------------------------------------------------------------------------------- 1 | .vc-uvs-speaker { 2 | color: var(--interactive-normal); 3 | display: flex; 4 | align-items: center; 5 | justify-content: center; 6 | } 7 | 8 | .vc-uvs-clickable { 9 | cursor: pointer; 10 | } 11 | 12 | .vc-uvs-clickable:hover { 13 | color: var(--interactive-hover); 14 | } 15 | 16 | .vc-uvs-profile-speaker { 17 | width: var(--custom-nickname-icon-size); 18 | height: var(--custom-nickname-icon-size); 19 | } 20 | 21 | .vc-uvs-tooltip-container { 22 | max-width: 50vw; 23 | } 24 | 25 | .vc-uvs-tooltip-content { 26 | display: flex; 27 | flex-direction: column; 28 | gap: 6px; 29 | } 30 | 31 | .vc-uvs-name { 32 | display: flex; 33 | align-items: center; 34 | gap: 8px; 35 | } 36 | 37 | .vc-uvs-guild-icon { 38 | border-radius: 100%; 39 | align-self: center; 40 | } 41 | 42 | .vc-uvs-vc-members { 43 | display: flex; 44 | gap: 6px; 45 | } -------------------------------------------------------------------------------- /src/webpack/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export * as Common from "./common"; 20 | export * from "./types"; 21 | export * from "./webpack"; 22 | -------------------------------------------------------------------------------- /src/utils/margins.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | // TODO: Migrate all usages from utils to components 20 | export { Margins } from "@components/margins"; 21 | -------------------------------------------------------------------------------- /src/plugins/pinDms/styles.css: -------------------------------------------------------------------------------- 1 | .vc-pindms-section-container { 2 | box-sizing: border-box; 3 | text-overflow: ellipsis; 4 | white-space: nowrap; 5 | overflow: hidden; 6 | text-transform: uppercase; 7 | font-size: 12px; 8 | line-height: 16px; 9 | letter-spacing: .02em; 10 | font-family: var(--font-display); 11 | font-weight: 600; 12 | flex: 1 1 auto; 13 | color: var(--channels-default); 14 | cursor: pointer; 15 | } 16 | 17 | .vc-pindms-modal-content { 18 | display: grid; 19 | justify-content: center; 20 | padding: 1rem; 21 | gap: 1.5rem; 22 | } 23 | 24 | .vc-pindms-modal-content [class^="defaultContainer"] { 25 | display: none; 26 | } 27 | 28 | .vc-pindms-collapse-icon { 29 | width: 16px; 30 | height: 16px; 31 | color: var(--interactive-normal); 32 | transform: rotate(90deg) 33 | } 34 | 35 | .vc-pindms-collapsed .vc-pindms-collapse-icon { 36 | transform: rotate(0deg); 37 | } 38 | -------------------------------------------------------------------------------- /src/plugins/decor/ui/components/Grid.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { cl } from "@plugins/decor/ui"; 8 | import { React } from "@webpack/common"; 9 | import { JSX } from "react"; 10 | 11 | export interface GridProps { 12 | renderItem: (item: ItemT) => JSX.Element; 13 | getItemKey: (item: ItemT) => string; 14 | itemKeyPrefix?: string; 15 | items: Array; 16 | } 17 | 18 | export default function Grid({ renderItem, getItemKey, itemKeyPrefix: ikp, items }: GridProps) { 19 | return
20 | {items.map(item => 21 | 24 | {renderItem(item)} 25 | 26 | )} 27 |
; 28 | } 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | push: 4 | pull_request: 5 | branches: 6 | - main 7 | - dev 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: pnpm/action-setup@v3 # Install pnpm using packageManager key in package.json 15 | 16 | - name: Use Node.js 20 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: 20 20 | cache: "pnpm" 21 | 22 | - name: Install dependencies 23 | run: pnpm install --frozen-lockfile 24 | 25 | - name: Lint & Test if desktop version compiles 26 | run: pnpm test 27 | 28 | - name: Test if web version compiles 29 | run: pnpm buildWeb 30 | 31 | - name: Test if plugin structure is valid 32 | run: pnpm generatePluginJson 33 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/messages/Sticker.d.ts: -------------------------------------------------------------------------------- 1 | import { StickerFormatType, StickerType } from "../../../enums"; 2 | 3 | interface BaseSticker { 4 | asset: string; 5 | available: boolean; 6 | description: string; 7 | format_type: StickerFormatType; 8 | id: string; 9 | name: string; 10 | sort_value?: number; 11 | /** a comma separated string */ 12 | tags: string; 13 | } 14 | 15 | export interface PackSticker extends BaseSticker { 16 | pack_id: string; 17 | type: StickerType.STANDARD; 18 | } 19 | 20 | export interface GuildSticker extends BaseSticker { 21 | guild_id: string; 22 | type: StickerType.GUILD; 23 | } 24 | 25 | export type Sticker = PackSticker | GuildSticker; 26 | 27 | export interface PremiumStickerPack { 28 | banner_asset_id?: string; 29 | cover_sticker_id?: string; 30 | description: string; 31 | id: string; 32 | name: string; 33 | sku_id: string; 34 | stickers: PackSticker[]; 35 | } 36 | -------------------------------------------------------------------------------- /src/plugins/decor/README.md: -------------------------------------------------------------------------------- 1 | # Decor 2 | 3 | Custom avatar decorations! 4 | 5 | ![Custom decorations in chat](https://github.com/Vendicated/Vencord/assets/30497388/b0c4c4c8-8723-42a8-b50f-195ad4e26136) 6 | 7 | Create and use your own custom avatar decorations, or pick your favorite from the presets. 8 | 9 | You'll be able to see the custom avatar decorations of other users of this plugin, and they'll be able to see your custom avatar decoration. 10 | 11 | You can select and manage your custom avatar decorations under the "Profiles" page in settings, or in the plugin settings. 12 | 13 | ![Custom decorations management](https://github.com/Vendicated/Vencord/assets/30497388/74fe8a9e-a2a2-4b29-bc10-9eaa58208ad4) 14 | 15 | Review the [guidelines](https://github.com/decor-discord/.github/blob/main/GUIDELINES.md) before creating your own custom avatar decoration. 16 | 17 | Join the [Discord server](https://discord.gg/dXp2SdxDcP) for support and notifications on your decoration's review. 18 | -------------------------------------------------------------------------------- /src/plugins/decor/ui/components/DecorationGridCreate.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { PlusIcon } from "@components/Icons"; 8 | import { getIntlMessage } from "@utils/discord"; 9 | import { Text } from "@webpack/common"; 10 | import { HTMLProps } from "react"; 11 | 12 | import { DecorationGridItem } from "."; 13 | 14 | type DecorationGridCreateProps = HTMLProps & { 15 | onSelect: () => void; 16 | }; 17 | 18 | export default function DecorationGridCreate(props: DecorationGridCreateProps) { 19 | return 23 | 24 | 28 | {getIntlMessage("CREATE")} 29 | 30 | ; 31 | } 32 | -------------------------------------------------------------------------------- /src/plugins/decor/ui/components/DecorationGridNone.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { NoEntrySignIcon } from "@components/Icons"; 8 | import { getIntlMessage } from "@utils/discord"; 9 | import { Text } from "@webpack/common"; 10 | import { HTMLProps } from "react"; 11 | 12 | import { DecorationGridItem } from "."; 13 | 14 | type DecorationGridNoneProps = HTMLProps & { 15 | isSelected: boolean; 16 | onSelect: () => void; 17 | }; 18 | 19 | export default function DecorationGridNone(props: DecorationGridNoneProps) { 20 | return 23 | 24 | 28 | {getIntlMessage("NONE")} 29 | 30 | ; 31 | } 32 | -------------------------------------------------------------------------------- /src/plugins/translate/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { IpcMainInvokeEvent } from "electron"; 8 | 9 | export async function makeDeeplTranslateRequest(_: IpcMainInvokeEvent, pro: boolean, apiKey: string, payload: string) { 10 | const url = pro 11 | ? "https://api.deepl.com/v2/translate" 12 | : "https://api-free.deepl.com/v2/translate"; 13 | 14 | try { 15 | const res = await fetch(url, { 16 | method: "POST", 17 | headers: { 18 | "Content-Type": "application/json", 19 | "Authorization": `DeepL-Auth-Key ${apiKey}` 20 | }, 21 | body: payload 22 | }); 23 | 24 | const data = await res.text(); 25 | return { status: res.status, data }; 26 | } catch (e) { 27 | return { status: -1, data: String(e) }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/Role.d.ts: -------------------------------------------------------------------------------- 1 | export interface Role { 2 | color: number; 3 | colorString: string | undefined; 4 | colorStrings: { 5 | primaryColor: string | undefined; 6 | secondaryColor: string | undefined; 7 | tertiaryColor: string | undefined; 8 | }; 9 | colors: { 10 | primary_color: number | undefined; 11 | secondary_color: number | undefined; 12 | tertiary_color: number | undefined; 13 | }; 14 | flags: number; 15 | hoist: boolean; 16 | icon: string | undefined; 17 | id: string; 18 | managed: boolean; 19 | mentionable: boolean; 20 | name: string; 21 | originalPosition: number; 22 | permissions: bigint; 23 | position: number; 24 | /** 25 | * probably incomplete 26 | */ 27 | tags: { 28 | bot_id: string; 29 | integration_id: string; 30 | premium_subscriber: unknown; 31 | } | undefined; 32 | unicodeEmoji: string | undefined; 33 | } 34 | -------------------------------------------------------------------------------- /packages/vencord-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vencord/types", 3 | "private": false, 4 | "version": "1.13.2", 5 | "description": "", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "prepublishOnly": "tsx ./prepare.ts", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "Vencord", 13 | "license": "GPL-3.0", 14 | "devDependencies": { 15 | "@types/fs-extra": "^11.0.4", 16 | "fs-extra": "^11.3.0", 17 | "tsx": "^4.19.2" 18 | }, 19 | "dependencies": { 20 | "@types/lodash": "4.17.15", 21 | "@types/node": "^22.13.4", 22 | "@vencord/discord-types": "^1.0.0", 23 | "highlight.js": "11.11.1", 24 | "moment": "^2.22.2", 25 | "ts-pattern": "^5.6.0", 26 | "type-fest": "^4.35.0" 27 | }, 28 | "peerDependencies": { 29 | "@types/react": "18.3.1", 30 | "@types/react-dom": "18.3.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/plugins/fixSpotifyEmbeds.desktop/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { definePluginSettings } from "@api/Settings"; 8 | import { Devs } from "@utils/constants"; 9 | import definePlugin, { makeRange, OptionType } from "@utils/types"; 10 | 11 | // The entire code of this plugin can be found in ipcPlugins 12 | export default definePlugin({ 13 | name: "FixSpotifyEmbeds", 14 | description: "Fixes spotify embeds being incredibly loud by letting you customise the volume", 15 | authors: [Devs.Ven], 16 | settings: definePluginSettings({ 17 | volume: { 18 | type: OptionType.SLIDER, 19 | description: "The volume % to set for spotify embeds. Anything above 10% is veeeery loud", 20 | markers: makeRange(0, 100, 10), 21 | stickToMarkers: false, 22 | default: 10 23 | } 24 | }) 25 | }); 26 | -------------------------------------------------------------------------------- /src/plugins/spotifyControls/SeekBar.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { LazyComponent } from "@utils/lazyReact"; 8 | import { Slider } from "@webpack/common"; 9 | 10 | export const SeekBar = LazyComponent(() => { 11 | const SliderClass = Slider.$$vencordGetWrappedComponent(); 12 | 13 | // Discord's Slider does not update `state.value` when `props.initialValue` changes if state.value is not nullish. 14 | // We extend their class and override their `getDerivedStateFromProps` to update the value 15 | return class SeekBar extends SliderClass { 16 | static getDerivedStateFromProps(props: any, state: any) { 17 | const newState = super.getDerivedStateFromProps!(props, state); 18 | if (newState) { 19 | newState.value = props.initialValue; 20 | } 21 | 22 | return newState; 23 | } 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /src/plugins/imageZoom/utils/waitFor.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export function waitFor(condition: () => boolean, cb: () => void) { 20 | if (condition()) cb(); 21 | else requestAnimationFrame(() => waitFor(condition, cb)); 22 | } 23 | -------------------------------------------------------------------------------- /packages/vencord-types/globals.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | declare global { 20 | export var VencordNative: typeof import("./VencordNative").default; 21 | export var Vencord: typeof import("./Vencord"); 22 | } 23 | 24 | export { }; 25 | -------------------------------------------------------------------------------- /scripts/checkNodeVersion.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | if (Number(process.versions.node.split(".")[0]) < 18) 20 | throw `Your node version (${process.version}) is too old, please update to v18 or higher https://nodejs.org/en/download/`; 21 | -------------------------------------------------------------------------------- /src/plugins/openInApp/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { IpcMainInvokeEvent } from "electron"; 8 | import { request } from "https"; 9 | 10 | // These links don't support CORS, so this has to be native 11 | const validRedirectUrls = /^https:\/\/(spotify\.link|s\.team)\/.+$/; 12 | 13 | function getRedirect(url: string) { 14 | return new Promise((resolve, reject) => { 15 | const req = request(new URL(url), { method: "HEAD" }, res => { 16 | resolve( 17 | res.headers.location 18 | ? getRedirect(res.headers.location) 19 | : url 20 | ); 21 | }); 22 | req.on("error", reject); 23 | req.end(); 24 | }); 25 | } 26 | 27 | export async function resolveRedirect(_: IpcMainInvokeEvent, url: string) { 28 | if (!validRedirectUrls.test(url)) return url; 29 | 30 | return getRedirect(url); 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/blank.yml: -------------------------------------------------------------------------------- 1 | name: Blank Issue 2 | description: Create a blank issue. ALWAYS FIRST USE OUR SUPPORT CHANNEL! ONLY USE THIS FORM IF YOU ARE A CONTRIBUTOR OR WERE TOLD TO DO SO IN THE SUPPORT CHANNEL. 3 | 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true) 9 | 10 | GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer. 11 | 12 | - type: textarea 13 | id: content 14 | attributes: 15 | label: Content 16 | validations: 17 | required: true 18 | 19 | - type: checkboxes 20 | id: agreement-check 21 | attributes: 22 | label: Request Agreement 23 | options: 24 | - label: I have read the requirements for opening an issue above 25 | required: true 26 | -------------------------------------------------------------------------------- /scripts/build/module/style.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | (window.VencordStyles ??= new Map()).set(STYLE_NAME, { 20 | name: STYLE_NAME, 21 | source: STYLE_SOURCE, 22 | classNames: {}, 23 | dom: null, 24 | }); 25 | 26 | export default STYLE_NAME; 27 | -------------------------------------------------------------------------------- /scripts/build/inject/react.mjs: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export const VencordFragment = /* #__PURE__*/ Symbol.for("react.fragment"); 20 | export let VencordCreateElement = 21 | (...args) => (VencordCreateElement = Vencord.Webpack.Common.React.createElement)(...args); 22 | -------------------------------------------------------------------------------- /src/webpack/common/classes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import * as t from "@vencord/discord-types"; 20 | import { findByPropsLazy } from "@webpack"; 21 | 22 | export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent"); 23 | -------------------------------------------------------------------------------- /src/webpack/common/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export * from "./classes"; 20 | export * from "./components"; 21 | export * from "./menu"; 22 | export * from "./react"; 23 | export * from "./stores"; 24 | export * from "./userSettings"; 25 | export * from "./utils"; 26 | -------------------------------------------------------------------------------- /src/plugins/voiceMessages/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { classNameFactory } from "@api/Styles"; 20 | import { findStoreLazy } from "@webpack"; 21 | 22 | export const MediaEngineStore = findStoreLazy("MediaEngineStore"); 23 | export const cl = classNameFactory("vc-vmsg-"); 24 | -------------------------------------------------------------------------------- /src/utils/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export function relaunch() { 20 | if (IS_DISCORD_DESKTOP) 21 | window.DiscordNative.app.relaunch(); 22 | else if (IS_VESKTOP) 23 | window.VesktopNative.app.relaunch(); 24 | else 25 | location.reload(); 26 | } 27 | -------------------------------------------------------------------------------- /src/plugins/messageLatency/README.md: -------------------------------------------------------------------------------- 1 | # MessageLatency 2 | 3 | Displays an indicator for messages that took ≥n seconds to send. 4 | 5 | > **NOTE** 6 | > 7 | > - This plugin only applies to messages received after opening the channel 8 | > - False positives can exist if the user's system clock has drifted. 9 | > - Grouped messages only display latency of the first message 10 | 11 | ## Demo 12 | 13 | ### Chat View 14 | 15 | ![chat-view](https://github.com/Vendicated/Vencord/assets/82430093/69430881-60b3-422f-aa3d-c62953837566) 16 | 17 | ### Clock -ve Drift 18 | 19 | ![pissbot-on-top](https://github.com/Vendicated/Vencord/assets/82430093/d9248b66-e761-4872-8829-e8bf4fea6ec8) 20 | 21 | ### Clock +ve Drift 22 | 23 | ![dumb-ai](https://github.com/Vendicated/Vencord/assets/82430093/0e9783cf-51d5-4559-ae10-42399e7d4099) 24 | 25 | ### Connection Delay 26 | 27 | ![who-this](https://github.com/Vendicated/Vencord/assets/82430093/fd68873d-8630-42cc-a166-e9063d2718b2) 28 | 29 | ### Icons 30 | 31 | ![icons](https://github.com/Vendicated/Vencord/assets/82430093/17630bd9-44ee-4967-bcdf-3315eb6eca85) 32 | -------------------------------------------------------------------------------- /scripts/suppressExperimentalWarnings.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | process.emit = (originalEmit => function (name, data) { 20 | if (name === "warning" && data?.name === "ExperimentalWarning") 21 | return false; 22 | 23 | return originalEmit.apply(process, arguments); 24 | })(process.emit); 25 | -------------------------------------------------------------------------------- /src/utils/guards.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export function isTruthy(item: T): item is Exclude { 20 | return Boolean(item); 21 | } 22 | 23 | export function isNonNullish(item: T): item is Exclude { 24 | return item != null; 25 | } 26 | -------------------------------------------------------------------------------- /src/plugins/betterSessions/components/RenameButton.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Button } from "@components/Button"; 8 | import { SessionInfo } from "@plugins/betterSessions/types"; 9 | import { openModal } from "@utils/modal"; 10 | 11 | import { RenameModal } from "./RenameModal"; 12 | 13 | export function RenameButton({ session, state }: { session: SessionInfo["session"], state: [string, React.Dispatch>]; }) { 14 | return ( 15 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/plugins/fixYoutubeEmbeds.desktop/native.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { RendererSettings } from "@main/settings"; 8 | import { app } from "electron"; 9 | 10 | app.on("browser-window-created", (_, win) => { 11 | win.webContents.on("frame-created", (_, { frame }) => { 12 | frame?.once("dom-ready", () => { 13 | if (frame.url.startsWith("https://www.youtube.com/")) { 14 | const settings = RendererSettings.store.plugins?.FixYoutubeEmbeds; 15 | if (!settings?.enabled) return; 16 | 17 | frame.executeJavaScript(` 18 | new MutationObserver(() => { 19 | if( 20 | document.querySelector('div.ytp-error-content-wrap-subreason a[href*="www.youtube.com/watch?v="]') 21 | ) location.reload() 22 | }).observe(document.body, { childList: true, subtree:true }); 23 | `); 24 | } 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/plugins/unlockedAvatarZoom/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { definePluginSettings } from "@api/Settings"; 8 | import { Devs } from "@utils/constants"; 9 | import definePlugin, { makeRange, OptionType } from "@utils/types"; 10 | 11 | const settings = definePluginSettings({ 12 | zoomMultiplier: { 13 | type: OptionType.SLIDER, 14 | description: "Zoom multiplier", 15 | markers: makeRange(2, 16), 16 | default: 4, 17 | }, 18 | }); 19 | 20 | export default definePlugin({ 21 | name: "UnlockedAvatarZoom", 22 | description: "Allows you to zoom in further in the image crop tool when changing your avatar", 23 | authors: [Devs.nakoyasha], 24 | settings, 25 | patches: [ 26 | { 27 | find: "#{intl::AVATAR_UPLOAD_EDIT_MEDIA}", 28 | replacement: { 29 | match: /maxValue:\d/, 30 | replace: "maxValue:$self.settings.store.zoomMultiplier", 31 | } 32 | } 33 | ] 34 | }); 35 | -------------------------------------------------------------------------------- /browser/monacoWin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vencord QuickCSS Editor 6 | 20 | 21 | 22 | 23 |
24 | 25 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/components/settings/QuickAction.css: -------------------------------------------------------------------------------- 1 | .vc-settings-quickActions-card { 2 | display: grid; 3 | grid-template-columns: repeat(3, 1fr); 4 | gap: 0.5em; 5 | padding: 0.5em; 6 | margin-bottom: 1em; 7 | } 8 | 9 | @media (width <=1040px) { 10 | .vc-settings-quickActions-card { 11 | grid-template-columns: repeat(2, 1fr); 12 | } 13 | } 14 | 15 | .vc-settings-quickActions-pill { 16 | all: unset; 17 | background: var(--button-secondary-background); 18 | color: var(--header-secondary); 19 | display: flex; 20 | align-items: center; 21 | gap: 0.5em; 22 | padding: 8px 9px; 23 | border-radius: 8px; 24 | transition: 0.1s ease-out; 25 | box-sizing: border-box; 26 | } 27 | 28 | .vc-settings-quickActions-pill:hover { 29 | background: var(--button-secondary-background-hover); 30 | transform: translateY(-1px); 31 | box-shadow: var(--elevation-high); 32 | } 33 | 34 | .vc-settings-quickActions-pill:focus-visible { 35 | outline: 2px solid var(--focus-primary); 36 | outline-offset: 2px; 37 | } 38 | 39 | .vc-settings-quickActions-img { 40 | width: 24px; 41 | height: 24px; 42 | } -------------------------------------------------------------------------------- /packages/discord-types/src/stores/ChannelStore.d.ts: -------------------------------------------------------------------------------- 1 | import { Channel, FluxStore } from ".."; 2 | 3 | export class ChannelStore extends FluxStore { 4 | getChannel(channelId: string): Channel; 5 | getBasicChannel(channelId: string): Channel | undefined; 6 | hasChannel(channelId: string): boolean; 7 | 8 | getChannelIds(guildId?: string | null): string[]; 9 | getMutableBasicGuildChannelsForGuild(guildId: string): Record; 10 | getMutableGuildChannelsForGuild(guildId: string): Record; 11 | getAllThreadsForGuild(guildId: string): Channel[]; 12 | getAllThreadsForParent(channelId: string): Channel[]; 13 | 14 | getDMFromUserId(userId: string): string; 15 | getDMChannelFromUserId(userId: string): Channel | undefined; 16 | getDMUserIds(): string[]; 17 | getMutableDMsByUserIds(): Record; 18 | getMutablePrivateChannels(): Record; 19 | getSortedPrivateChannels(): Channel[]; 20 | 21 | getGuildChannelsVersion(guildId: string): number; 22 | getPrivateChannelsVersion(): number; 23 | getInitialOverlayState(): Record; 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/cspViolations.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { useLayoutEffect } from "@webpack/common"; 8 | 9 | import { useForceUpdater } from "./react"; 10 | 11 | const cssRelevantDirectives = ["style-src", "style-src-elem", "img-src", "font-src"] as const; 12 | 13 | export const CspBlockedUrls = new Set(); 14 | const CspErrorListeners = new Set<() => void>(); 15 | 16 | document.addEventListener("securitypolicyviolation", ({ effectiveDirective, blockedURI }) => { 17 | if (!blockedURI || !cssRelevantDirectives.includes(effectiveDirective as any)) return; 18 | 19 | CspBlockedUrls.add(blockedURI); 20 | 21 | CspErrorListeners.forEach(listener => listener()); 22 | }); 23 | 24 | export function useCspErrors() { 25 | const forceUpdate = useForceUpdater(); 26 | 27 | useLayoutEffect(() => { 28 | CspErrorListeners.add(forceUpdate); 29 | 30 | return () => void CspErrorListeners.delete(forceUpdate); 31 | }, [forceUpdate]); 32 | 33 | return [...CspBlockedUrls] as const; 34 | } 35 | -------------------------------------------------------------------------------- /browser/modifyResponseHeaders.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "action": { 5 | "type": "modifyHeaders", 6 | "responseHeaders": [ 7 | { 8 | "header": "content-security-policy", 9 | "operation": "remove" 10 | }, 11 | { 12 | "header": "content-security-policy-report-only", 13 | "operation": "remove" 14 | } 15 | ] 16 | }, 17 | "condition": { 18 | "resourceTypes": ["main_frame", "sub_frame"] 19 | } 20 | }, 21 | { 22 | "id": 2, 23 | "action": { 24 | "type": "modifyHeaders", 25 | "responseHeaders": [ 26 | { 27 | "header": "content-type", 28 | "operation": "set", 29 | "value": "text/css" 30 | } 31 | ] 32 | }, 33 | "condition": { 34 | "resourceTypes": ["stylesheet"], 35 | "urlFilter": "https://raw.githubusercontent.com/*" 36 | } 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /src/components/Heading.css: -------------------------------------------------------------------------------- 1 | .vc-h1, 2 | .vc-h2 { 3 | color: var(--header-primary); 4 | font-weight: 600; 5 | } 6 | 7 | .vc-h3, 8 | .vc-h4, 9 | .vc-h5 { 10 | color: var(--header-secondary); 11 | } 12 | 13 | .vc-h1 { 14 | font-size: 20px; 15 | line-height: 24px 16 | } 17 | 18 | .vc-h2 { 19 | font-size: 16px; 20 | line-height: 20px 21 | } 22 | 23 | .vc-h3 { 24 | font-weight: 500; 25 | line-height: 24px 26 | } 27 | 28 | .vc-h3, 29 | .vc-h4 { 30 | font-size: 16px 31 | } 32 | 33 | .vc-h4 { 34 | font-weight: 600; 35 | letter-spacing: .3px 36 | } 37 | 38 | .vc-h4, 39 | .vc-h5 { 40 | line-height: 20px 41 | } 42 | 43 | .vc-h5 { 44 | color: var(--header-primary); 45 | font-size: 16px; 46 | font-weight: 500; 47 | margin-bottom: 8px; 48 | text-transform: unset 49 | } 50 | 51 | .vc-h1-defaultMargin, 52 | .vc-h2-defaultMargin { 53 | margin-bottom: 20px 54 | } 55 | 56 | /* This is copied from Discord, don't ask me why 0 margin */ 57 | .vc-h4-defaultMargin { 58 | margin-bottom: 0; 59 | margin-top: 0; 60 | } 61 | 62 | .vc-h3-defaultMargin, 63 | .vc-h5-defaultMargin { 64 | margin-bottom: 8px 65 | } -------------------------------------------------------------------------------- /src/utils/lazyReact.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import type { ComponentType } from "react"; 8 | 9 | import { makeLazy } from "./lazy"; 10 | 11 | const NoopComponent = () => null; 12 | 13 | export type LazyComponentWrapper = ComponentType & { $$vencordGetWrappedComponent(): ComponentType; }; 14 | 15 | /** 16 | * A lazy component. The factory method is called on first render. 17 | * @param factory Function returning a Component 18 | * @param attempts How many times to try to get the component before giving up 19 | * @returns Result of factory function 20 | */ 21 | export function LazyComponent(factory: () => ComponentType, attempts = 5): LazyComponentWrapper> { 22 | const get = makeLazy(factory, attempts); 23 | const LazyComponent = (props: T) => { 24 | const Component = get() ?? NoopComponent; 25 | return ; 26 | }; 27 | 28 | LazyComponent.$$vencordGetWrappedComponent = get; 29 | 30 | return LazyComponent; 31 | } 32 | -------------------------------------------------------------------------------- /src/components/settings/PluginBadge.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export function AddonBadge({ text, color }) { 20 | return ( 21 |
26 | {text} 27 |
28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /src/utils/onlyOnce.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export function onlyOnce(f: F): F { 20 | let called = false; 21 | let result: any; 22 | return function onlyOnceWrapper(this: unknown) { 23 | if (called) return result; 24 | 25 | called = true; 26 | 27 | return (result = f.apply(this, arguments)); 28 | } as unknown as F; 29 | } 30 | -------------------------------------------------------------------------------- /src/components/settings/tabs/plugins/components/ComponentSetting.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { PluginOptionComponent } from "@utils/types"; 20 | 21 | import { ComponentSettingProps } from "./Common"; 22 | 23 | export function ComponentSetting({ option, onChange }: ComponentSettingProps) { 24 | return option.component({ setValue: onChange, option }); 25 | } 26 | -------------------------------------------------------------------------------- /src/plugins/notificationVolume/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { definePluginSettings } from "@api/Settings"; 8 | import { Devs } from "@utils/constants"; 9 | import definePlugin, { OptionType } from "@utils/types"; 10 | 11 | const settings = definePluginSettings({ 12 | notificationVolume: { 13 | type: OptionType.SLIDER, 14 | description: "Notification volume", 15 | markers: [0, 25, 50, 75, 100], 16 | default: 100, 17 | stickToMarkers: false 18 | } 19 | }); 20 | 21 | export default definePlugin({ 22 | name: "NotificationVolume", 23 | description: "Save your ears and set a separate volume for notifications and in-app sounds", 24 | authors: [Devs.philipbry], 25 | settings, 26 | patches: [ 27 | { 28 | find: "ensureAudio(){", 29 | replacement: { 30 | match: /(?=Math\.min\(\i\.\i\.getOutputVolume\(\)\/100)/g, 31 | replace: "$self.settings.store.notificationVolume/100*" 32 | }, 33 | }, 34 | ], 35 | }); 36 | -------------------------------------------------------------------------------- /src/plugins/themeAttributes/README.md: -------------------------------------------------------------------------------- 1 | # ThemeAttributes 2 | 3 | This plugin adds data attributes and CSS variables to various elements inside Discord 4 | 5 | This allows themes to more easily theme those elements or even do things that otherwise wouldn't be possible 6 | 7 | ## Available Attributes 8 | 9 | ### All Tab Bars (User Settings, Server Settings, etc) 10 | 11 | `data-tab-id` contains the id of that tab 12 | 13 | ![image](https://github.com/Vendicated/Vencord/assets/45497981/1263b782-f673-4f09-820c-4cc366d062ad) 14 | 15 | ### Chat Messages 16 | 17 | - `data-author-id` contains the id of the author 18 | - `data-author-username` contains the username of the author 19 | - `data-is-self` is a boolean indicating whether this is the current user's message 20 | 21 | ![image](https://github.com/Vendicated/Vencord/assets/45497981/34bd5053-3381-402f-82b2-9c812cc7e122) 22 | 23 | ## CSS Variables 24 | 25 | ### Avatars 26 | 27 | `--avatar-url-` contains a URL for the users avatar with the size attribute adjusted for the resolutions `128, 256, 512, 1024, 2048, 4096`. 28 | 29 | ![image](https://github.com/Vendicated/Vencord/assets/26598490/192ddac0-c827-472f-9933-fa99ff36f723) 30 | -------------------------------------------------------------------------------- /src/components/handleComponentFailed.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { maybePromptToUpdate } from "@utils/updater"; 20 | 21 | export function handleComponentFailed() { 22 | maybePromptToUpdate( 23 | "Uh Oh! Failed to render this Page." + 24 | " However, there is an update available that might fix it." + 25 | " Would you like to update and restart now?" 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /src/components/settings/QuickAction.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import "./QuickAction.css"; 8 | 9 | import { classNameFactory } from "@api/Styles"; 10 | import { Card } from "@components/Card"; 11 | import type { ComponentType, PropsWithChildren, ReactNode } from "react"; 12 | 13 | const cl = classNameFactory("vc-settings-quickActions-"); 14 | 15 | export interface QuickActionProps { 16 | Icon: ComponentType<{ className?: string; }>; 17 | text: ReactNode; 18 | action?: () => void; 19 | disabled?: boolean; 20 | } 21 | 22 | export function QuickAction(props: QuickActionProps) { 23 | const { Icon, action, text, disabled } = props; 24 | 25 | return ( 26 | 30 | ); 31 | } 32 | 33 | export function QuickActionCard(props: PropsWithChildren) { 34 | return ( 35 | 36 | {props.children} 37 | 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/plugins/messageLogger/messageLogger.css: -------------------------------------------------------------------------------- 1 | .messagelogger-deleted [class^="buttons"] { 2 | display: none; 3 | } 4 | 5 | .messagelogger-deleted 6 | :is( 7 | .messagelogger-deleted-attachment, 8 | .emoji, 9 | [data-type="sticker"], 10 | [class*="embedIframe"], 11 | [class*="embedSpotify"], 12 | [class*="imageContainer"] 13 | ) { 14 | filter: grayscale(1) !important; 15 | transition: 150ms filter ease-in-out; 16 | 17 | &[class*="hiddenMosaicItem_"] { 18 | filter: grayscale(1) blur(var(--custom-message-attachment-spoiler-blur-radius, 44px)) !important; 19 | } 20 | 21 | &:hover { 22 | filter: grayscale(0) !important; 23 | } 24 | } 25 | 26 | .messagelogger-deleted [class*="spoilerWarning"] { 27 | color: var(--status-danger); 28 | } 29 | 30 | .theme-dark .messagelogger-edited { 31 | filter: brightness(80%); 32 | } 33 | 34 | .theme-light .messagelogger-edited { 35 | opacity: 0.5; 36 | } 37 | 38 | .messagelogger-edit-marker { 39 | cursor: pointer; 40 | } 41 | 42 | .vc-ml-modal-timestamp { 43 | cursor: unset; 44 | height: unset; 45 | } 46 | 47 | .vc-ml-modal-tab-bar { 48 | flex-wrap: wrap; 49 | gap: 16px; 50 | } 51 | -------------------------------------------------------------------------------- /src/components/settings/tabs/plugins/ContributorModal.css: -------------------------------------------------------------------------------- 1 | .vc-author-modal-root { 2 | padding: 1em; 3 | } 4 | 5 | .vc-author-modal-header { 6 | display: flex; 7 | align-items: center; 8 | margin-bottom: 1em; 9 | } 10 | 11 | .vc-author-modal-name { 12 | text-transform: none; 13 | flex-grow: 0; 14 | background: var(--background-base-lowest); 15 | border-radius: 0 9999px 9999px 0; 16 | padding: 6px 0.8em 6px 0.5em; 17 | font-size: 20px; 18 | height: 20px; 19 | position: relative; 20 | text-wrap: nowrap; 21 | } 22 | 23 | .vc-author-modal-name::before { 24 | content: ""; 25 | display: block; 26 | position: absolute; 27 | height: 100%; 28 | width: 32px; 29 | background: var(--background-base-lowest); 30 | z-index: -1; 31 | left: -32px; 32 | top: 0; 33 | border-top-left-radius: 9999px; 34 | border-bottom-left-radius: 9999px; 35 | } 36 | 37 | .vc-author-modal-avatar { 38 | height: 32px; 39 | width: 32px; 40 | border-radius: 50%; 41 | } 42 | 43 | .vc-author-modal-links { 44 | margin-left: auto; 45 | } 46 | 47 | .vc-author-modal-plugins { 48 | display: grid; 49 | gap: 0.5em; 50 | margin-top: 0.75em; 51 | } -------------------------------------------------------------------------------- /src/plugins/biggerStreamPreview/webpack/stores.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { findStoreLazy } from "@webpack"; 20 | 21 | import * as t from "./types/stores"; 22 | 23 | export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore"); 24 | export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore"); 25 | -------------------------------------------------------------------------------- /src/plugins/betterSessions/types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export interface SessionInfo { 20 | session: { 21 | id_hash: string; 22 | approx_last_used_time: Date; 23 | client_info: { 24 | os: string; 25 | platform: string; 26 | location: string; 27 | }; 28 | }, 29 | current?: boolean; 30 | } 31 | 32 | export type Session = SessionInfo["session"]; 33 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/Activity.d.ts: -------------------------------------------------------------------------------- 1 | import { ActivityFlags, ActivityStatusDisplayType, ActivityType } from "../../enums"; 2 | 3 | export interface ActivityAssets { 4 | large_image?: string; 5 | large_text?: string; 6 | large_url?: string; 7 | small_image?: string; 8 | small_text?: string; 9 | small_url?: string; 10 | } 11 | 12 | export interface ActivityButton { 13 | label: string; 14 | url: string; 15 | } 16 | 17 | export interface Activity { 18 | name: string; 19 | application_id: string; 20 | type: ActivityType; 21 | state?: string; 22 | state_url?: string; 23 | details?: string; 24 | details_url?: string; 25 | url?: string; 26 | flags: ActivityFlags; 27 | status_display_type?: ActivityStatusDisplayType; 28 | timestamps?: { 29 | start?: number; 30 | end?: number; 31 | }; 32 | assets?: ActivityAssets; 33 | buttons?: string[]; 34 | metadata?: { 35 | button_urls?: Array; 36 | }; 37 | party?: { 38 | id?: string; 39 | size?: [number, number]; 40 | }; 41 | } 42 | 43 | export type OnlineStatus = "online" | "idle" | "dnd" | "invisible" | "offline" | "unknown" | "streaming"; 44 | -------------------------------------------------------------------------------- /src/utils/dependencies.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | // The below code is only used on the Desktop (electron) build of Vencord. 20 | // Browser (extension) builds do not contain these remote imports. 21 | 22 | export const shikiWorkerSrc = `https://cdn.jsdelivr.net/npm/@vap/shiki-worker@0.0.8/dist/${IS_DEV ? "index.js" : "index.min.js"}`; 23 | export const shikiOnigasmSrc = "https://cdn.jsdelivr.net/npm/@vap/shiki@0.10.3/dist/onig.wasm"; 24 | -------------------------------------------------------------------------------- /src/components/ErrorCard.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import "./ErrorCard.css"; 20 | 21 | import { classes } from "@utils/misc"; 22 | import type { HTMLProps } from "react"; 23 | 24 | export function ErrorCard(props: React.PropsWithChildren>) { 25 | return ( 26 |
27 | {props.children} 28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /src/plugins/webScreenShareFixes.web/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Devs } from "@utils/constants"; 8 | import definePlugin from "@utils/types"; 9 | 10 | export default definePlugin({ 11 | name: "WebScreenShareFixes", 12 | authors: [Devs.Kaitlyn], 13 | description: "Removes 2500kbps bitrate cap on chromium and vesktop clients.", 14 | enabledByDefault: true, 15 | patches: [ 16 | { 17 | find: "x-google-max-bitrate", 18 | replacement: [ 19 | { 20 | match: /"x-google-max-bitrate=".concat\(\i\)/, 21 | replace: '"x-google-max-bitrate=".concat("80_000")' 22 | }, 23 | { 24 | match: ";level-asymmetry-allowed=1", 25 | replace: ";b=AS:800000;level-asymmetry-allowed=1" 26 | }, 27 | { 28 | match: /;usedtx=".concat\((\i)\?"0":"1"\)/, 29 | replace: '$&.concat($1?";stereo=1;sprop-stereo=1":"")' 30 | } 31 | ] 32 | } 33 | ] 34 | }); 35 | -------------------------------------------------------------------------------- /src/webpack/types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2025 Vendicated, Nuckyz and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Module, ModuleExports, WebpackRequire } from "@vencord/discord-types/webpack"; 8 | 9 | import { SYM_ORIGINAL_FACTORY, SYM_PATCHED_BY, SYM_PATCHED_SOURCE } from "./patchWebpack"; 10 | 11 | export type AnyWebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & Partial> & { 12 | /** The module factories, where all modules that have been loaded are stored (pre-loaded or loaded by lazy chunks) */ 13 | m: Record; 14 | }; 15 | 16 | /** exports can be anything, however initially it is always an empty object */ 17 | export type AnyModuleFactory = ((this: ModuleExports, module: Module, exports: ModuleExports, require: AnyWebpackRequire) => void) & { 18 | [SYM_PATCHED_SOURCE]?: string; 19 | [SYM_PATCHED_BY]?: Set; 20 | }; 21 | 22 | export type PatchedModuleFactory = AnyModuleFactory & { 23 | [SYM_ORIGINAL_FACTORY]: AnyModuleFactory; 24 | [SYM_PATCHED_SOURCE]?: string; 25 | [SYM_PATCHED_BY]?: Set; 26 | }; 27 | 28 | export type MaybePatchedModuleFactory = PatchedModuleFactory | AnyModuleFactory; 29 | -------------------------------------------------------------------------------- /src/plugins/clientTheme/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import "./clientTheme.css"; 8 | 9 | import { definePluginSettings } from "@api/Settings"; 10 | import { Devs } from "@utils/constants"; 11 | import definePlugin, { OptionType, StartAt } from "@utils/types"; 12 | 13 | import { ResetThemeColorComponent, ThemeSettingsComponent } from "./components/Settings"; 14 | import { disableClientTheme, startClientTheme } from "./utils/styleUtils"; 15 | 16 | export const settings = definePluginSettings({ 17 | color: { 18 | type: OptionType.COMPONENT, 19 | default: "313338", 20 | component: ThemeSettingsComponent 21 | }, 22 | resetColor: { 23 | type: OptionType.COMPONENT, 24 | component: ResetThemeColorComponent 25 | } 26 | }); 27 | 28 | export default definePlugin({ 29 | name: "ClientTheme", 30 | authors: [Devs.Nuckyz], 31 | description: "Recreation of the old client theme experiment. Add a color to your Discord client theme", 32 | settings, 33 | 34 | startAt: StartAt.DOMContentLoaded, 35 | start: () => startClientTheme(settings.store.color), 36 | stop: disableClientTheme 37 | }); 38 | -------------------------------------------------------------------------------- /scripts/utils.mjs: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /** 20 | * @param {string} filePath 21 | * @returns {string | null} 22 | */ 23 | export function getPluginTarget(filePath) { 24 | const pathParts = filePath.split(/[/\\]/); 25 | if (/^index\.tsx?$/.test(pathParts.at(-1))) pathParts.pop(); 26 | 27 | const identifier = pathParts.at(-1).replace(/\.tsx?$/, ""); 28 | const identiferBits = identifier.split("."); 29 | return identiferBits.length === 1 ? null : identiferBits.at(-1); 30 | } 31 | -------------------------------------------------------------------------------- /src/plugins/shikiCodeblocks.desktop/utils/color.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | export function hex2Rgb(hex: string) { 20 | hex = hex.slice(1); 21 | if (hex.length < 6) 22 | hex = hex 23 | .split("") 24 | .map(c => c + c) 25 | .join(""); 26 | if (hex.length === 6) hex += "ff"; 27 | if (hex.length > 6) hex = hex.slice(0, 6); 28 | return hex 29 | .split(/(..)/) 30 | .filter(Boolean) 31 | .map(c => parseInt(c, 16)); 32 | } 33 | -------------------------------------------------------------------------------- /browser/monaco.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import "./patch-worker"; 8 | 9 | import * as monaco from "monaco-editor/esm/vs/editor/editor.main.js"; 10 | 11 | declare global { 12 | const baseUrl: string; 13 | const getCurrentCss: () => Promise; 14 | const setCss: (css: string) => void; 15 | const getTheme: () => string; 16 | } 17 | 18 | const BASE = "/vendor/monaco/vs"; 19 | 20 | self.MonacoEnvironment = { 21 | getWorkerUrl(_moduleId: unknown, label: string) { 22 | const path = label === "css" ? "/language/css/css.worker.js" : "/editor/editor.worker.js"; 23 | return new URL(BASE + path, baseUrl).toString(); 24 | } 25 | }; 26 | 27 | getCurrentCss().then(css => { 28 | const editor = monaco.editor.create( 29 | document.getElementById("container")!, 30 | { 31 | value: css, 32 | language: "css", 33 | theme: getTheme(), 34 | } 35 | ); 36 | editor.onDidChangeModelContent(() => 37 | setCss(editor.getValue()) 38 | ); 39 | window.addEventListener("resize", () => { 40 | // make monaco re-layout 41 | editor.layout(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /src/components/settings/tabs/themes/styles.css: -------------------------------------------------------------------------------- 1 | .vc-settings-theme-grid { 2 | display: grid; 3 | gap: 16px; 4 | grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); 5 | } 6 | 7 | .vc-settings-theme-card { 8 | display: flex; 9 | flex-direction: column; 10 | background-color: var(--background-base-lower-alt); 11 | color: var(--interactive-active); 12 | border-radius: 8px; 13 | padding: 1em; 14 | width: 100%; 15 | transition: 0.1s ease-out; 16 | transition-property: box-shadow, transform, background, opacity; 17 | } 18 | 19 | .vc-settings-theme-card-text { 20 | text-overflow: ellipsis; 21 | height: 1.2em; 22 | margin-bottom: 2px; 23 | white-space: nowrap; 24 | overflow: hidden; 25 | } 26 | 27 | .vc-settings-theme-author::before { 28 | content: "by "; 29 | } 30 | 31 | .vc-settings-csp-list { 32 | display: flex; 33 | flex-direction: column; 34 | gap: 8px; 35 | } 36 | 37 | .vc-settings-csp-row { 38 | display: flex; 39 | justify-content: space-between; 40 | align-items: center; 41 | gap: 8px; 42 | 43 | 44 | & a { 45 | text-overflow: ellipsis; 46 | overflow: hidden; 47 | white-space: nowrap; 48 | line-height: 1.2em; 49 | } 50 | 51 | --custom-button-button-md-height: 26px; 52 | } -------------------------------------------------------------------------------- /src/plugins/decor/ui/components/DecorDecorationGridDecoration.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Decoration } from "@plugins/decor/lib/api"; 8 | import { decorationToAvatarDecoration } from "@plugins/decor/lib/utils/decoration"; 9 | import { ContextMenuApi } from "@webpack/common"; 10 | import type { HTMLProps } from "react"; 11 | 12 | import { DecorationGridDecoration } from "."; 13 | import DecorationContextMenu from "./DecorationContextMenu"; 14 | 15 | interface DecorDecorationGridDecorationProps extends HTMLProps { 16 | decoration: Decoration; 17 | isSelected: boolean; 18 | onSelect: () => void; 19 | } 20 | 21 | export default function DecorDecorationGridDecoration(props: DecorDecorationGridDecorationProps) { 22 | const { decoration } = props; 23 | 24 | return { 27 | ContextMenuApi.openContextMenu(e, () => ( 28 | 31 | )); 32 | }} 33 | avatarDecoration={decorationToAvatarDecoration(decoration)} 34 | />; 35 | } 36 | -------------------------------------------------------------------------------- /src/plugins/serverInfo/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; 8 | import { Devs } from "@utils/constants"; 9 | import definePlugin from "@utils/types"; 10 | import { Guild } from "@vencord/discord-types"; 11 | import { Menu } from "@webpack/common"; 12 | 13 | import { openGuildInfoModal } from "./GuildInfoModal"; 14 | 15 | const Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild; }) => { 16 | const group = findGroupChildrenByChildId("privacy", children); 17 | 18 | group?.push( 19 | openGuildInfoModal(guild)} 23 | /> 24 | ); 25 | }; 26 | 27 | export default definePlugin({ 28 | name: "ServerInfo", 29 | description: "Allows you to view info about a server", 30 | authors: [Devs.Ven, Devs.Nuckyz], 31 | dependencies: ["DynamicImageModalAPI"], 32 | tags: ["guild", "info", "ServerProfile"], 33 | 34 | contextMenus: { 35 | "guild-context": Patch, 36 | "guild-header-popout": Patch 37 | } 38 | }); 39 | -------------------------------------------------------------------------------- /src/plugins/voiceMessages/styles.css: -------------------------------------------------------------------------------- 1 | .vc-vmsg-modal { 2 | padding: 1em; 3 | } 4 | 5 | .vc-vmsg-buttons { 6 | display: grid; 7 | grid-template-columns: repeat(3, minmax(0, 1fr)); 8 | gap: 0.5em; 9 | margin-bottom: 1em; 10 | } 11 | 12 | .vc-vmsg-preview { 13 | color: var(--text-default); 14 | border-radius: 24px; 15 | background-color: var(--background-base-lower); 16 | position: relative; 17 | display: flex; 18 | align-items: center; 19 | padding: 0 16px; 20 | height: 48px; 21 | } 22 | 23 | .vc-vmsg-preview-indicator { 24 | background: var(--button-secondary-background); 25 | width: 16px; 26 | height: 16px; 27 | border-radius: 50%; 28 | transition: background 0.2s ease-in-out; 29 | } 30 | 31 | .vc-vmsg-preview-recording .vc-vmsg-preview-indicator { 32 | background: var(--status-danger); 33 | } 34 | 35 | .vc-vmsg-preview-time { 36 | opacity: 0.8; 37 | margin: 0 0.5em; 38 | font-size: 80%; 39 | 40 | /* monospace so different digits have same size */ 41 | font-family: var(--font-code); 42 | } 43 | 44 | .vc-vmsg-preview-label { 45 | opacity: 0.5; 46 | letter-spacing: 0.125em; 47 | font-weight: 600; 48 | flex: 1; 49 | text-align: center; 50 | } 51 | 52 | .vc-vmsg-error { 53 | color: var(--text-danger); 54 | } -------------------------------------------------------------------------------- /packages/discord-types/src/stores/GuildMemberStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore, GuildMember } from ".."; 2 | 3 | export class GuildMemberStore extends FluxStore { 4 | /** @returns Format: [guildId-userId: Timestamp (string)] */ 5 | getCommunicationDisabledUserMap(): Record; 6 | getCommunicationDisabledVersion(): number; 7 | 8 | getMutableAllGuildsAndMembers(): Record>; 9 | 10 | getMember(guildId: string, userId: string): GuildMember | null; 11 | getTrueMember(guildId: string, userId: string): GuildMember | null; 12 | getMemberIds(guildId: string): string[]; 13 | getMembers(guildId: string): GuildMember[]; 14 | 15 | getCachedSelfMember(guildId: string): GuildMember | null; 16 | getSelfMember(guildId: string): GuildMember | null; 17 | getSelfMemberJoinedAt(guildId: string): Date | null; 18 | 19 | getNick(guildId: string, userId: string): string | null; 20 | getNicknameGuildsMapping(userId: string): Record; 21 | getNicknames(userId: string): string[]; 22 | 23 | isMember(guildId: string, userId: string): boolean; 24 | isMember(guildId: string, userId: string): boolean; 25 | isGuestOrLurker(guildId: string, userId: string): boolean; 26 | isCurrentUserGuest(guildId: string): boolean; 27 | } 28 | -------------------------------------------------------------------------------- /src/plugins/decor/ui/components/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { AvatarDecoration } from "@plugins/decor"; 8 | import { findComponentByCode, LazyComponentWebpack } from "@webpack"; 9 | import { React } from "@webpack/common"; 10 | import type { ComponentType, HTMLProps, PropsWithChildren } from "react"; 11 | 12 | type DecorationGridItemComponent = ComponentType> & { 13 | onSelect: () => void, 14 | isSelected: boolean, 15 | }>; 16 | 17 | export let DecorationGridItem: DecorationGridItemComponent; 18 | export const setDecorationGridItem = v => DecorationGridItem = v; 19 | 20 | export const AvatarDecorationModalPreview = LazyComponentWebpack(() => { 21 | const component = findComponentByCode(".shopPreviewBanner"); 22 | return React.memo(component); 23 | }); 24 | 25 | type DecorationGridDecorationComponent = React.ComponentType & { 26 | avatarDecoration: AvatarDecoration; 27 | onSelect: () => void, 28 | isSelected: boolean, 29 | }>; 30 | 31 | export let DecorationGridDecoration: DecorationGridDecorationComponent; 32 | export const setDecorationGridDecoration = v => DecorationGridDecoration = v; 33 | -------------------------------------------------------------------------------- /src/plugins/memberCount/style.css: -------------------------------------------------------------------------------- 1 | .vc-membercount-widget { 2 | gap: 0.85em; 3 | display: flex; 4 | align-content: center; 5 | 6 | --color-online: var(--green-360); 7 | --color-total: var(--primary-400); 8 | --color-voice: var(--primary-400); 9 | } 10 | 11 | .vc-membercount-tooltip { 12 | margin-top: 0.25em; 13 | margin-left: 2px; 14 | } 15 | 16 | .vc-membercount-member-list { 17 | justify-content: center; 18 | flex-wrap: wrap; 19 | margin-top: 1em; 20 | padding-inline: 1em; 21 | line-height: 1.2em; 22 | } 23 | 24 | .vc-membercount-container { 25 | display: flex; 26 | align-items: center; 27 | gap: 0.5em; 28 | } 29 | 30 | .vc-membercount-online { 31 | color: var(--color-online); 32 | } 33 | 34 | .vc-membercount-total { 35 | color: var(--color-total); 36 | } 37 | 38 | .vc-membercount-voice { 39 | color: var(--color-voice); 40 | } 41 | 42 | .vc-membercount-online-count { 43 | fill: var(--status-online); 44 | width: 18px; 45 | height: 18px; 46 | } 47 | 48 | .vc-membercount-total-count { 49 | fill: none; 50 | stroke: var(--status-offline); 51 | stroke-width: 4px; 52 | width: 15px; 53 | height: 15px; 54 | } 55 | 56 | .vc-membercount-voice-icon { 57 | color: var(--color-voice); 58 | width: 15px; 59 | height: 15px; 60 | } -------------------------------------------------------------------------------- /src/plugins/voiceMessages/settings.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { definePluginSettings } from "@api/Settings"; 20 | import { OptionType } from "@utils/types"; 21 | 22 | export const settings = definePluginSettings({ 23 | noiseSuppression: { 24 | type: OptionType.BOOLEAN, 25 | description: "Noise Suppression", 26 | default: true, 27 | }, 28 | echoCancellation: { 29 | type: OptionType.BOOLEAN, 30 | description: "Echo Cancellation", 31 | default: true, 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /packages/discord-types/src/common/messages/Emoji.d.ts: -------------------------------------------------------------------------------- 1 | export type Emoji = CustomEmoji | UnicodeEmoji; 2 | 3 | export interface CustomEmoji { 4 | type: 1; 5 | allNamesString: string; 6 | animated: boolean; 7 | available: boolean; 8 | guildId: string; 9 | id: string; 10 | managed: boolean; 11 | name: string; 12 | originalName?: string; 13 | require_colons: boolean; 14 | roles: string[]; 15 | } 16 | 17 | export interface UnicodeEmoji { 18 | type: 0; 19 | diversityChildren: Record; 20 | emojiObject: { 21 | names: string[]; 22 | surrogates: string; 23 | unicodeVersion: number; 24 | }; 25 | index: number; 26 | surrogates: string; 27 | uniqueName: string; 28 | useSpriteSheet: boolean; 29 | get allNamesString(): string; 30 | get animated(): boolean; 31 | get defaultDiversityChild(): any; 32 | get hasDiversity(): boolean | undefined; 33 | get hasDiversityParent(): boolean | undefined; 34 | get hasMultiDiversity(): boolean | undefined; 35 | get hasMultiDiversityParent(): boolean | undefined; 36 | get managed(): boolean; 37 | get name(): string; 38 | get names(): string[]; 39 | get optionallyDiverseSequence(): string | undefined; 40 | get unicodeVersion(): number; 41 | get url(): string; 42 | } 43 | -------------------------------------------------------------------------------- /src/plugins/noF1/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | 22 | export default definePlugin({ 23 | name: "NoF1", 24 | description: "Disables F1 help bind.", 25 | authors: [Devs.Cyn], 26 | patches: [ 27 | { 28 | find: ',"f1"],comboKeysBindGlobal:', 29 | replacement: { 30 | match: ',"f1"],comboKeysBindGlobal:', 31 | replace: "],comboKeysBindGlobal:", 32 | }, 33 | }, 34 | ], 35 | }); 36 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // this allows you to debug Vencord from VSCode. 3 | // How to use: 4 | // You need to run Discord via the command line to pass some flags to it. 5 | // If you want to debug the main (node.js) process (preload.ts, ipcMain/*, patcher.ts), 6 | // add the --inspect flag 7 | // To debug the renderer (99% of Vencord), add the --remote-debugging-port=9223 flag 8 | // 9 | // Now launch the desired configuration in VSCode and start Discord with the flags. 10 | // For example, to debug both process, run Electron: All then launch Discord with 11 | // discord --remote-debugging-port=9223 --inspect 12 | 13 | "version": "0.2.0", 14 | "configurations": [ 15 | { 16 | "name": "Electron: Main", 17 | "type": "node", 18 | "request": "attach", 19 | "port": 9229, 20 | "timeout": 30000 21 | }, 22 | { 23 | "name": "Electron: Renderer", 24 | "type": "chrome", 25 | "request": "attach", 26 | "port": 9223, 27 | "timeout": 30000, 28 | "webRoot": "${workspaceFolder}/src" 29 | } 30 | ], 31 | "compounds": [ 32 | { 33 | "name": "Electron: All", 34 | "configurations": ["Electron: Main", "Electron: Renderer"] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /src/api/MessageUpdater.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2024 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { Message } from "@vencord/discord-types"; 8 | import { MessageCache, MessageStore } from "@webpack/common"; 9 | 10 | /** 11 | * Update and re-render a message 12 | * @param channelId The channel id of the message 13 | * @param messageId The message id 14 | * @param fields The fields of the message to change. Leave empty if you just want to re-render 15 | */ 16 | export function updateMessage(channelId: string, messageId: string, fields?: Partial>) { 17 | const channelMessageCache = MessageCache.getOrCreate(channelId); 18 | if (!channelMessageCache.has(messageId)) return; 19 | 20 | // To cause a message to re-render, we basically need to create a new instance of the message and obtain a new reference 21 | // If we have fields to modify we can use the merge method of the class, otherwise we just create a new instance with the old fields 22 | const newChannelMessageCache = channelMessageCache.update(messageId, (oldMessage: any) => { 23 | return fields ? oldMessage.merge(fields) : new oldMessage.constructor(oldMessage); 24 | }); 25 | 26 | MessageCache.commit(newChannelMessageCache); 27 | MessageStore.emitChange(); 28 | } 29 | -------------------------------------------------------------------------------- /src/plugins/noOnboardingDelay/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | 22 | export default definePlugin({ 23 | name: "NoOnboardingDelay", 24 | description: "Skips the slow and annoying onboarding delay", 25 | authors: [Devs.nekohaxx], 26 | patches: [ 27 | { 28 | find: "#{intl::ONBOARDING_COVER_WELCOME_SUBTITLE}", 29 | replacement: { 30 | match: "3e3", 31 | replace: "0" 32 | }, 33 | }, 34 | ], 35 | }); 36 | -------------------------------------------------------------------------------- /src/plugins/dontRoundMyTimestamps/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | import { moment } from "@webpack/common"; 22 | 23 | export default definePlugin({ 24 | name: "DontRoundMyTimestamps", 25 | authors: [Devs.Lexi], 26 | description: "Always rounds relative timestamps down, so 7.6y becomes 7y instead of 8y", 27 | 28 | start() { 29 | moment.relativeTimeRounding(Math.floor); 30 | }, 31 | 32 | stop() { 33 | moment.relativeTimeRounding(Math.round); 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /src/plugins/secretRingTone/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a Discord client mod 3 | * Copyright (c) 2023 Vendicated and contributors 4 | * SPDX-License-Identifier: GPL-3.0-or-later 5 | */ 6 | 7 | import { definePluginSettings } from "@api/Settings"; 8 | import { Devs } from "@utils/constants"; 9 | import definePlugin, { OptionType } from "@utils/types"; 10 | 11 | const settings = definePluginSettings({ 12 | onlySnow: { 13 | type: OptionType.BOOLEAN, 14 | description: "Only play the Snow Halation Theme", 15 | default: false, 16 | restartNeeded: true 17 | } 18 | }); 19 | 20 | export default definePlugin({ 21 | name: "SecretRingToneEnabler", 22 | description: "Always play the secret version of the discord ringtone (except during special ringtone events)", 23 | authors: [Devs.AndrewDLO, Devs.FieryFlames, Devs.RamziAH], 24 | settings, 25 | patches: [ 26 | { 27 | find: '"call_ringing_beat"', 28 | replacement: [ 29 | { 30 | match: /500!==\i\(\)\.random\(1,1e3\)/, 31 | replace: "false" 32 | }, 33 | { 34 | predicate: () => settings.store.onlySnow, 35 | match: /"call_ringing_beat",/, 36 | replace: "" 37 | } 38 | ] 39 | } 40 | ] 41 | }); 42 | -------------------------------------------------------------------------------- /src/plugins/shikiCodeblocks.desktop/hooks/useCopyCooldown.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { copyToClipboard } from "@utils/clipboard"; 20 | import { React } from "@webpack/common"; 21 | 22 | export function useCopyCooldown(cooldown: number) { 23 | const [copyCooldown, setCopyCooldown] = React.useState(false); 24 | 25 | function copy(text: string) { 26 | copyToClipboard(text); 27 | setCopyCooldown(true); 28 | 29 | setTimeout(() => { 30 | setCopyCooldown(false); 31 | }, cooldown); 32 | } 33 | 34 | return [copyCooldown, copy] as const; 35 | } 36 | -------------------------------------------------------------------------------- /browser/background.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @template T 3 | * @param {T[]} arr 4 | * @param {(v: T) => boolean} predicate 5 | */ 6 | function removeFirst(arr, predicate) { 7 | const idx = arr.findIndex(predicate); 8 | if (idx !== -1) arr.splice(idx, 1); 9 | } 10 | 11 | chrome.webRequest.onHeadersReceived.addListener( 12 | ({ responseHeaders, type, url }) => { 13 | if (!responseHeaders) return; 14 | 15 | if (type === "main_frame") { 16 | // In main frame requests, the CSP needs to be removed to enable fetching of custom css 17 | // as desired by the user 18 | removeFirst(responseHeaders, h => h.name.toLowerCase() === "content-security-policy"); 19 | } else if (type === "stylesheet" && url.startsWith("https://raw.githubusercontent.com/")) { 20 | // Most users will load css from GitHub, but GitHub doesn't set the correct content type, 21 | // so we fix it here 22 | removeFirst(responseHeaders, h => h.name.toLowerCase() === "content-type"); 23 | responseHeaders.push({ 24 | name: "Content-Type", 25 | value: "text/css" 26 | }); 27 | } 28 | return { responseHeaders }; 29 | }, 30 | { urls: ["https://raw.githubusercontent.com/*", "*://*.discord.com/*"], types: ["main_frame", "stylesheet"] }, 31 | ["blocking", "responseHeaders"] 32 | ); 33 | -------------------------------------------------------------------------------- /src/components/Switch.css: -------------------------------------------------------------------------------- 1 | .vc-switch-container { 2 | background: var(--primary-400); 3 | border: 1px solid transparent; 4 | border-radius: 16px; 5 | box-sizing: border-box; 6 | cursor: pointer; 7 | height: 28px; 8 | position: relative; 9 | width: 44px; 10 | 11 | .high-contrast-mode & { 12 | border-color: var(--border-strong); 13 | } 14 | } 15 | 16 | .vc-switch-checked { 17 | background: var(--brand-500); 18 | border-color: var(--control-border-primary-default); 19 | } 20 | 21 | .vc-switch-disabled { 22 | cursor: not-allowed; 23 | opacity: 0.3; 24 | } 25 | 26 | .vc-switch-focusVisible { 27 | /* stylelint-disable-next-line custom-property-pattern */ 28 | box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--focus-primary, #00b0f4)); 29 | } 30 | 31 | .vc-switch-slider { 32 | display: block; 33 | height: 20px; 34 | left: 0; 35 | margin: 3px; 36 | position: absolute; 37 | width: 28px; 38 | transition: 100ms transform ease-in-out; 39 | overflow: visible; 40 | } 41 | 42 | .vc-switch-input { 43 | border-radius: 14px; 44 | cursor: pointer; 45 | height: 100%; 46 | left: 0; 47 | margin: 0; 48 | opacity: 0; 49 | position: absolute; 50 | top: 0; 51 | width: 100%; 52 | 53 | &:disabled { 54 | pointer-events: none; 55 | cursor: not-allowed 56 | } 57 | } -------------------------------------------------------------------------------- /src/shared/debounce.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | /** 20 | * Returns a new function that will call the wrapped function 21 | * after the specified delay. If the function is called again 22 | * within the delay, the timer will be reset. 23 | * @param func The function to wrap 24 | * @param delay The delay in milliseconds 25 | */ 26 | export function debounce(func: T, delay = 300): T { 27 | let timeout: NodeJS.Timeout; 28 | return function (...args: any[]) { 29 | clearTimeout(timeout); 30 | timeout = setTimeout(() => { func(...args); }, delay); 31 | } as any; 32 | } 33 | -------------------------------------------------------------------------------- /packages/discord-types/src/stores/DraftStore.d.ts: -------------------------------------------------------------------------------- 1 | import { FluxStore } from ".."; 2 | 3 | export enum DraftType { 4 | ChannelMessage = 0, 5 | ThreadSettings = 1, 6 | FirstThreadMessage = 2, 7 | ApplicationLauncherCommand = 3, 8 | Poll = 4, 9 | SlashCommand = 5, 10 | ForwardContextMessage = 6 11 | } 12 | 13 | export interface Draft { 14 | timestamp: number; 15 | draft: string; 16 | } 17 | 18 | export interface ThreadSettingsDraft { 19 | timestamp: number; 20 | parentMessageId?: string; 21 | name?: string; 22 | isPrivate?: boolean; 23 | parentChannelId?: string; 24 | location?: string; 25 | } 26 | 27 | export type ChannelDrafts = { 28 | [DraftType.ThreadSettings]: ThreadSettingsDraft; 29 | } & { 30 | [key in Exclude]: Draft; 31 | }; 32 | 33 | export type UserDrafts = Partial>; 34 | export type DraftState = Partial>; 35 | 36 | export class DraftStore extends FluxStore { 37 | getState(): DraftState; 38 | getRecentlyEditedDrafts(type: DraftType): Array; 39 | getDraft(channelId: string, type: DraftType): string; 40 | 41 | getThreadSettings(channelId: string): ThreadSettingsDraft | null | undefined; 42 | getThreadDraftWithParentMessageId(parentMessageId: string): ThreadSettingsDraft | null | undefined; 43 | } 44 | -------------------------------------------------------------------------------- /src/plugins/shikiCodeblocks.desktop/utils/createStyle.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | const styles = new Map(); 20 | 21 | export function setStyle(css: string, id: string) { 22 | const style = document.createElement("style"); 23 | style.innerText = css; 24 | document.head.appendChild(style); 25 | styles.set(id, style); 26 | } 27 | 28 | export function removeStyle(id: string) { 29 | styles.get(id)?.remove(); 30 | return styles.delete(id); 31 | } 32 | 33 | export const clearStyles = () => { 34 | styles.forEach(style => style.remove()); 35 | styles.clear(); 36 | }; 37 | -------------------------------------------------------------------------------- /browser/userscript.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Vencord 3 | // @description A Discord client mod - Web version 4 | // @version %version% 5 | // @author Vendicated (https://github.com/Vendicated) 6 | // @namespace https://github.com/Vendicated/Vencord 7 | // @supportURL https://github.com/Vendicated/Vencord 8 | // @icon https://raw.githubusercontent.com/Vendicated/Vencord/refs/heads/main/browser/icon.png 9 | // @license GPL-3.0 10 | // @match *://*.discord.com/* 11 | // @grant GM_xmlhttpRequest 12 | // @grant unsafeWindow 13 | // @run-at document-start 14 | // @compatible chrome Chrome + Tampermonkey or Violentmonkey 15 | // @compatible firefox Firefox Tampermonkey 16 | // @compatible opera Opera + Tampermonkey or Violentmonkey 17 | // @compatible edge Edge + Tampermonkey or Violentmonkey 18 | // @compatible safari Safari + Tampermonkey or Violentmonkey 19 | // ==/UserScript== 20 | 21 | 22 | // this UserScript DOES NOT work on Firefox with Violentmonkey or Greasemonkey due to a bug that makes it impossible 23 | // to overwrite stuff on the window on sites that use CSP. Use Tampermonkey or use a chromium based browser 24 | // https://github.com/violentmonkey/violentmonkey/issues/997 25 | 26 | // this is a compiled and minified version of Vencord. For the source code, visit the GitHub repo 27 | -------------------------------------------------------------------------------- /browser/manifestv2.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "minimum_chrome_version": "91", 4 | 5 | "name": "Vencord Web", 6 | "description": "The cutest Discord mod now in your browser", 7 | "author": "Vendicated", 8 | "homepage_url": "https://github.com/Vendicated/Vencord", 9 | "icons": { 10 | "128": "icon.png" 11 | }, 12 | 13 | "permissions": [ 14 | "webRequest", 15 | "webRequestBlocking", 16 | "*://*.discord.com/*", 17 | "https://raw.githubusercontent.com/*" 18 | ], 19 | 20 | "content_scripts": [ 21 | { 22 | "run_at": "document_start", 23 | "matches": ["*://*.discord.com/*"], 24 | "js": ["content.js"], 25 | "all_frames": true, 26 | "world": "ISOLATED" 27 | }, 28 | { 29 | "run_at": "document_start", 30 | "matches": ["*://*.discord.com/*"], 31 | "js": ["dist/Vencord.js"], 32 | "all_frames": true, 33 | "world": "MAIN" 34 | } 35 | ], 36 | 37 | "background": { 38 | "scripts": ["background.js"] 39 | }, 40 | 41 | "web_accessible_resources": ["dist/Vencord.js", "dist/Vencord.css"], 42 | 43 | "browser_specific_settings": { 44 | "gecko": { 45 | "id": "vencord-firefox@vendicated.dev", 46 | "strict_min_version": "128.0" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/plugins/iLoveSpam/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | 22 | export default definePlugin({ 23 | name: "iLoveSpam", 24 | description: "Do not hide messages from 'likely spammers'", 25 | authors: [Devs.botato, Devs.Nyako], 26 | patches: [ 27 | { 28 | find: "hasFlag:{writable", 29 | replacement: { 30 | match: /if\((\i)<=(?:0x40000000|(?:1<<30|1073741824))\)return/, 31 | replace: "if($1===(1<<20))return false;$&", 32 | }, 33 | }, 34 | ], 35 | }); 36 | -------------------------------------------------------------------------------- /src/plugins/loadingQuotes/quotes.txt: -------------------------------------------------------------------------------- 1 | # Blank lines and lines starting with "#" are ignored 2 | 3 | Explode 4 | Read if cute 5 | Have a nice day! 6 | Starting Lightcord... 7 | Loading 0BDFDB.plugin.js... 8 | Installing BetterDiscord... 9 | h 10 | shhhhh did you know that you're my favourite user? But don't tell the others!! 11 | Today's video is sponsored by Raid Shadow Legends, one of the biggest mobile role-playing games of 2019 and it's totally free! 12 | Never gonna give you up, Never gonna let you down 13 | ( ͡° ͜ʖ ͡°) 14 | (ノ◕ヮ◕)ノ*:・゚✧ 15 | You look so pretty today! 16 | Thinking of a funny quote... 17 | 3.141592653589793 18 | meow 19 | Welcome, friend 20 | If you, or someone you love, has Ligma, please see the Ligma health line at https://bit.ly/ligma_hotline 21 | Trans Rights 22 | I’d just like to interject for a moment. What you’re refering to as Linux, is in fact, GNU/Linux, or as I’ve recently taken to calling it, GNU plus Linux. 23 | You're doing good today! 24 | Don't worry, it's nothing 9 cups of coffee couldn't solve! 25 | �(repeat like 30 times) 26 | a light amount of tomfoolery is okay 27 | do you love? 28 | horror 29 | so eepy 30 | So without further ado, let's just jump right into it! 31 | Dying is absolutely safe 32 | hey you! you're cute :)) 33 | heya ~ 34 | <:trolley:997086295010594867> 35 | Time is gone, space is insane. Here it comes, here again. 36 | sometimes it's okay to just guhhhhhhhhhhhhhh 37 | Welcome to nginx! 38 | -------------------------------------------------------------------------------- /src/plugins/noUnblockToJump/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Sofia Lima 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | 22 | export default definePlugin({ 23 | name: "NoUnblockToJump", 24 | description: "Allows you to jump to messages of blocked or ignored users and likely spammers without unblocking them", 25 | authors: [Devs.dzshn], 26 | patches: [ 27 | { 28 | find: "#{intl::UNIGNORE_TO_JUMP_BODY}", 29 | replacement: { 30 | match: /return \i\.\i\.isBlockedForMessage\(/, 31 | replace: "return true;$&" 32 | } 33 | } 34 | ] 35 | }); 36 | -------------------------------------------------------------------------------- /src/plugins/_api/messageAccessories.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | 22 | export default definePlugin({ 23 | name: "MessageAccessoriesAPI", 24 | description: "API to add message accessories.", 25 | authors: [Devs.Cyn], 26 | patches: [ 27 | { 28 | find: "#{intl::REMOVE_ATTACHMENT_BODY}", 29 | replacement: { 30 | match: /(?<=.container\)?,children:)(\[.+?\])/, 31 | replace: "Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)", 32 | }, 33 | }, 34 | ], 35 | }); 36 | -------------------------------------------------------------------------------- /src/plugins/noDevtoolsWarning/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Vencord, a modification for Discord's desktop app 3 | * Copyright (c) 2022 Vendicated and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import { Devs } from "@utils/constants"; 20 | import definePlugin from "@utils/types"; 21 | 22 | export default definePlugin({ 23 | name: "NoDevtoolsWarning", 24 | description: "Disables the 'HOLD UP' banner in the console. As a side effect, also prevents Discord from hiding your token, which prevents random logouts.", 25 | authors: [Devs.Ven], 26 | patches: [{ 27 | find: "setDevtoolsCallbacks", 28 | replacement: { 29 | match: /if\(null!=\i&&"0.0.0"===\i\.remoteApp\.getVersion\(\)\)/, 30 | replace: "if(true)" 31 | } 32 | }] 33 | }); 34 | --------------------------------------------------------------------------------