├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── AssignBadges ├── AssignBadges.plugin.js └── README.md ├── CallTimeCounter ├── CallTimeCounter.plugin.js └── README.md ├── ClickToCopyUsername ├── ClickToCopyUsername.plugin.js └── README.md ├── CopyRoleColors ├── CopyRoleColors.plugin.js └── README.md ├── DiscordActivities ├── DiscordActivities.plugin.js ├── README.md └── assets │ ├── call.png │ └── pokernight.png ├── DndWhilePlaying ├── DndWhilePlaying.plugin.js └── README.md ├── GlobalReplies ├── GlobalReplies.plugin.js ├── README.md └── assets │ └── preview.png ├── GrammarCorrect ├── GrammarCorrect.plugin.js └── README.md ├── HidePerServerAvatars ├── HidePerServerAvatars.plugin.js └── README.md ├── InAppNotifications ├── InAppNotifications.plugin.js └── README.md ├── OldUpload ├── OldUpload.plugin.js └── README.md ├── QuickMessages ├── QuickMessages.plugin.js └── README.md ├── QuickToggler ├── QuickToggler.plugin.js └── README.md ├── TypingUsersAvatars ├── README.md └── TypingUsersAvatars.plugin.js └── UserVolumeBooster ├── README.md └── UserVolumeBooster.plugin.js /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve | DO NOT OPEN ISSUES FOR SUPPORT, JOIN THE 4 | SUPPORT SERVER https://discord.gg/zJbXFXNAhJ 5 | title: "[BUG]" 6 | labels: bug 7 | assignees: QWERTxD 8 | 9 | --- 10 | 11 | **Describe the Bug** 12 | 13 | 14 | **To Reproduce** 15 | 16 | 17 | **Expected Behavior** 18 | 19 | 20 | **Screenshots** 21 | 22 | 23 | **Discord Version** 24 | 25 | 26 | **Additional Context** 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE REQUEST]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | 13 | **Describe the feature you'd like** 14 | 15 | 16 | **Additional context** 17 | 18 | -------------------------------------------------------------------------------- /AssignBadges/AssignBadges.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name AssignBadges 3 | * @version 1.0.29 4 | * @description Allows you to locally assign badges to users through the user context menu. 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/AssignBadges 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/AssignBadges/AssignBadges.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "AssignBadges", 35 | "version": "1.0.29", 36 | "description": "Allows you to locally assign badges to users through the user context menu.", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/AssignBadges", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/AssignBadges/AssignBadges.plugin.js" 44 | }, 45 | "build": { 46 | "zlibrary": true, 47 | "copy": true, 48 | "production": false, 49 | "scssHash": false, 50 | "alias": { 51 | "components": "components/index.js" 52 | }, 53 | "release": { 54 | "source": true, 55 | "readme": true 56 | } 57 | }, 58 | "changelog": [{ 59 | "type": "fixed", 60 | "title": "Fixes", 61 | "items": [ 62 | "Fixed the ContextMenus", 63 | "Fixed some issues with the Bot Tag" 64 | ] 65 | }] 66 | }; 67 | function buildPlugin([BasePlugin, PluginApi]) { 68 | const module = { 69 | exports: {} 70 | }; 71 | (() => { 72 | "use strict"; 73 | class StyleLoader { 74 | static styles = ""; 75 | static element = null; 76 | static append(module, css) { 77 | this.styles += `/* ${module} */\n${css}`; 78 | } 79 | static inject(name = config.info.name) { 80 | if (this.element) this.element.remove(); 81 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 82 | id: name, 83 | textContent: this.styles 84 | })); 85 | } 86 | static remove() { 87 | if (this.element) { 88 | this.element.remove(); 89 | this.element = null; 90 | } 91 | } 92 | } 93 | function ___createMemoize___(instance, name, value) { 94 | value = value(); 95 | Object.defineProperty(instance, name, { 96 | value, 97 | configurable: true 98 | }); 99 | return value; 100 | }; 101 | const Modules = { 102 | get 'react-spring'() { 103 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 104 | }, 105 | '@discord/utils': { 106 | get 'joinClassNames'() { 107 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 108 | }, 109 | get 'useForceUpdate'() { 110 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 111 | }, 112 | get 'Logger'() { 113 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 114 | }, 115 | get 'Navigation'() { 116 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 117 | } 118 | }, 119 | '@discord/components': { 120 | get 'Tooltip'() { 121 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 122 | }, 123 | get 'TooltipContainer'() { 124 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 125 | }, 126 | get 'TextInput'() { 127 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 128 | }, 129 | get 'SlideIn'() { 130 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 131 | }, 132 | get 'SettingsNotice'() { 133 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 134 | }, 135 | get 'TransitionGroup'() { 136 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 137 | }, 138 | get 'Button'() { 139 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 140 | }, 141 | get 'Popout'() { 142 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 143 | }, 144 | get 'Flex'() { 145 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 146 | }, 147 | get 'Text'() { 148 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('Text')) 149 | }, 150 | get 'Card'() { 151 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 152 | } 153 | }, 154 | '@discord/modules': { 155 | get 'Dispatcher'() { 156 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dirtyDispatch', 'subscribe')) 157 | }, 158 | get 'ComponentDispatcher'() { 159 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 160 | }, 161 | get 'EmojiUtils'() { 162 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 163 | }, 164 | get 'PermissionUtils'() { 165 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 166 | }, 167 | get 'DMUtils'() { 168 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 169 | } 170 | }, 171 | '@discord/stores': { 172 | get 'Messages'() { 173 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 174 | }, 175 | get 'Channels'() { 176 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 177 | }, 178 | get 'Guilds'() { 179 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 180 | }, 181 | get 'SelectedGuilds'() { 182 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 183 | }, 184 | get 'SelectedChannels'() { 185 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 186 | }, 187 | get 'Info'() { 188 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 189 | }, 190 | get 'Status'() { 191 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 192 | }, 193 | get 'Users'() { 194 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 195 | }, 196 | get 'SettingsStore'() { 197 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 198 | }, 199 | get 'UserProfile'() { 200 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 201 | }, 202 | get 'Members'() { 203 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 204 | }, 205 | get 'Activities'() { 206 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 207 | }, 208 | get 'Games'() { 209 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 210 | }, 211 | get 'Auth'() { 212 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 213 | }, 214 | get 'TypingUsers'() { 215 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 216 | } 217 | }, 218 | '@discord/actions': { 219 | get 'ProfileActions'() { 220 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 221 | }, 222 | get 'GuildActions'() { 223 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 224 | } 225 | }, 226 | get '@discord/i18n'() { 227 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 228 | }, 229 | get '@discord/constants'() { 230 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 231 | }, 232 | get '@discord/contextmenu'() { 233 | return ___createMemoize___(this, '@discord/contextmenu', () => { 234 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 235 | ctx.Menu = ctx.default; 236 | return ctx; 237 | }) 238 | }, 239 | get '@discord/forms'() { 240 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 241 | }, 242 | get '@discord/scrollbars'() { 243 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 244 | }, 245 | get '@discord/native'() { 246 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 247 | }, 248 | get '@discord/flux'() { 249 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 250 | }, 251 | get '@discord/modal'() { 252 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 253 | }, 254 | get '@discord/connections'() { 255 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 256 | }, 257 | get '@discord/sanitize'() { 258 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 259 | }, 260 | get '@discord/icons'() { 261 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 262 | }, 263 | '@discord/classes': { 264 | get 'Timestamp'() { 265 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 266 | }, 267 | get 'Message'() { 268 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 269 | }, 270 | get 'User'() { 271 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 272 | }, 273 | get 'Channel'() { 274 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 275 | } 276 | } 277 | }; 278 | var __webpack_modules__ = { 279 | 113: module => { 280 | module.exports = BdApi.React; 281 | } 282 | }; 283 | var __webpack_module_cache__ = {}; 284 | function __webpack_require__(moduleId) { 285 | var cachedModule = __webpack_module_cache__[moduleId]; 286 | if (void 0 !== cachedModule) return cachedModule.exports; 287 | var module = __webpack_module_cache__[moduleId] = { 288 | exports: {} 289 | }; 290 | __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 291 | return module.exports; 292 | } 293 | (() => { 294 | __webpack_require__.n = module => { 295 | var getter = module && module.__esModule ? () => module["default"] : () => module; 296 | __webpack_require__.d(getter, { 297 | a: getter 298 | }); 299 | return getter; 300 | }; 301 | })(); 302 | (() => { 303 | __webpack_require__.d = (exports, definition) => { 304 | for (var key in definition) 305 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 306 | enumerable: true, 307 | get: definition[key] 308 | }); 309 | }; 310 | })(); 311 | (() => { 312 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 313 | })(); 314 | (() => { 315 | __webpack_require__.r = exports => { 316 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 317 | value: "Module" 318 | }); 319 | Object.defineProperty(exports, "__esModule", { 320 | value: true 321 | }); 322 | }; 323 | })(); 324 | var __webpack_exports__ = {}; 325 | (() => { 326 | __webpack_require__.r(__webpack_exports__); 327 | __webpack_require__.d(__webpack_exports__, { 328 | default: () => AssignBadges 329 | }); 330 | const external_PluginApi_namespaceObject = PluginApi; 331 | const external_BasePlugin_namespaceObject = BasePlugin; 332 | var external_BasePlugin_default = __webpack_require__.n(external_BasePlugin_namespaceObject); 333 | const contextmenu_namespaceObject = Modules["@discord/contextmenu"]; 334 | const external_PluginApi_DiscordModules_namespaceObject = PluginApi.DiscordModules; 335 | const { 336 | BadgeKeys 337 | } = external_PluginApi_namespaceObject.WebpackModules.getByProps("BadgeKeys"); 338 | const { 339 | UserFlags 340 | } = external_PluginApi_namespaceObject.WebpackModules.getByProps("UserFlags"); 341 | const UserFlagsFormatted = [{ 342 | id: "STAFF", 343 | value: UserFlags["STAFF"], 344 | name: "Discord Staff", 345 | key: BadgeKeys["STAFF"] 346 | }, { 347 | id: "PARTNER", 348 | value: UserFlags["PARTNER"], 349 | name: "Partnered Server Owner", 350 | key: BadgeKeys["PARTNER"] 351 | }, { 352 | id: "HYPESQUAD", 353 | value: UserFlags["HYPESQUAD"], 354 | name: "HypeSquad Events", 355 | key: BadgeKeys["HYPESQUAD"] 356 | }, { 357 | id: "HYPESQUAD_ONLINE_HOUSE_1", 358 | value: UserFlags["HYPESQUAD_ONLINE_HOUSE_1"], 359 | name: "House Bravery", 360 | key: BadgeKeys["HYPESQUAD_ONLINE_HOUSE_1"] 361 | }, { 362 | id: "HYPESQUAD_ONLINE_HOUSE_2", 363 | value: UserFlags["HYPESQUAD_ONLINE_HOUSE_2"], 364 | name: "House Brilliance", 365 | key: BadgeKeys["HYPESQUAD_ONLINE_HOUSE_2"] 366 | }, { 367 | id: "HYPESQUAD_ONLINE_HOUSE_3", 368 | value: UserFlags["HYPESQUAD_ONLINE_HOUSE_3"], 369 | name: "House Balance", 370 | key: BadgeKeys["HYPESQUAD_ONLINE_HOUSE_3"] 371 | }, { 372 | id: "EARLY_VERIFIED_BOT", 373 | value: 0, 374 | name: "Verified Bot", 375 | key: BadgeKeys["VERIFIED_BOT"] 376 | }, { 377 | id: "BUG_HUNTER_LEVEL_1", 378 | value: UserFlags["BUG_HUNTER_LEVEL_1"], 379 | name: "Bug Hunter Level 1", 380 | key: BadgeKeys["BUG_HUNTER_LEVEL_1"] 381 | }, { 382 | id: "BUG_HUNTER_LEVEL_2", 383 | value: UserFlags["BUG_HUNTER_LEVEL_2"], 384 | name: "Bug Hunter Level 2", 385 | key: BadgeKeys["BUG_HUNTER_LEVEL_2"] 386 | }, { 387 | id: "EARLY_SUPPORTER", 388 | value: UserFlags["PREMIUM_EARLY_SUPPORTER"], 389 | name: "Early Supporter", 390 | key: BadgeKeys["EARLY_SUPPORTER"] 391 | }, { 392 | id: "EARLY_VERIFIED_DEVELOPER", 393 | value: UserFlags["VERIFIED_DEVELOPER"], 394 | name: "Early Verified Bot Developer", 395 | key: BadgeKeys["EARLY_VERIFIED_DEVELOPER"] 396 | }, { 397 | id: "CERTIFIED_MODERATOR", 398 | value: UserFlags["CERTIFIED_MODERATOR"], 399 | name: "Discord Certified Moderator", 400 | key: BadgeKeys["CERTIFIED_MODERATOR"] 401 | }, { 402 | id: "PREMIUM", 403 | value: 0, 404 | name: "Nitro", 405 | key: BadgeKeys["PREMIUM"] 406 | }]; 407 | const modules_UserFlags = UserFlagsFormatted; 408 | const utils_namespaceObject = Modules["@discord/utils"]; 409 | var React = __webpack_require__(113); 410 | function _defineProperty(obj, key, value) { 411 | if (key in obj) Object.defineProperty(obj, key, { 412 | value, 413 | enumerable: true, 414 | configurable: true, 415 | writable: true 416 | }); 417 | else obj[key] = value; 418 | return obj; 419 | } 420 | const months = function(n) { 421 | return 26298e5 * n; 422 | }; 423 | const day = 864e5; 424 | const { 425 | MenuCheckboxItem, 426 | MenuRadioItem 427 | } = external_PluginApi_namespaceObject.WebpackModules.getByProps("MenuRadioItem"); 428 | const classes = { 429 | ...external_PluginApi_namespaceObject.WebpackModules.getByProps("executedCommand", "buttonContainer", "applicationName"), 430 | ...external_PluginApi_namespaceObject.WebpackModules.getByProps("container", "profileBadge18", "profileBadge22", "profileBadge22"), 431 | ...external_PluginApi_namespaceObject.WebpackModules.getByProps("member", "lostPermission") 432 | }; 433 | const memberlistClasses = external_PluginApi_namespaceObject.WebpackModules.getByProps("placeholder", "activity", "icon"); 434 | const getFlags = external_PluginApi_namespaceObject.WebpackModules.find((m => { 435 | let d = m.default.toString(); 436 | return ~d.indexOf("closeUserProfileModal") && ~d.indexOf("openPremiumSettings"); 437 | })); 438 | const User = external_PluginApi_namespaceObject.WebpackModules.getByPrototypes("getAvatarURL"); 439 | const BadgeList = external_PluginApi_namespaceObject.WebpackModules.getByProps("BadgeSizes").default; 440 | const boosts = [{ 441 | id: "boost1", 442 | value: 0 << 0, 443 | name: "Booster - 1 Month", 444 | time: 1.04 445 | }, { 446 | id: "boost2", 447 | value: 0 << 0, 448 | name: "Booster - 2 Months", 449 | time: 2.04 450 | }, { 451 | id: "boost3", 452 | value: 0 << 0, 453 | name: "Booster - 3 Months", 454 | time: 3.04 455 | }, { 456 | id: "boost4", 457 | value: 0 << 0, 458 | name: "Booster - 6 Months", 459 | time: 6.04 460 | }, { 461 | id: "boost5", 462 | value: 0 << 0, 463 | name: "Booster - 9 Months", 464 | time: 9.04 465 | }, { 466 | id: "boost6", 467 | value: 0 << 0, 468 | name: "Booster - 1 Year", 469 | time: 12.04 470 | }, { 471 | id: "boost7", 472 | value: 0 << 0, 473 | name: "Booster - 1 Year and 3 Months", 474 | time: 15.04 475 | }, { 476 | id: "boost8", 477 | value: 0 << 0, 478 | name: "Booster - 1 Year and 6 Months", 479 | time: 18.04 480 | }, { 481 | id: "boost9", 482 | value: 0 << 0, 483 | name: "Booster - 2 Years", 484 | time: 24.04 485 | }]; 486 | const BotTag = external_PluginApi_namespaceObject.WebpackModules.getByProps("BotTagTypes").default; 487 | const MessageAuthor = external_PluginApi_namespaceObject.WebpackModules.find((m => m.default.toString().indexOf("userOverride") > -1)); 488 | const NameTag = external_PluginApi_namespaceObject.WebpackModules.find((m => "DiscordTag" === m.default.displayName)); 489 | const flush = new Set; 490 | class AssignBadges extends(external_BasePlugin_default()) { 491 | constructor(...args) { 492 | super(...args); 493 | _defineProperty(this, "promises", { 494 | cancelled: false, 495 | cancel() { 496 | this.cancelled = true; 497 | } 498 | }); 499 | _defineProperty(this, "patches", []); 500 | } 501 | onStart() { 502 | this.patchUserContextMenus(); 503 | this.patchUserFlagGetter(); 504 | this.patchUserStore(); 505 | this.patchMessageAuthor(); 506 | this.patchNameTag(); 507 | this.patchMemberlistItem(); 508 | } 509 | onStop() { 510 | external_PluginApi_namespaceObject.Patcher.unpatchAll(); 511 | flush.forEach((f => f())); 512 | } 513 | isUserVerifiedBot(user) { 514 | const settings = this.getSettings(); 515 | const userSettings = settings?.[user.id]; 516 | if (userSettings && userSettings?.EARLY_VERIFIED_BOT) return true; 517 | return false; 518 | } 519 | patchUserFlagGetter() { 520 | external_PluginApi_namespaceObject.Patcher.before(getFlags, "default", ((_this, [props]) => { 521 | const settings = this.getSettings()?.[props.user.id]; 522 | if (settings) 523 | if (true === settings?.PREMIUM) props.premiumSince = new Date(0); 524 | if (settings?.boost) { 525 | const boost = boosts[boosts.findIndex((e => e.id === settings.boost))]; 526 | props.premiumGuildSince = new Date(Date.now() - months(boost.time) - day); 527 | } 528 | })); 529 | } 530 | patchUserStore() { 531 | external_PluginApi_namespaceObject.Patcher.after(external_PluginApi_DiscordModules_namespaceObject.UserStore, "getUser", ((_this, [id], ret) => { 532 | const settings = this.getSettings(); 533 | const userSettings = settings?.[id]; 534 | if (userSettings) { 535 | const newFlags = Object.keys(userSettings).filter((e => userSettings[e])).map((e => modules_UserFlags.find((f => f.id === e)))).filter((e => e)).map((e => e.value)).reduce(((a, b) => a + b), 0); 536 | ret.publicFlags = newFlags; 537 | } 538 | })); 539 | } 540 | patchMessageAuthor() { 541 | external_PluginApi_namespaceObject.Patcher.after(MessageAuthor, "default", ((_this, [props], ret) => { 542 | const user = props.message.author; 543 | if (!user) return; 544 | if (this.isUserVerifiedBot(user)) { 545 | const badgeIndex = props.compact ? 0 : 4; 546 | const displayClass = props.compact ? classes.botTagCompact : classes.botTagCozy; 547 | ret.props.children[badgeIndex] = React.createElement(BotTag, { 548 | verified: true, 549 | className: (0, utils_namespaceObject.joinClassNames)(displayClass, classes.botTag) 550 | }); 551 | } 552 | })); 553 | } 554 | patchNameTag() { 555 | external_PluginApi_namespaceObject.Patcher.after(NameTag, "default", ((_this, [props], ret) => { 556 | const user = props.user; 557 | if (!user) return; 558 | if (this.isUserVerifiedBot(user)) { 559 | ret.props.botType = 0; 560 | ret.props.botVerified = true; 561 | } 562 | })); 563 | } 564 | async patchMemberlistItem() { 565 | const MemberListItem = await external_PluginApi_namespaceObject.ReactComponents.getComponentByName("MemberListItem", `.${classes.member}`); 566 | external_PluginApi_namespaceObject.Patcher.after(MemberListItem.component.prototype, "renderDecorators", (({ 567 | props 568 | }, _, returnValue) => { 569 | try { 570 | const tree = returnValue?.props?.children; 571 | if (!Array.isArray(tree)) return; 572 | if (this.isUserVerifiedBot(props.user)) tree[0] = React.createElement(BotTag, { 573 | verified: true, 574 | className: memberlistClasses.botTag 575 | }); 576 | } catch (error) { 577 | console.error("Error while patching MemberListItem:", error); 578 | } 579 | })); 580 | MemberListItem.forceUpdateAll(); 581 | } 582 | async patchUserContextMenus() { 583 | const getMenu = props => { 584 | const settings = this.getSettings(); 585 | const propsUser = external_PluginApi_DiscordModules_namespaceObject.UserStore.getUser(props); 586 | props = { 587 | user: propsUser 588 | }; 589 | const userBadges = getFlags.default({ 590 | user: propsUser 591 | }).map((badge => badge?.key)); 592 | const [selectedBoost, setSelectedBoost] = React.useState(settings[props.user.id]?.boost); 593 | return React.createElement(contextmenu_namespaceObject.MenuItem, { 594 | id: "assign-badge", 595 | key: "assign-badge", 596 | label: "Manage Badges", 597 | children: [modules_UserFlags.map((flag => { 598 | const [state, setState] = React.useState(settings?.[props.user.id]?.hasOwnProperty(flag.id) ? settings?.[props.user.id]?.[flag.id] : ~userBadges.indexOf(flag.key)); 599 | return React.createElement(MenuCheckboxItem, { 600 | id: flag.id, 601 | label: "EARLY_VERIFIED_BOT" !== flag.id ? React.createElement("div", { 602 | className: classes?.container 603 | }, React.createElement(BadgeList, { 604 | user: this.fakeUser(flag.value), 605 | premiumSince: "PREMIUM" === flag.id ? new Date(0) : null, 606 | size: 2 607 | }), flag.name) : React.createElement("div", { 608 | className: classes?.container 609 | }, React.createElement(BotTag, { 610 | verified: true 611 | })), 612 | checked: state, 613 | action: () => { 614 | const user = settings[props.user.id] || {}; 615 | user[flag.id] = !state; 616 | settings[props.user.id] = user; 617 | this.saveSettings(settings); 618 | setState(!state); 619 | } 620 | }); 621 | })), React.createElement(contextmenu_namespaceObject.MenuItem, { 622 | id: "boosts", 623 | label: React.createElement("div", { 624 | className: classes?.container 625 | }, React.createElement(BadgeList, { 626 | user: this.fakeUser(0), 627 | premiumGuildSince: new Date(Date.now() - months(3) - day), 628 | size: 2 629 | }), "Boosts") 630 | }, [boosts.map((boost => React.createElement(MenuRadioItem, { 631 | id: boost.id, 632 | checked: selectedBoost === boost.id, 633 | label: React.createElement("div", { 634 | className: classes?.container 635 | }, React.createElement(BadgeList, { 636 | user: this.fakeUser(0), 637 | premiumGuildSince: new Date(Date.now() - months(boost.time) - day), 638 | size: 2 639 | }), boost.name), 640 | action: () => { 641 | const user = settings[props.user.id] || {}; 642 | user.boost = boost.id; 643 | setSelectedBoost(boost.id); 644 | settings[props.user.id] = user; 645 | this.saveSettings(settings); 646 | } 647 | }))), React.createElement(contextmenu_namespaceObject.MenuGroup, null, React.createElement(contextmenu_namespaceObject.MenuItem, { 648 | label: "Reset Boost Preferences", 649 | id: "reset-boosts", 650 | color: "colorDanger", 651 | action: () => { 652 | delete settings[props.user.id]?.boost; 653 | this.saveSettings(settings); 654 | external_PluginApi_namespaceObject.Toasts.success(`Successfully cleared boost preferences for ${props.user}!`); 655 | } 656 | }))]), React.createElement(contextmenu_namespaceObject.MenuGroup, null, React.createElement(contextmenu_namespaceObject.MenuItem, { 657 | color: "colorDanger", 658 | label: "Reset Preferences", 659 | id: "reset", 660 | action: () => { 661 | delete settings[props.user.id]; 662 | this.saveSettings(settings); 663 | settings[props.user.id] = {}; 664 | external_PluginApi_namespaceObject.Toasts.success(`Successfully cleared preferences for ${props.user}!`); 665 | } 666 | }))] 667 | }); 668 | }; 669 | class Utils { 670 | static combine(...filters) { 671 | return (...args) => filters.every((filter => filter(...args))); 672 | } 673 | } 674 | function findContextMenu(displayName, filter = (() => true)) { 675 | const regex = new RegExp(displayName, "i"); 676 | const normalFilter = exports => exports && exports.default && regex.test(exports.default.displayName) && filter(exports.default); 677 | const nestedFilter = module => regex.test(module.toString()); { 678 | const normalCache = external_PluginApi_namespaceObject.WebpackModules.getModule(Utils.combine(normalFilter, (e => filter(e.default)))); 679 | if (normalCache) return { 680 | type: "normal", 681 | module: normalCache 682 | }; 683 | } { 684 | const webpackId = Object.keys(external_PluginApi_namespaceObject.WebpackModules.require.m).find((id => nestedFilter(external_PluginApi_namespaceObject.WebpackModules.require.m[id]))); 685 | const nestedCache = void 0 !== webpackId && external_PluginApi_namespaceObject.WebpackModules.getByIndex(webpackId); 686 | if (nestedCache && filter(nestedCache?.default)) return { 687 | type: "nested", 688 | module: nestedCache 689 | }; 690 | } 691 | return new Promise((resolve => { 692 | const cancel = () => external_PluginApi_namespaceObject.WebpackModules.removeListener(listener); 693 | const listener = (exports, module) => { 694 | const normal = normalFilter(exports); 695 | const nested = nestedFilter(module); 696 | if (!nested && !normal || !filter(exports?.default)) return; 697 | resolve({ 698 | type: normal ? "normal" : "nested", 699 | module: exports 700 | }); 701 | external_PluginApi_namespaceObject.WebpackModules.removeListener(listener); 702 | flush.delete(cancel); 703 | }; 704 | external_PluginApi_namespaceObject.WebpackModules.addListener(listener); 705 | flush.add(cancel); 706 | })); 707 | } 708 | const patched = new Set; 709 | const REGEX = /displayName="\S+?usercontextmenu./i; 710 | const originalSymbol = Symbol("AssignBadges Original"); 711 | const search = async () => { 712 | const Menu = await findContextMenu(REGEX, (m => !patched.has(m))); 713 | if (this.promises.cancelled) return; 714 | const patch = (rendered, props) => { 715 | const children = external_PluginApi_namespaceObject.Utilities.findInReactTree(rendered, Array.isArray); 716 | const user = props.user || external_PluginApi_DiscordModules_namespaceObject.UserStore.getUser(props.channel?.getRecipientId?.()); 717 | if (!children || !user || children.some((c => c && "assign-badge" === c.key))) return rendered; 718 | children.splice(7, 0, getMenu(user.id)); 719 | }; 720 | function AnalyticsWrapper(props) { 721 | const rendered = props[originalSymbol].call(this, props); 722 | try { 723 | patch(rendered, props); 724 | } catch (error) { 725 | cancel(); 726 | console.error("Error in AnalyticsWrapper:", error); 727 | } 728 | return rendered; 729 | } 730 | let original = null; 731 | function ContextMenuWrapper(props, _, rendered) { 732 | rendered ??= original.call(this, props); 733 | try { 734 | if (rendered?.props?.children?.type?.displayName.indexOf("ContextMenu") > 0) { 735 | const child = rendered.props.children; 736 | child.props[originalSymbol] = child.type; 737 | AnalyticsWrapper.displayName = child.type.displayName; 738 | child.type = AnalyticsWrapper; 739 | return rendered; 740 | } 741 | patch(rendered, props); 742 | } catch (error) { 743 | cancel(); 744 | console.error("Error in ContextMenuWrapper:", error); 745 | } 746 | return rendered; 747 | } 748 | const cancel = external_PluginApi_namespaceObject.Patcher.after(Menu.module, "default", ((_, [props], ret) => { 749 | const contextMenu = external_PluginApi_namespaceObject.Utilities.getNestedProp(ret, "props.children"); 750 | if (!contextMenu || "function" !== typeof contextMenu.type) return; 751 | original ??= contextMenu.type; 752 | ContextMenuWrapper.displayName ??= original.displayName; 753 | contextMenu.type = ContextMenuWrapper; 754 | })); 755 | patched.add(Menu.module.default); 756 | search(); 757 | }; 758 | search(); 759 | } 760 | fakeUser(flags) { 761 | return new User({ 762 | id: 1337, 763 | username: "Lana", 764 | publicFlags: flags 765 | }); 766 | } 767 | getSettings() { 768 | return external_PluginApi_namespaceObject.PluginUtilities.loadSettings(this.constructor.name, {}); 769 | } 770 | saveSettings(settings) { 771 | external_PluginApi_namespaceObject.PluginUtilities.saveSettings(this.constructor.name, settings); 772 | } 773 | } 774 | })(); 775 | module.exports.LibraryPluginHack = __webpack_exports__; 776 | })(); 777 | const PluginExports = module.exports.LibraryPluginHack; 778 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 779 | } 780 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 781 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 782 | class { 783 | getName() { 784 | return config.info.name; 785 | } 786 | getAuthor() { 787 | return config.info.authors.map(a => a.name).join(", "); 788 | } 789 | getDescription() { 790 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 791 | } 792 | getVersion() { 793 | return config.info.version; 794 | } 795 | load() { 796 | BdApi.showConfirmationModal( 797 | "Library plugin is needed", 798 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 799 | confirmText: "Download", 800 | cancelText: "Cancel", 801 | onConfirm: () => { 802 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 803 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 804 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 805 | }); 806 | } 807 | } 808 | ); 809 | } 810 | start() {} 811 | stop() {} 812 | }; 813 | /*@end@*/ -------------------------------------------------------------------------------- /AssignBadges/README.md: -------------------------------------------------------------------------------- 1 | # AssignBadges 2 | 3 | > Allows you to locally assign badges to users through the user context menu. 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /CallTimeCounter/CallTimeCounter.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name CallTimeCounter 3 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/blob/main/CallTimeCounter/CallTimeCounter.plugin.js 4 | * @description Shows how much time you are in a voice chat. 5 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/CallTimeCounter/CallTimeCounter.plugin.js 6 | * @website https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/CallTimeCounter 7 | * @version 0.0.6 8 | */ 9 | 10 | const request = require("request"); 11 | const fs = require("fs"); 12 | const path = require("path"); 13 | 14 | const config = { 15 | info: { 16 | name: "CallTimeCounter", 17 | authors: [ 18 | { 19 | name: "QWERT" 20 | } 21 | ], 22 | version: "0.0.6", 23 | description: "Shows how much time you are in a voice chat.", 24 | github_raw: "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/CallTimeCounter/CallTimeCounter.plugin.js", 25 | }, 26 | changelog: [ 27 | { 28 | title: "Fixes", 29 | type: "fixed", 30 | items: [ 31 | "Fixed for BetterDiscord 1.8 update." 32 | ] 33 | } 34 | ], 35 | defaultConfig: [] 36 | }; 37 | 38 | module.exports = !global.ZeresPluginLibrary ? class { 39 | constructor() { 40 | this._config = config; 41 | } 42 | 43 | load() { 44 | BdApi.showConfirmationModal("Library plugin is needed", 45 | `The library plugin needed for AQWERT'sPluginBuilder is missing. Please click Download Now to install it.`, { 46 | confirmText: "Download", 47 | cancelText: "Cancel", 48 | onConfirm: () => { 49 | request.get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", (error, response, body) => { 50 | if (error) 51 | return electron.shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 52 | 53 | fs.writeFileSync(path.join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body); 54 | }); 55 | } 56 | }); 57 | } 58 | 59 | start() { } 60 | 61 | stop() { } 62 | } : (([Plugin, Library]) => { 63 | const { DiscordModules, WebpackModules, Patcher, PluginUtilities } = Library; 64 | const { React, SelectedChannelStore: {getVoiceChannelId} } = DiscordModules; 65 | const PanelSubtext = WebpackModules.find(m => m?.$$typeof?.toString() === "Symbol(react.forward_ref)" 66 | && m.render?.toString().includes("createHref"), {searchExports: true}); 67 | let lastVoice, lastState; 68 | const Dispatcher = WebpackModules.getByProps('dispatch', 'register'); 69 | 70 | class Timer extends React.Component { 71 | constructor(props) { 72 | super(props); 73 | this.connected = this.connected.bind(this); 74 | this.state = { 75 | startTime: 0, 76 | delta: 0 77 | }; 78 | } 79 | 80 | connected(e) { 81 | if (e.state && e.state === 'RTC_DISCONNECTED' && !e.hasOwnProperty('streamKey')) { 82 | this.setState((prev) => ( 83 | prev.startTime = Date.now())); 84 | } 85 | } 86 | 87 | componentDidMount() { 88 | if(lastVoice === getVoiceChannelId()) { 89 | Dispatcher.subscribe('RTC_CONNECTION_STATE', this.connected); 90 | this.setState(lastState); 91 | this.interval = setInterval(() => { 92 | this.setState((prev) => (prev.delta = Math.round((Date.now() - prev.startTime) / 1000) * 1000)); 93 | this.setState((prev) => prev.lastVoice = getVoiceChannelId()); 94 | }, 1000); 95 | }else{ 96 | this.setState((prev) => ( 97 | prev.startTime = Date.now())); 98 | Dispatcher.subscribe('RTC_CONNECTION_STATE', this.connected); 99 | this.interval = setInterval(() => { 100 | this.setState((prev) => (prev.delta = Math.round((Date.now() - prev.startTime) / 1000) * 1000)); 101 | this.setState((prev) => prev.lastVoice = getVoiceChannelId()); 102 | }, 1000); 103 | } 104 | } 105 | 106 | componentWillUnmount() { 107 | Dispatcher.unsubscribe('RTC_CONNECTION_STATE', this.connected); 108 | lastVoice = this.state.lastVoice; 109 | lastState = this.state; 110 | setTimeout(() => { 111 | lastVoice = null; 112 | lastState = {}; 113 | }, 1000) 114 | clearInterval(this.interval); 115 | } 116 | 117 | render() { 118 | return React.createElement("div", { className: "voiceTimer" }, `Time elapsed: ${new Date(this.state.delta).toISOString().substr(11, 8)}`); 119 | } 120 | }; 121 | 122 | class plugin extends Plugin { 123 | constructor() { 124 | super(); 125 | } 126 | 127 | 128 | onStart() { 129 | this.patch(); 130 | 131 | PluginUtilities.addStyle("voicetimer", ` 132 | .voiceTimer { 133 | text-decoration: none !important; 134 | margin-top: 8px; 135 | } 136 | `) 137 | } 138 | 139 | onStop() { 140 | Patcher.unpatchAll(); 141 | PluginUtilities.removeStyle("voicetimer"); 142 | } 143 | 144 | patch() { 145 | Patcher.before(PanelSubtext, "render", (_, [props], ret) => { 146 | if (!props?.children?.props?.className?.includes("channel")) return; 147 | props.children.props.children = [ 148 | props.children.props.children, 149 | React.createElement(Timer, { className: "voiceTimer" }) 150 | ] 151 | }); 152 | } 153 | 154 | } 155 | 156 | return plugin; 157 | })(global.ZeresPluginLibrary.buildPlugin(config)); 158 | -------------------------------------------------------------------------------- /CallTimeCounter/README.md: -------------------------------------------------------------------------------- 1 | # Call Time Counter 2 | [![Download][icon]][link] 3 | 4 | Shows how much time you are in a voice chat. 5 | 6 | A port of [VCTimer by Rasync](https://github.com/RazerMoon/vcTimer) (for Powercord) to BetterDiscord 7 | ### Preview 8 | ![Preview](https://cdn.discordapp.com/attachments/777957545439920138/842109412960894986/unknown.png) 9 | 10 | [icon]: https://img.shields.io/badge/Download-Call%20Time%20Counter-brightgreen.svg 11 | [link]: https://betterdiscord.app/plugin/CallTimeCounter -------------------------------------------------------------------------------- /ClickToCopyUsername/ClickToCopyUsername.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name ClickToCopyUsername 3 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/blob/main/ClickToCopyUsername/ClickToCopyUsername.plugin.js 4 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/ClickToCopyUsername/ClickToCopyUsername.plugin.js 5 | * @website https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/ClickToCopyUsername 6 | * @version 0.0.2 7 | */ 8 | 9 | const request = require("request"); 10 | const fs = require("fs"); 11 | const path = require("path"); 12 | 13 | const config = { 14 | info: { 15 | name: "ClickToCopyUsername", 16 | authors: [ 17 | { 18 | name: "QWERT" 19 | } 20 | ], 21 | version: "0.0.2", 22 | description: "Allows you to copy someone's username by pressing their nametag, like on mobile.", 23 | github_raw: "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/ClickToCopyUsername/ClickToCopyUsername.plugin.js", 24 | }, 25 | changelog: [ 26 | { 27 | title: "hello world", 28 | type: "added", 29 | items: [ 30 | "plugin" 31 | ] 32 | } 33 | ], 34 | defaultConfig: [] 35 | }; 36 | 37 | module.exports = !global.ZeresPluginLibrary ? class { 38 | constructor() { 39 | this._config = config; 40 | } 41 | 42 | load() { 43 | BdApi.showConfirmationModal("Library plugin is needed", 44 | `The library plugin needed for AQWERT'sPluginBuilder is missing. Please click Download Now to install it.`, { 45 | confirmText: "Download", 46 | cancelText: "Cancel", 47 | onConfirm: () => { 48 | request.get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", (error, response, body) => { 49 | if (error) 50 | return electron.shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 51 | 52 | fs.writeFileSync(path.join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body); 53 | }); 54 | } 55 | }); 56 | } 57 | 58 | start() { } 59 | 60 | stop() { } 61 | } : (([Plugin, Library]) => { 62 | const { DiscordModules, WebpackModules, Patcher, PluginUtilities, Toasts } = Library; 63 | const { ElectronModule, React } = DiscordModules; 64 | class plugin extends Plugin { 65 | constructor() { 66 | super(); 67 | } 68 | 69 | 70 | onStart() { 71 | this.patchNameTag(); 72 | } 73 | 74 | onStop() { 75 | Patcher.unpatchAll(); 76 | } 77 | 78 | patchNameTag() { 79 | const NameTag = WebpackModules.find(m => m?.default?.displayName === "NameTag"); 80 | Patcher.after(NameTag, "default", (_, [props], ret) => { 81 | ret.props.style = { 82 | cursor: "pointer" 83 | } 84 | ret.props.onClick = _ => { 85 | ElectronModule.copy(`${props.name}#${props.discriminator}`); 86 | Toasts.success(`Successfully copied username for ${props.name}!`); 87 | }; 88 | }) 89 | } 90 | 91 | } 92 | 93 | return plugin; 94 | })(global.ZeresPluginLibrary.buildPlugin(config)); 95 | -------------------------------------------------------------------------------- /ClickToCopyUsername/README.md: -------------------------------------------------------------------------------- 1 | # ClickToCopyUsername 2 | [![Download][icon]][link] 3 | 4 | Allows you to copy someone's username by pressing their nametag, like on mobile. 5 | 6 | [icon]: https://img.shields.io/badge/Download-ClickToCopyUsername-brightgreen.svg 7 | [link]: https://betterdiscord.net/ghdl?id=3600 8 | -------------------------------------------------------------------------------- /CopyRoleColors/CopyRoleColors.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name CopyRoleColors 3 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/blob/main/CopyRoleColors/CopyRoleColors.plugin.js 4 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/CopyRoleColors/CopyRoleColors.plugin.js 5 | * @website https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/CopyRoleColors 6 | * @version 0.0.4 7 | */ 8 | 9 | const request = require("request"); 10 | const fs = require("fs"); 11 | const path = require("path"); 12 | 13 | const config = { 14 | info: { 15 | name: "CopyRoleColors", 16 | authors: [ 17 | { 18 | name: "QWERT", 19 | }, 20 | ], 21 | version: "0.0.4", 22 | description: "Adds option to copy role color in the role context menu.", 23 | github_raw: "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/CopyRoleColors/CopyRoleColors.plugin.js", 24 | }, 25 | changelog: [ 26 | { 27 | title: "Fixed v2", 28 | type: "fixed v2", 29 | items: ["Fixed a bug where the plugin would crash."], 30 | }, 31 | ], 32 | defaultConfig: [], 33 | }; 34 | 35 | module.exports = !global.ZeresPluginLibrary 36 | ? class { 37 | constructor() { 38 | this._config = config; 39 | } 40 | 41 | load() { 42 | BdApi.showConfirmationModal( 43 | "Library plugin is needed", 44 | `The library plugin needed for AQWERT'sPluginBuilder is missing. Please click Download Now to install it.`, 45 | { 46 | confirmText: "Download", 47 | cancelText: "Cancel", 48 | onConfirm: () => { 49 | request.get( 50 | "https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", 51 | (error, response, body) => { 52 | if (error) 53 | return electron.shell.openExternal( 54 | "https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js" 55 | ); 56 | 57 | fs.writeFileSync( 58 | path.join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), 59 | body 60 | ); 61 | } 62 | ); 63 | }, 64 | } 65 | ); 66 | } 67 | 68 | start() {} 69 | 70 | stop() {} 71 | } 72 | : (([Plugin, Library]) => { 73 | const { DiscordModules, WebpackModules, Toasts, Patcher, ContextMenu } = 74 | Library; 75 | const { Strings, ElectronModule } = DiscordModules; 76 | const MemberRole = WebpackModules.getByProps("MemberRole").MemberRole; 77 | 78 | class plugin extends Plugin { 79 | constructor() { 80 | super(); 81 | } 82 | 83 | onStart() { 84 | this.patch(); 85 | } 86 | 87 | onStop() { 88 | Patcher.unpatchAll(); 89 | } 90 | 91 | patch() { 92 | Patcher.after(MemberRole, "render", (_, [props], ret) => { 93 | console.log({ props, ret }); 94 | const newContextMenu = ContextMenu.buildMenu([ 95 | { 96 | label: "Copy Role Color", 97 | action: (_) => { 98 | ElectronModule.copy(props.role.colorString || "#b9bbbe"); 99 | Toasts.success( 100 | `Successfully copied role color for ${props.role.name}!` 101 | ); 102 | }, 103 | }, 104 | { 105 | type: "separator", 106 | }, 107 | { 108 | id: "copy-id", 109 | label: Strings.Messages.COPY_ID, 110 | action: (_) => { 111 | ElectronModule.copy(props.role.id); 112 | }, 113 | }, 114 | ]); 115 | 116 | ret.props.children.props.onContextMenu = (e) => { 117 | ContextMenu.openContextMenu(e, newContextMenu); 118 | }; 119 | }); 120 | } 121 | } 122 | 123 | return plugin; 124 | })(global.ZeresPluginLibrary.buildPlugin(config)); 125 | -------------------------------------------------------------------------------- /CopyRoleColors/README.md: -------------------------------------------------------------------------------- 1 | # CopyRoleColors 2 | [![Download][icon]][link] 3 | 4 | Adds option to copy role color in the role context menu. 5 | 6 | [icon]: https://img.shields.io/badge/Download-CopyRoleColors-brightgreen.svg 7 | [link]: https://betterdiscord.net/ghdl?id=3601 8 | -------------------------------------------------------------------------------- /DiscordActivities/DiscordActivities.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name DiscordActivities 3 | * @version 1.1.2 4 | * @description Allows you to play Discord's Activity Games (Such as watching YouTube together and Chess) with friends in voice chats. 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/DiscordActivities 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/DiscordActivities/DiscordActivities.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "DiscordActivities", 35 | "version": "1.1.2", 36 | "description": "Allows you to play Discord's Activity Games (Such as watching YouTube together and Chess) with friends in voice chats.", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/DiscordActivities", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/DiscordActivities/DiscordActivities.plugin.js" 44 | }, 45 | "build": { 46 | "zlibrary": true, 47 | "copy": true, 48 | "production": false, 49 | "scssHash": false, 50 | "alias": { 51 | "components": "components/index.js" 52 | }, 53 | "release": { 54 | "source": true, 55 | "readme": true, 56 | "public": true, 57 | "previews": [{ 58 | "name": "Call Panel", 59 | "src": "./assets/call.png" 60 | }, 61 | { 62 | "name": "Poker Night Activity", 63 | "src": "./assets/pokernight.png" 64 | } 65 | ] 66 | } 67 | } 68 | }; 69 | function buildPlugin([BasePlugin, PluginApi]) { 70 | const module = { 71 | exports: {} 72 | }; 73 | (() => { 74 | "use strict"; 75 | class StyleLoader { 76 | static styles = ""; 77 | static element = null; 78 | static append(module, css) { 79 | this.styles += `/* ${module} */\n${css}`; 80 | } 81 | static inject(name = config.info.name) { 82 | if (this.element) this.element.remove(); 83 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 84 | id: name, 85 | textContent: this.styles 86 | })); 87 | } 88 | static remove() { 89 | if (this.element) { 90 | this.element.remove(); 91 | this.element = null; 92 | } 93 | } 94 | } 95 | function ___createMemoize___(instance, name, value) { 96 | value = value(); 97 | Object.defineProperty(instance, name, { 98 | value, 99 | configurable: true 100 | }); 101 | return value; 102 | }; 103 | const Modules = { 104 | get 'react-spring'() { 105 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 106 | }, 107 | '@discord/utils': { 108 | get 'joinClassNames'() { 109 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 110 | }, 111 | get 'useForceUpdate'() { 112 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 113 | }, 114 | get 'Logger'() { 115 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 116 | }, 117 | get 'Navigation'() { 118 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 119 | } 120 | }, 121 | '@discord/components': { 122 | get 'Tooltip'() { 123 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 124 | }, 125 | get 'TooltipContainer'() { 126 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 127 | }, 128 | get 'TextInput'() { 129 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 130 | }, 131 | get 'SlideIn'() { 132 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 133 | }, 134 | get 'SettingsNotice'() { 135 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 136 | }, 137 | get 'TransitionGroup'() { 138 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 139 | }, 140 | get 'Button'() { 141 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 142 | }, 143 | get 'Popout'() { 144 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 145 | }, 146 | get 'Flex'() { 147 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 148 | }, 149 | get 'Text'() { 150 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('Text')) 151 | }, 152 | get 'Card'() { 153 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 154 | } 155 | }, 156 | '@discord/modules': { 157 | get 'Dispatcher'() { 158 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dirtyDispatch', 'subscribe')) 159 | }, 160 | get 'ComponentDispatcher'() { 161 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 162 | }, 163 | get 'EmojiUtils'() { 164 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 165 | }, 166 | get 'PermissionUtils'() { 167 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 168 | }, 169 | get 'DMUtils'() { 170 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 171 | } 172 | }, 173 | '@discord/stores': { 174 | get 'Messages'() { 175 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 176 | }, 177 | get 'Channels'() { 178 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 179 | }, 180 | get 'Guilds'() { 181 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 182 | }, 183 | get 'SelectedGuilds'() { 184 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 185 | }, 186 | get 'SelectedChannels'() { 187 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 188 | }, 189 | get 'Info'() { 190 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 191 | }, 192 | get 'Status'() { 193 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 194 | }, 195 | get 'Users'() { 196 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 197 | }, 198 | get 'SettingsStore'() { 199 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 200 | }, 201 | get 'UserProfile'() { 202 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 203 | }, 204 | get 'Members'() { 205 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 206 | }, 207 | get 'Activities'() { 208 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 209 | }, 210 | get 'Games'() { 211 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 212 | }, 213 | get 'Auth'() { 214 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 215 | }, 216 | get 'TypingUsers'() { 217 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 218 | } 219 | }, 220 | '@discord/actions': { 221 | get 'ProfileActions'() { 222 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 223 | }, 224 | get 'GuildActions'() { 225 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 226 | } 227 | }, 228 | get '@discord/i18n'() { 229 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 230 | }, 231 | get '@discord/constants'() { 232 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 233 | }, 234 | get '@discord/contextmenu'() { 235 | return ___createMemoize___(this, '@discord/contextmenu', () => { 236 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 237 | ctx.Menu = ctx.default; 238 | return ctx; 239 | }) 240 | }, 241 | get '@discord/forms'() { 242 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 243 | }, 244 | get '@discord/scrollbars'() { 245 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 246 | }, 247 | get '@discord/native'() { 248 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 249 | }, 250 | get '@discord/flux'() { 251 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 252 | }, 253 | get '@discord/modal'() { 254 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 255 | }, 256 | get '@discord/connections'() { 257 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 258 | }, 259 | get '@discord/sanitize'() { 260 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 261 | }, 262 | get '@discord/icons'() { 263 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 264 | }, 265 | '@discord/classes': { 266 | get 'Timestamp'() { 267 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 268 | }, 269 | get 'Message'() { 270 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 271 | }, 272 | get 'User'() { 273 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 274 | }, 275 | get 'Channel'() { 276 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 277 | } 278 | } 279 | }; 280 | var __webpack_require__ = {}; 281 | (() => { 282 | __webpack_require__.n = module => { 283 | var getter = module && module.__esModule ? () => module["default"] : () => module; 284 | __webpack_require__.d(getter, { 285 | a: getter 286 | }); 287 | return getter; 288 | }; 289 | })(); 290 | (() => { 291 | __webpack_require__.d = (exports, definition) => { 292 | for (var key in definition) 293 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 294 | enumerable: true, 295 | get: definition[key] 296 | }); 297 | }; 298 | })(); 299 | (() => { 300 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 301 | })(); 302 | (() => { 303 | __webpack_require__.r = exports => { 304 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 305 | value: "Module" 306 | }); 307 | Object.defineProperty(exports, "__esModule", { 308 | value: true 309 | }); 310 | }; 311 | })(); 312 | var __webpack_exports__ = {}; 313 | __webpack_require__.r(__webpack_exports__); 314 | __webpack_require__.d(__webpack_exports__, { 315 | default: () => DiscordActivities 316 | }); 317 | const external_PluginApi_namespaceObject = PluginApi; 318 | const external_PluginApi_DiscordModules_namespaceObject = PluginApi.DiscordModules; 319 | const external_BasePlugin_namespaceObject = BasePlugin; 320 | var external_BasePlugin_default = __webpack_require__.n(external_BasePlugin_namespaceObject); 321 | const activities = external_PluginApi_namespaceObject.WebpackModules.getByProps("getSelfEmbeddedActivities"); 322 | class DiscordActivities extends(external_BasePlugin_default()) { 323 | onStart() { 324 | this.patchGuildRegion(); 325 | this.patchEnabledAppIds(); 326 | } 327 | onStop() { 328 | external_PluginApi_namespaceObject.Patcher.unpatchAll(); 329 | } 330 | patchGuildRegion() { 331 | external_PluginApi_namespaceObject.Patcher.after(external_PluginApi_DiscordModules_namespaceObject.GuildStore, "getGuild", ((_this, [props], ret) => { 332 | if (!ret?.region) return; 333 | ret.region = "us-west"; 334 | })); 335 | } 336 | patchEnabledAppIds() { 337 | const applicationIds = ["755827207812677713", "832012774040141894", "832013003968348200", "878067389634314250", "879863976006127627", "879863686565621790", "852509694341283871", "880218394199220334", "773336526917861400", "814288819477020702", "879864070101172255", "879863881349087252", "832012854282158180", "763133495793942528", "880218832743055411", "878067427668275241", "879864010126786570", "879864104980979792", "891001866073296967", "832012586023256104", "832012682520428625", "832013108234289153"]; 338 | external_PluginApi_namespaceObject.Patcher.instead(activities, "getEnabledAppIds", (function() { 339 | return applicationIds; 340 | })); 341 | } 342 | } 343 | module.exports.LibraryPluginHack = __webpack_exports__; 344 | })(); 345 | const PluginExports = module.exports.LibraryPluginHack; 346 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 347 | } 348 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 349 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 350 | class { 351 | getName() { 352 | return config.info.name; 353 | } 354 | getAuthor() { 355 | return config.info.authors.map(a => a.name).join(", "); 356 | } 357 | getDescription() { 358 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 359 | } 360 | getVersion() { 361 | return config.info.version; 362 | } 363 | load() { 364 | BdApi.showConfirmationModal( 365 | "Library plugin is needed", 366 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 367 | confirmText: "Download", 368 | cancelText: "Cancel", 369 | onConfirm: () => { 370 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 371 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 372 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 373 | }); 374 | } 375 | } 376 | ); 377 | } 378 | start() {} 379 | stop() {} 380 | }; 381 | /*@end@*/ -------------------------------------------------------------------------------- /DiscordActivities/README.md: -------------------------------------------------------------------------------- 1 | # DiscordActivities 2 | 3 | > Allows you to play Discord's Activity Games (Such as watching YouTube together and Chess) with friends in voice chats. 4 |
5 | 6 | 7 | # Previews 8 | 9 | ## Call Panel 10 | ![image](https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/DiscordActivities/./assets/call.png) 11 |
12 | 13 | ## Poker Night Activity 14 | ![image](https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/DiscordActivities/./assets/pokernight.png) 15 | 16 |
17 | Made with by BDBuilder -------------------------------------------------------------------------------- /DiscordActivities/assets/call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/717e9b711723c535157e3227b28ef24d44eaa105/DiscordActivities/assets/call.png -------------------------------------------------------------------------------- /DiscordActivities/assets/pokernight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/717e9b711723c535157e3227b28ef24d44eaa105/DiscordActivities/assets/pokernight.png -------------------------------------------------------------------------------- /DndWhilePlaying/DndWhilePlaying.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name DndWhilePlaying 3 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/blob/main/DndWhilePlaying/DndWhilePlaying.plugin.js 4 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/DndWhilePlaying/DndWhilePlaying.plugin.js 5 | * @website https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/DndWhilePlaying 6 | * @invite zMnHFAKsu3 7 | * @version 0.0.4 8 | */ 9 | 10 | const request = require("request"); 11 | const fs = require("fs"); 12 | const path = require("path"); 13 | 14 | const config = { 15 | info: { 16 | name: "DndWhilePlaying", 17 | authors: [ 18 | { 19 | name: "QWERT", 20 | discord_id: "678556376640913408", 21 | } 22 | ], 23 | version: "0.0.4", 24 | description: "Automatically updates your status to Do Not Disturb when playing games and resets it back when stopped playing.", 25 | github: "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/DndWhilePlaying", 26 | github_raw: "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/DndWhilePlaying/DndWhilePlaying.plugin.js", 27 | }, 28 | changelog: [ 29 | { 30 | "title": "Bug Fix", 31 | "type": "fixed", 32 | "items": ["fixed: plugin can now change status to dnd and back"] 33 | } 34 | ] 35 | }; 36 | 37 | module.exports = !global.ZeresPluginLibrary ? class { 38 | constructor() { 39 | this._config = config; 40 | } 41 | 42 | load() { 43 | BdApi.showConfirmationModal("Library plugin is needed", 44 | `The library plugin needed for ${config.info.name} is missing. Please click Download Now to install it.`, { 45 | confirmText: "Download", 46 | cancelText: "Cancel", 47 | onConfirm: () => { 48 | request.get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", (error, response, body) => { 49 | if (error) 50 | return electron.shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 51 | 52 | fs.writeFileSync(path.join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body); 53 | }); 54 | } 55 | }); 56 | } 57 | 58 | start() { } 59 | 60 | stop() { } 61 | } : (([Plugin, Library]) => { 62 | const Dispatcher = BdApi.findModuleByProps("dispatch", "subscribe"); 63 | const UserSettingsProtoStore = BdApi.Webpack.getModule( 64 | (m) => 65 | m && 66 | typeof m.getName == "function" && 67 | m.getName() == "UserSettingsProtoStore" && 68 | m, 69 | { first: true, searchExports: true } 70 | ); 71 | 72 | const UserSettingsProtoUtils = BdApi.Webpack.getModule( 73 | (m) => 74 | m.ProtoClass && 75 | m.ProtoClass.typeName.endsWith(".PreloadedUserSettings"), 76 | { first: true, searchExports: true } 77 | ); 78 | class DndWhilePlaying extends Plugin { 79 | constructor() { 80 | super(); 81 | } 82 | 83 | async runningGamesChange(event) { 84 | const { games } = event; 85 | 86 | const status = UserSettingsProtoStore.settings.status.status.value; 87 | 88 | if(status === 'invisible') return; 89 | 90 | if(games.length > 0) { 91 | if(BdApi.getData("DndWhilePlaying", "inGame") !== true) { 92 | await BdApi.saveData("DndWhilePlaying", "status", status); 93 | await BdApi.saveData("DndWhilePlaying", "inGame", true); 94 | } 95 | if (status !== "dnd") { 96 | UserSettingsProtoUtils.updateAsync( 97 | "status", 98 | (statusSetting) => { 99 | statusSetting.status.value = "dnd"; 100 | }, 101 | 0 102 | ); 103 | } 104 | 105 | } else if (games.length == 0) { 106 | const savedStatus = BdApi.getData("DndWhilePlaying", "status"); 107 | if (savedStatus) { 108 | UserSettingsProtoUtils.updateAsync( 109 | "status", 110 | (statusSetting) => { 111 | statusSetting.status.value = savedStatus; 112 | }, 113 | 0 114 | ); 115 | } 116 | 117 | await BdApi.saveData("DndWhilePlaying", "status", false); 118 | await BdApi.saveData("DndWhilePlaying", "inGame", false); 119 | } 120 | } 121 | 122 | onStart() { 123 | Dispatcher.subscribe("RUNNING_GAMES_CHANGE", this.runningGamesChange); 124 | } 125 | 126 | onStop() { 127 | Dispatcher.unsubscribe("RUNNING_GAMES_CHANGE", this.runningGamesChange); 128 | } 129 | 130 | } 131 | 132 | return DndWhilePlaying; 133 | })(global.ZeresPluginLibrary.buildPlugin(config)); 134 | -------------------------------------------------------------------------------- /DndWhilePlaying/README.md: -------------------------------------------------------------------------------- 1 | # DndWhilePlaying 2 | [![Download][icon]][link] 3 | 4 | Automatically updates your status to Do Not Disturb when playing games and resets it back when stopped playing. 5 | 6 | [icon]: https://img.shields.io/badge/Download-DndWhilePlaying-brightgreen.svg 7 | [link]: https://betterdiscord.net/ghdl?id=3569 8 | -------------------------------------------------------------------------------- /GlobalReplies/GlobalReplies.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name GlobalReplies 3 | * @version 1.0.6 4 | * @description Allows you to reply to messages outside of the channel they were sent in. 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/GlobalReplies 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/master/GlobalReplies/GlobalReplies.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "GlobalReplies", 35 | "version": "1.0.6", 36 | "description": "Allows you to reply to messages outside of the channel they were sent in.", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/GlobalReplies", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/master/GlobalReplies/GlobalReplies.plugin.js" 44 | }, 45 | "build": { 46 | "zlibrary": true, 47 | "copy": true, 48 | "production": false, 49 | "scssHash": false, 50 | "alias": { 51 | "components": "components/index.js" 52 | }, 53 | "release": { 54 | "source": true, 55 | "readme": true 56 | } 57 | }, 58 | "changelog": [{ 59 | "type": "fixed", 60 | "title": "Fixes", 61 | "items": [ 62 | "Fixed" 63 | ] 64 | }] 65 | }; 66 | function buildPlugin([BasePlugin, PluginApi]) { 67 | const module = { 68 | exports: {} 69 | }; 70 | (() => { 71 | "use strict"; 72 | class StyleLoader { 73 | static styles = ""; 74 | static element = null; 75 | static append(module, css) { 76 | this.styles += `/* ${module} */\n${css}`; 77 | } 78 | static inject(name = config.info.name) { 79 | if (this.element) this.element.remove(); 80 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 81 | id: name, 82 | textContent: this.styles 83 | })); 84 | } 85 | static remove() { 86 | if (this.element) { 87 | this.element.remove(); 88 | this.element = null; 89 | } 90 | } 91 | } 92 | function ___createMemoize___(instance, name, value) { 93 | value = value(); 94 | Object.defineProperty(instance, name, { 95 | value, 96 | configurable: true 97 | }); 98 | return value; 99 | }; 100 | const Modules = { 101 | get 'react-spring'() { 102 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 103 | }, 104 | '@discord/utils': { 105 | get 'joinClassNames'() { 106 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 107 | }, 108 | get 'useForceUpdate'() { 109 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 110 | }, 111 | get 'Logger'() { 112 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 113 | }, 114 | get 'Navigation'() { 115 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 116 | } 117 | }, 118 | '@discord/components': { 119 | get 'Tooltip'() { 120 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 121 | }, 122 | get 'TooltipContainer'() { 123 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 124 | }, 125 | get 'TextInput'() { 126 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 127 | }, 128 | get 'SlideIn'() { 129 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 130 | }, 131 | get 'SettingsNotice'() { 132 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 133 | }, 134 | get 'TransitionGroup'() { 135 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 136 | }, 137 | get 'Button'() { 138 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 139 | }, 140 | get 'Popout'() { 141 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 142 | }, 143 | get 'Flex'() { 144 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 145 | }, 146 | get 'Text'() { 147 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('Text')) 148 | }, 149 | get 'Card'() { 150 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 151 | } 152 | }, 153 | '@discord/modules': { 154 | get 'Dispatcher'() { 155 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dirtyDispatch', 'subscribe')) 156 | }, 157 | get 'ComponentDispatcher'() { 158 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 159 | }, 160 | get 'EmojiUtils'() { 161 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 162 | }, 163 | get 'PermissionUtils'() { 164 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 165 | }, 166 | get 'DMUtils'() { 167 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 168 | } 169 | }, 170 | '@discord/stores': { 171 | get 'Messages'() { 172 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 173 | }, 174 | get 'Channels'() { 175 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 176 | }, 177 | get 'Guilds'() { 178 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 179 | }, 180 | get 'SelectedGuilds'() { 181 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 182 | }, 183 | get 'SelectedChannels'() { 184 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 185 | }, 186 | get 'Info'() { 187 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 188 | }, 189 | get 'Status'() { 190 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 191 | }, 192 | get 'Users'() { 193 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 194 | }, 195 | get 'SettingsStore'() { 196 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 197 | }, 198 | get 'UserProfile'() { 199 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 200 | }, 201 | get 'Members'() { 202 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 203 | }, 204 | get 'Activities'() { 205 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 206 | }, 207 | get 'Games'() { 208 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 209 | }, 210 | get 'Auth'() { 211 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 212 | }, 213 | get 'TypingUsers'() { 214 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 215 | } 216 | }, 217 | '@discord/actions': { 218 | get 'ProfileActions'() { 219 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 220 | }, 221 | get 'GuildActions'() { 222 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 223 | } 224 | }, 225 | get '@discord/i18n'() { 226 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 227 | }, 228 | get '@discord/constants'() { 229 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 230 | }, 231 | get '@discord/contextmenu'() { 232 | return ___createMemoize___(this, '@discord/contextmenu', () => { 233 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 234 | ctx.Menu = ctx.default; 235 | return ctx; 236 | }) 237 | }, 238 | get '@discord/forms'() { 239 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 240 | }, 241 | get '@discord/scrollbars'() { 242 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 243 | }, 244 | get '@discord/native'() { 245 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 246 | }, 247 | get '@discord/flux'() { 248 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 249 | }, 250 | get '@discord/modal'() { 251 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 252 | }, 253 | get '@discord/connections'() { 254 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 255 | }, 256 | get '@discord/sanitize'() { 257 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 258 | }, 259 | get '@discord/icons'() { 260 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 261 | }, 262 | '@discord/classes': { 263 | get 'Timestamp'() { 264 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 265 | }, 266 | get 'Message'() { 267 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 268 | }, 269 | get 'User'() { 270 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 271 | }, 272 | get 'Channel'() { 273 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 274 | } 275 | } 276 | }; 277 | var __webpack_modules__ = { 278 | 113: module => { 279 | module.exports = BdApi.React; 280 | } 281 | }; 282 | var __webpack_module_cache__ = {}; 283 | function __webpack_require__(moduleId) { 284 | var cachedModule = __webpack_module_cache__[moduleId]; 285 | if (void 0 !== cachedModule) return cachedModule.exports; 286 | var module = __webpack_module_cache__[moduleId] = { 287 | exports: {} 288 | }; 289 | __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 290 | return module.exports; 291 | } 292 | (() => { 293 | __webpack_require__.n = module => { 294 | var getter = module && module.__esModule ? () => module["default"] : () => module; 295 | __webpack_require__.d(getter, { 296 | a: getter 297 | }); 298 | return getter; 299 | }; 300 | })(); 301 | (() => { 302 | __webpack_require__.d = (exports, definition) => { 303 | for (var key in definition) 304 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 305 | enumerable: true, 306 | get: definition[key] 307 | }); 308 | }; 309 | })(); 310 | (() => { 311 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 312 | })(); 313 | (() => { 314 | __webpack_require__.r = exports => { 315 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 316 | value: "Module" 317 | }); 318 | Object.defineProperty(exports, "__esModule", { 319 | value: true 320 | }); 321 | }; 322 | })(); 323 | var __webpack_exports__ = {}; 324 | (() => { 325 | __webpack_require__.r(__webpack_exports__); 326 | __webpack_require__.d(__webpack_exports__, { 327 | default: () => GlobalReplies 328 | }); 329 | const external_BasePlugin_namespaceObject = BasePlugin; 330 | var external_BasePlugin_default = __webpack_require__.n(external_BasePlugin_namespaceObject); 331 | const external_PluginApi_DiscordModules_namespaceObject = PluginApi.DiscordModules; 332 | const external_PluginApi_namespaceObject = PluginApi; 333 | const forms_namespaceObject = Modules["@discord/forms"]; 334 | const components_namespaceObject = Modules["@discord/components"]; 335 | var external_BdApi_React_ = __webpack_require__(113); 336 | var React = __webpack_require__(113); 337 | const { 338 | getData, 339 | setData 340 | } = BdApi; 341 | function getTemplate() { 342 | return getData("GlobalReplies", "template") ?? `Replying to {{author}} {{messageLink}} `; 343 | } 344 | function Variable(props) { 345 | return React.createElement("p", null, React.createElement("strong", null, props.title), " ", React.createElement("span", null, " — "), " ", React.createElement("span", null, props.desc)); 346 | } 347 | function Settings() { 348 | const [state, setState] = (0, external_BdApi_React_.useState)(getTemplate()); 349 | return [React.createElement(forms_namespaceObject.FormItem, { 350 | title: "Global reply template" 351 | }, React.createElement(components_namespaceObject.TextInput, { 352 | value: state, 353 | onChange: e => { 354 | setState(e); 355 | setData("GlobalReplies", "template", e); 356 | } 357 | }), React.createElement(components_namespaceObject.Button, { 358 | look: "lookLink-15mFoz", 359 | onClick: () => { 360 | setState(`Replying to {{author}} {{messageLink}} `); 361 | setData("GlobalReplies", "template", `Replying to {{author}} {{messageLink}} `); 362 | } 363 | }, "Reset")), React.createElement(forms_namespaceObject.FormNotice, { 364 | title: "Variables", 365 | type: "cardWarningOutline", 366 | body: [React.createElement("p", null), React.createElement(Variable, { 367 | title: "{{author}}", 368 | desc: "Being replaced with the author mention" 369 | }), React.createElement(Variable, { 370 | title: "{{authorTag}}", 371 | desc: "Being replaced with the author tag (User#0000)" 372 | }), React.createElement(Variable, { 373 | title: "{{messageLink}}", 374 | desc: "Being replaced with the replied message link" 375 | }), React.createElement(Variable, { 376 | title: "{{channel}}", 377 | desc: "Being replaced with the channel of the replied message" 378 | }), React.createElement(Variable, { 379 | title: "{{message}}", 380 | desc: "Will be replaced with the user message" 381 | }), React.createElement(Variable, { 382 | title: "{{newLine}}", 383 | desc: "Switching to a new line" 384 | })] 385 | })]; 386 | } 387 | var GlobalReplies_React = __webpack_require__(113); 388 | const { 389 | Patcher, 390 | findModule: get, 391 | findModuleByProps: getByProps, 392 | findModuleByDisplayName: getByName, 393 | getData: GlobalReplies_getData, 394 | setData: GlobalReplies_setData 395 | } = BdApi; 396 | const { 397 | ComponentDispatch 398 | } = getByProps("ComponentDispatch"); 399 | const MessageContextMenu = external_PluginApi_namespaceObject.DCM.getDiscordMenu("MessageContextMenu"); 400 | const Menu = getByProps("MenuItem"); 401 | const ChannelText = getByName("ChannelText"); 402 | const { 403 | getChannels 404 | } = getByProps("getChannels"); 405 | const GuildPermissions = getByProps("getChannelPermissions"); 406 | const { 407 | Permissions 408 | } = getByProps("API_HOST"); 409 | class GlobalReplies extends(external_BasePlugin_default()) { 410 | onStart() { 411 | this.patch(); 412 | console.log("%cGlobalReplies", "background: #1c90b5; color: white; padding: 2px; border-radius: 4px; font-weight: bold;", "Successfully started."); 413 | } 414 | onStop() { 415 | console.log("%cGlobalReplies", "background: #1c90b5; color: white; padding: 2px; border-radius: 4px; font-weight: bold;", "stopped."); 416 | Patcher.unpatchAll(this.constructor.name); 417 | } 418 | patch() { 419 | MessageContextMenu.then((module => { 420 | Patcher.after(this.constructor.name, module, "default", ((_this, [props], ret) => { 421 | const channel = external_PluginApi_DiscordModules_namespaceObject.ChannelStore.getChannel(props?.message?.channel_id); 422 | const server = external_PluginApi_DiscordModules_namespaceObject.GuildStore.getGuild(channel?.guild_id); 423 | const channels = getChannels(server?.id); 424 | if (!server || !server?.id) return; 425 | const tree = ret.props.children[2].props.children; 426 | tree.splice(6, 0, GlobalReplies_React.createElement(Menu.MenuItem, { 427 | id: "gloabl-reply", 428 | label: "Global Reply", 429 | children: channels.SELECTABLE.filter((e => GuildPermissions.can(Permissions.SEND_MESSAGES, e.channel))).map((e => GlobalReplies_React.createElement(Menu.MenuItem, { 430 | id: `${e.channel.name}-${e.comparator}`, 431 | action: () => { 432 | external_PluginApi_DiscordModules_namespaceObject.NavigationUtils.replaceWith(`/channels/${server.id}/${e.channel.id}`); 433 | ComponentDispatch.dispatchToLastSubscribed("INSERT_TEXT", { 434 | plainText: external_PluginApi_namespaceObject.Utilities.formatString(this.getTemplate(), { 435 | messageLink: `https://discord.com/channels/${server.id}/${channel.id}/${props.message.id}`, 436 | author: `<@${props.message.author.id}>`, 437 | authorTag: props.message.author.tag, 438 | message: props.message.content, 439 | channel: `<#${channel.id}>`, 440 | newLine: "\n" 441 | }) 442 | }); 443 | }, 444 | label: [GlobalReplies_React.createElement(ChannelText, { 445 | width: "10", 446 | height: "10" 447 | }), ` ${e.channel.name}`] 448 | }))) 449 | })); 450 | })); 451 | })); 452 | } 453 | getTemplate() { 454 | return GlobalReplies_getData(this.constructor.name, "template") ?? `Replying to {{author}} {{messageLink}} `; 455 | } 456 | getSettingsPanel() { 457 | return GlobalReplies_React.createElement(Settings, null); 458 | } 459 | } 460 | })(); 461 | module.exports.LibraryPluginHack = __webpack_exports__; 462 | })(); 463 | const PluginExports = module.exports.LibraryPluginHack; 464 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 465 | } 466 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 467 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 468 | class { 469 | getName() { 470 | return config.info.name; 471 | } 472 | getAuthor() { 473 | return config.info.authors.map(a => a.name).join(", "); 474 | } 475 | getDescription() { 476 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 477 | } 478 | getVersion() { 479 | return config.info.version; 480 | } 481 | load() { 482 | BdApi.showConfirmationModal( 483 | "Library plugin is needed", 484 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 485 | confirmText: "Download", 486 | cancelText: "Cancel", 487 | onConfirm: () => { 488 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 489 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 490 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 491 | }); 492 | } 493 | } 494 | ); 495 | } 496 | start() {} 497 | stop() {} 498 | }; 499 | /*@end@*/ -------------------------------------------------------------------------------- /GlobalReplies/README.md: -------------------------------------------------------------------------------- 1 | # GlobalReplies 2 | 3 | > Allows you to reply to messages outside of the channel they were sent in. 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /GlobalReplies/assets/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/717e9b711723c535157e3227b28ef24d44eaa105/GlobalReplies/assets/preview.png -------------------------------------------------------------------------------- /GrammarCorrect/GrammarCorrect.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name GrammarCorrect 3 | * @version 1.0.6 4 | * @description Corrects your grammar mistakes just like Grammarly 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/GrammarCorrect 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/GrammarCorrect/GrammarCorrect.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "GrammarCorrect", 35 | "version": "1.0.6", 36 | "description": "Corrects your grammar mistakes just like Grammarly", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/GrammarCorrect", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/GrammarCorrect/GrammarCorrect.plugin.js" 44 | }, 45 | "changelog": [{ 46 | "type": "fixed", 47 | "title": "Fixed", 48 | "items": [ 49 | "Correcting works now" 50 | ] 51 | }], 52 | "build": { 53 | "zlibrary": true, 54 | "copy": true, 55 | "production": false, 56 | "scssHash": false, 57 | "alias": { 58 | "components": "components/index.js" 59 | }, 60 | "release": { 61 | "source": true, 62 | "readme": true 63 | } 64 | } 65 | }; 66 | function buildPlugin([BasePlugin, PluginApi]) { 67 | const module = { 68 | exports: {} 69 | }; 70 | (() => { 71 | "use strict"; 72 | class StyleLoader { 73 | static styles = ""; 74 | static element = null; 75 | static append(module, css) { 76 | this.styles += `/* ${module} */\n${css}`; 77 | } 78 | static inject(name = config.info.name) { 79 | if (this.element) this.element.remove(); 80 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 81 | id: name, 82 | textContent: this.styles 83 | })); 84 | } 85 | static remove() { 86 | if (this.element) { 87 | this.element.remove(); 88 | this.element = null; 89 | } 90 | } 91 | } 92 | function ___createMemoize___(instance, name, value) { 93 | value = value(); 94 | Object.defineProperty(instance, name, { 95 | value, 96 | configurable: true 97 | }); 98 | return value; 99 | }; 100 | const Modules = { 101 | get 'react-spring'() { 102 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 103 | }, 104 | '@discord/utils': { 105 | get 'joinClassNames'() { 106 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 107 | }, 108 | get 'useForceUpdate'() { 109 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 110 | }, 111 | get 'Logger'() { 112 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 113 | }, 114 | get 'Navigation'() { 115 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 116 | } 117 | }, 118 | '@discord/components': { 119 | get 'Tooltip'() { 120 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 121 | }, 122 | get 'TooltipContainer'() { 123 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 124 | }, 125 | get 'TextInput'() { 126 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 127 | }, 128 | get 'SlideIn'() { 129 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 130 | }, 131 | get 'SettingsNotice'() { 132 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 133 | }, 134 | get 'TransitionGroup'() { 135 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 136 | }, 137 | get 'Button'() { 138 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 139 | }, 140 | get 'Popout'() { 141 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 142 | }, 143 | get 'Flex'() { 144 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 145 | }, 146 | get 'Text'() { 147 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('Text')) 148 | }, 149 | get 'Card'() { 150 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 151 | } 152 | }, 153 | '@discord/modules': { 154 | get 'Dispatcher'() { 155 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dirtyDispatch', 'subscribe')) 156 | }, 157 | get 'ComponentDispatcher'() { 158 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 159 | }, 160 | get 'EmojiUtils'() { 161 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 162 | }, 163 | get 'PermissionUtils'() { 164 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 165 | }, 166 | get 'DMUtils'() { 167 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 168 | } 169 | }, 170 | '@discord/stores': { 171 | get 'Messages'() { 172 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 173 | }, 174 | get 'Channels'() { 175 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 176 | }, 177 | get 'Guilds'() { 178 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 179 | }, 180 | get 'SelectedGuilds'() { 181 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 182 | }, 183 | get 'SelectedChannels'() { 184 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 185 | }, 186 | get 'Info'() { 187 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 188 | }, 189 | get 'Status'() { 190 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 191 | }, 192 | get 'Users'() { 193 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 194 | }, 195 | get 'SettingsStore'() { 196 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 197 | }, 198 | get 'UserProfile'() { 199 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 200 | }, 201 | get 'Members'() { 202 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 203 | }, 204 | get 'Activities'() { 205 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 206 | }, 207 | get 'Games'() { 208 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 209 | }, 210 | get 'Auth'() { 211 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 212 | }, 213 | get 'TypingUsers'() { 214 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 215 | } 216 | }, 217 | '@discord/actions': { 218 | get 'ProfileActions'() { 219 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 220 | }, 221 | get 'GuildActions'() { 222 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 223 | } 224 | }, 225 | get '@discord/i18n'() { 226 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 227 | }, 228 | get '@discord/constants'() { 229 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 230 | }, 231 | get '@discord/contextmenu'() { 232 | return ___createMemoize___(this, '@discord/contextmenu', () => { 233 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 234 | ctx.Menu = ctx.default; 235 | return ctx; 236 | }) 237 | }, 238 | get '@discord/forms'() { 239 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 240 | }, 241 | get '@discord/scrollbars'() { 242 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 243 | }, 244 | get '@discord/native'() { 245 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 246 | }, 247 | get '@discord/flux'() { 248 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 249 | }, 250 | get '@discord/modal'() { 251 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 252 | }, 253 | get '@discord/connections'() { 254 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 255 | }, 256 | get '@discord/sanitize'() { 257 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 258 | }, 259 | get '@discord/icons'() { 260 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 261 | }, 262 | '@discord/classes': { 263 | get 'Timestamp'() { 264 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 265 | }, 266 | get 'Message'() { 267 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 268 | }, 269 | get 'User'() { 270 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 271 | }, 272 | get 'Channel'() { 273 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 274 | } 275 | } 276 | }; 277 | var __webpack_require__ = {}; 278 | (() => { 279 | __webpack_require__.n = module => { 280 | var getter = module && module.__esModule ? () => module["default"] : () => module; 281 | __webpack_require__.d(getter, { 282 | a: getter 283 | }); 284 | return getter; 285 | }; 286 | })(); 287 | (() => { 288 | __webpack_require__.d = (exports, definition) => { 289 | for (var key in definition) 290 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 291 | enumerable: true, 292 | get: definition[key] 293 | }); 294 | }; 295 | })(); 296 | (() => { 297 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 298 | })(); 299 | (() => { 300 | __webpack_require__.r = exports => { 301 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 302 | value: "Module" 303 | }); 304 | Object.defineProperty(exports, "__esModule", { 305 | value: true 306 | }); 307 | }; 308 | })(); 309 | var __webpack_exports__ = {}; 310 | __webpack_require__.r(__webpack_exports__); 311 | __webpack_require__.d(__webpack_exports__, { 312 | default: () => GrammarCorrect 313 | }); 314 | const external_BasePlugin_namespaceObject = BasePlugin; 315 | var external_BasePlugin_default = __webpack_require__.n(external_BasePlugin_namespaceObject); 316 | const external_PluginApi_namespaceObject = PluginApi; 317 | const { 318 | React, 319 | Patcher, 320 | findModule: get, 321 | findModuleByProps: getByProps, 322 | findModuleByDisplayName: getByName, 323 | getData, 324 | setData 325 | } = BdApi; 326 | const { 327 | ComponentDispatch 328 | } = getByProps("ComponentDispatch"); 329 | const Menu = getByProps("MenuItem"); 330 | const SlateTextAreaContextMenu = get((m => "SlateTextAreaContextMenu" === m?.default?.displayName)); 331 | const ChannelTextAreaContainer = get((m => "ChannelTextAreaContainer" === m?.type?.render?.displayName)); 332 | const SwitchItem = getByName("SwitchItem"); 333 | class GrammarCorrect extends(external_BasePlugin_default()) { 334 | onStart() { 335 | this.patch(); 336 | this.patchSendMessage(); 337 | console.log("%cGrammarCorrect", "background: #03C197; color: white; padding: 2px; border-radius: 4px; font-weight: 600;", "Successfully started."); 338 | } 339 | onStop() { 340 | Patcher.unpatchAll("grammar"); 341 | console.log("%cGrammarCorrect", "background: #03C197; color: white; padding: 2px; border-radius: 4px; font-weight: 600;", "Stopped."); 342 | } 343 | isAuto() { 344 | return getData(this.constructor.name, "autoCorrect") ?? false; 345 | } 346 | patchSendMessage() { 347 | if (!this.isAuto()) return; 348 | Patcher.instead("grammar", external_PluginApi_namespaceObject.DiscordModules.MessageActions, "sendMessage", ((_this, [channelId, message, , reply], ret) => { 349 | this.correct(message.content).then((e => { 350 | message.content = e; 351 | ret(channelId, message, null, reply); 352 | })); 353 | })); 354 | } 355 | patch() { 356 | Patcher.after("grammar", SlateTextAreaContextMenu, "default", ((_this, [props], ret) => { 357 | const children = ret.props.children; 358 | let text = ""; 359 | Patcher.after("grammar", ChannelTextAreaContainer.type, "render", ((_, [{ 360 | textValue 361 | }]) => { 362 | text = textValue; 363 | })); 364 | children.splice(children.length - 1, 0, React.createElement(Menu.MenuGroup, null, React.createElement(Menu.MenuItem, { 365 | id: "correct", 366 | key: "correct", 367 | label: "Correct", 368 | action: async () => { 369 | const correction = await this.correct(text); 370 | if (!correction) return ComponentDispatch.dispatch("SHAKE_APP", { 371 | duration: 200, 372 | intensity: 3 373 | }); 374 | ComponentDispatch.dispatch("CLEAR_TEXT"); 375 | ComponentDispatch.dispatch("INSERT_TEXT", { 376 | plainText: correction 377 | }); 378 | } 379 | }))); 380 | })); 381 | } 382 | async correct(text) { 383 | if ("" === text.trim()) return null; 384 | const resp = await fetch("https://orthographe.reverso.net/api/v1/Spelling", { 385 | headers: { 386 | "content-type": "application/json" 387 | }, 388 | body: JSON.stringify({ 389 | autoReplace: true, 390 | generateRecommendations: false, 391 | generateSynonyms: false, 392 | getCorrectionDetails: true, 393 | interfaceLanguage: "en", 394 | language: "eng", 395 | locale: "Indifferent", 396 | origin: "interactive", 397 | text 398 | }), 399 | method: "POST" 400 | }).then((r => r.json())); 401 | return resp.text || null; 402 | } 403 | getSettingsPanel() { 404 | const that = this; 405 | return function() { 406 | const [state, setState] = React.useState(that.isAuto()); 407 | return React.createElement(SwitchItem, { 408 | value: state, 409 | onChange: e => { 410 | setState(e); 411 | setData(that.constructor.name, "autoCorrect", e); 412 | } 413 | }, "Always correct messages before sending"); 414 | }; 415 | } 416 | } 417 | module.exports.LibraryPluginHack = __webpack_exports__; 418 | })(); 419 | const PluginExports = module.exports.LibraryPluginHack; 420 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 421 | } 422 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 423 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 424 | class { 425 | getName() { 426 | return config.info.name; 427 | } 428 | getAuthor() { 429 | return config.info.authors.map(a => a.name).join(", "); 430 | } 431 | getDescription() { 432 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 433 | } 434 | getVersion() { 435 | return config.info.version; 436 | } 437 | load() { 438 | BdApi.showConfirmationModal( 439 | "Library plugin is needed", 440 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 441 | confirmText: "Download", 442 | cancelText: "Cancel", 443 | onConfirm: () => { 444 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 445 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 446 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 447 | }); 448 | } 449 | } 450 | ); 451 | } 452 | start() {} 453 | stop() {} 454 | }; 455 | /*@end@*/ -------------------------------------------------------------------------------- /GrammarCorrect/README.md: -------------------------------------------------------------------------------- 1 | # GrammarCorrect 2 | 3 | > Corrects your grammar mistakes just like Grammarly 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /HidePerServerAvatars/HidePerServerAvatars.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name HidePerServerAvatars 3 | * @version 1.0.0 4 | * @description Shows the actual users avatars in chat instead of their per-server avatar. 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/HidePerServerAvatars 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/HidePerServerAvatars/HidePerServerAvatars.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "HidePerServerAvatars", 35 | "version": "1.0.0", 36 | "description": "Shows the actual users avatars in chat instead of their per-server avatar.", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/HidePerServerAvatars", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/HidePerServerAvatars/HidePerServerAvatars.plugin.js" 44 | }, 45 | "build": { 46 | "zlibrary": true, 47 | "copy": true, 48 | "production": false, 49 | "scssHash": false, 50 | "alias": { 51 | "components": "components/index.js" 52 | }, 53 | "release": { 54 | "source": true, 55 | "readme": true 56 | } 57 | } 58 | }; 59 | function buildPlugin([BasePlugin, PluginApi]) { 60 | const module = { 61 | exports: {} 62 | }; 63 | (() => { 64 | "use strict"; 65 | class StyleLoader { 66 | static styles = ""; 67 | static element = null; 68 | static append(module, css) { 69 | this.styles += `/* ${module} */\n${css}`; 70 | } 71 | static inject(name = config.info.name) { 72 | if (this.element) this.element.remove(); 73 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 74 | id: name, 75 | textContent: this.styles 76 | })); 77 | } 78 | static remove() { 79 | if (this.element) { 80 | this.element.remove(); 81 | this.element = null; 82 | } 83 | } 84 | } 85 | function ___createMemoize___(instance, name, value) { 86 | value = value(); 87 | Object.defineProperty(instance, name, { 88 | value, 89 | configurable: true 90 | }); 91 | return value; 92 | }; 93 | const Modules = { 94 | get 'react-spring'() { 95 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 96 | }, 97 | '@discord/utils': { 98 | get 'joinClassNames'() { 99 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 100 | }, 101 | get 'useForceUpdate'() { 102 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 103 | }, 104 | get 'Logger'() { 105 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 106 | }, 107 | get 'Navigation'() { 108 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 109 | } 110 | }, 111 | '@discord/components': { 112 | get 'Tooltip'() { 113 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 114 | }, 115 | get 'TooltipContainer'() { 116 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 117 | }, 118 | get 'TextInput'() { 119 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 120 | }, 121 | get 'SlideIn'() { 122 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 123 | }, 124 | get 'SettingsNotice'() { 125 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 126 | }, 127 | get 'TransitionGroup'() { 128 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 129 | }, 130 | get 'Button'() { 131 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 132 | }, 133 | get 'Popout'() { 134 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 135 | }, 136 | get 'Flex'() { 137 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 138 | }, 139 | get 'Text'() { 140 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('Text')) 141 | }, 142 | get 'Card'() { 143 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 144 | } 145 | }, 146 | '@discord/modules': { 147 | get 'Dispatcher'() { 148 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dirtyDispatch', 'subscribe')) 149 | }, 150 | get 'ComponentDispatcher'() { 151 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 152 | }, 153 | get 'EmojiUtils'() { 154 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 155 | }, 156 | get 'PermissionUtils'() { 157 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 158 | }, 159 | get 'DMUtils'() { 160 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 161 | } 162 | }, 163 | '@discord/stores': { 164 | get 'Messages'() { 165 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 166 | }, 167 | get 'Channels'() { 168 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 169 | }, 170 | get 'Guilds'() { 171 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 172 | }, 173 | get 'SelectedGuilds'() { 174 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 175 | }, 176 | get 'SelectedChannels'() { 177 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 178 | }, 179 | get 'Info'() { 180 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 181 | }, 182 | get 'Status'() { 183 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 184 | }, 185 | get 'Users'() { 186 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 187 | }, 188 | get 'SettingsStore'() { 189 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 190 | }, 191 | get 'UserProfile'() { 192 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 193 | }, 194 | get 'Members'() { 195 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 196 | }, 197 | get 'Activities'() { 198 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 199 | }, 200 | get 'Games'() { 201 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 202 | }, 203 | get 'Auth'() { 204 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 205 | }, 206 | get 'TypingUsers'() { 207 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 208 | } 209 | }, 210 | '@discord/actions': { 211 | get 'ProfileActions'() { 212 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 213 | }, 214 | get 'GuildActions'() { 215 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 216 | } 217 | }, 218 | get '@discord/i18n'() { 219 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 220 | }, 221 | get '@discord/constants'() { 222 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 223 | }, 224 | get '@discord/contextmenu'() { 225 | return ___createMemoize___(this, '@discord/contextmenu', () => { 226 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 227 | ctx.Menu = ctx.default; 228 | return ctx; 229 | }) 230 | }, 231 | get '@discord/forms'() { 232 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 233 | }, 234 | get '@discord/scrollbars'() { 235 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 236 | }, 237 | get '@discord/native'() { 238 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 239 | }, 240 | get '@discord/flux'() { 241 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 242 | }, 243 | get '@discord/modal'() { 244 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 245 | }, 246 | get '@discord/connections'() { 247 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 248 | }, 249 | get '@discord/sanitize'() { 250 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 251 | }, 252 | get '@discord/icons'() { 253 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 254 | }, 255 | '@discord/classes': { 256 | get 'Timestamp'() { 257 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 258 | }, 259 | get 'Message'() { 260 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 261 | }, 262 | get 'User'() { 263 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 264 | }, 265 | get 'Channel'() { 266 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 267 | } 268 | } 269 | }; 270 | var __webpack_require__ = {}; 271 | (() => { 272 | __webpack_require__.n = module => { 273 | var getter = module && module.__esModule ? () => module["default"] : () => module; 274 | __webpack_require__.d(getter, { 275 | a: getter 276 | }); 277 | return getter; 278 | }; 279 | })(); 280 | (() => { 281 | __webpack_require__.d = (exports, definition) => { 282 | for (var key in definition) 283 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 284 | enumerable: true, 285 | get: definition[key] 286 | }); 287 | }; 288 | })(); 289 | (() => { 290 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 291 | })(); 292 | (() => { 293 | __webpack_require__.r = exports => { 294 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 295 | value: "Module" 296 | }); 297 | Object.defineProperty(exports, "__esModule", { 298 | value: true 299 | }); 300 | }; 301 | })(); 302 | var __webpack_exports__ = {}; 303 | __webpack_require__.r(__webpack_exports__); 304 | __webpack_require__.d(__webpack_exports__, { 305 | default: () => HidePerServerAvatars 306 | }); 307 | const external_BasePlugin_namespaceObject = BasePlugin; 308 | var external_BasePlugin_default = __webpack_require__.n(external_BasePlugin_namespaceObject); 309 | const external_PluginApi_namespaceObject = PluginApi; 310 | const external_PluginApi_DiscordModules_namespaceObject = PluginApi.DiscordModules; 311 | const UserPopoutHeader = external_PluginApi_namespaceObject.WebpackModules.find((m => "UserPopoutHeader" === m?.default?.displayName)); 312 | const Avatar = external_PluginApi_namespaceObject.WebpackModules.getByProps("AnimatedAvatar"); 313 | class HidePerServerAvatars extends(external_BasePlugin_default()) { 314 | onStart() { 315 | this.patch(); 316 | } 317 | onStop() { 318 | external_PluginApi_namespaceObject.Patcher.unpatchAll(); 319 | } 320 | patch() { 321 | external_PluginApi_namespaceObject.Patcher.after(external_PluginApi_DiscordModules_namespaceObject.GuildMemberStore, "getMember", ((_this, [props], ret) => { 322 | if (ret?.guildMemberAvatar) ret.guildMemberAvatar = null; 323 | })); 324 | external_PluginApi_namespaceObject.Patcher.after(UserPopoutHeader, "default", ((_this, [props]) => { 325 | if (props?.user) props.user.guildMemberAvatars = {}; 326 | })); 327 | external_PluginApi_namespaceObject.Patcher.after(Avatar, "default", ((_this, [props]) => { 328 | const match = props.src.match(/.*\/\/.*\/guilds\/\d{16,20}\/users\/\d{16,20}\/avatars\/.*/); 329 | if (match) props.src = external_PluginApi_DiscordModules_namespaceObject.UserStore.getUser(match[0].split("/")[6]).getAvatarURL(); 330 | })); 331 | } 332 | } 333 | module.exports.LibraryPluginHack = __webpack_exports__; 334 | })(); 335 | const PluginExports = module.exports.LibraryPluginHack; 336 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 337 | } 338 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 339 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 340 | class { 341 | getName() { 342 | return config.info.name; 343 | } 344 | getAuthor() { 345 | return config.info.authors.map(a => a.name).join(", "); 346 | } 347 | getDescription() { 348 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 349 | } 350 | getVersion() { 351 | return config.info.version; 352 | } 353 | load() { 354 | BdApi.showConfirmationModal( 355 | "Library plugin is needed", 356 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 357 | confirmText: "Download", 358 | cancelText: "Cancel", 359 | onConfirm: () => { 360 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 361 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 362 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 363 | }); 364 | } 365 | } 366 | ); 367 | } 368 | start() {} 369 | stop() {} 370 | }; 371 | /*@end@*/ -------------------------------------------------------------------------------- /HidePerServerAvatars/README.md: -------------------------------------------------------------------------------- 1 | # HidePerServerAvatars 2 | 3 | > Shows the actual users avatars in chat instead of their per-server avatar. 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /InAppNotifications/README.md: -------------------------------------------------------------------------------- 1 | # In App Notifications 2 | [![Download][icon]][link] 3 | 4 | Displays notifications such as new messages, friends added in Discord. 5 | ### Preview 6 | ![Preview](https://media.discordapp.net/attachments/824985697047937024/841708321287307274/unknown.png) 7 | 8 | [icon]: https://img.shields.io/badge/Download-In%20App%20Notifications-brightgreen.svg 9 | [link]: http://qwertxd.github.io/?pluginName=InAppNotifications&src=uk 10 | -------------------------------------------------------------------------------- /OldUpload/OldUpload.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name OldUpload 3 | * @version 1.0.1 4 | * @description Reverts Discord upload button to work as it worked before the update (Quick Upload by default and not when Double-Clicking only) 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/OldUpload 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/OldUpload/OldUpload.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "OldUpload", 35 | "version": "1.0.1", 36 | "description": "Reverts Discord upload button to work as it worked before the update (Quick Upload by default and not when Double-Clicking only)", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/OldUpload", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/OldUpload/OldUpload.plugin.js" 44 | }, 45 | "build": { 46 | "zlibrary": true, 47 | "copy": true, 48 | "production": false, 49 | "scssHash": false, 50 | "alias": { 51 | "components": "components/index.js" 52 | }, 53 | "release": { 54 | "source": true, 55 | "readme": true 56 | } 57 | } 58 | }; 59 | function buildPlugin([BasePlugin, PluginApi]) { 60 | const module = { 61 | exports: {} 62 | }; 63 | (() => { 64 | "use strict"; 65 | class StyleLoader { 66 | static styles = ""; 67 | static element = null; 68 | static append(module, css) { 69 | this.styles += `/* ${module} */\n${css}`; 70 | } 71 | static inject(name = config.info.name) { 72 | if (this.element) this.element.remove(); 73 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 74 | id: name, 75 | textContent: this.styles 76 | })); 77 | } 78 | static remove() { 79 | if (this.element) { 80 | this.element.remove(); 81 | this.element = null; 82 | } 83 | } 84 | } 85 | function ___createMemoize___(instance, name, value) { 86 | value = value(); 87 | Object.defineProperty(instance, name, { 88 | value, 89 | configurable: true 90 | }); 91 | return value; 92 | }; 93 | const Modules = { 94 | get 'react-spring'() { 95 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 96 | }, 97 | '@discord/utils': { 98 | get 'joinClassNames'() { 99 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 100 | }, 101 | get 'useForceUpdate'() { 102 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 103 | }, 104 | get 'Logger'() { 105 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 106 | }, 107 | get 'Navigation'() { 108 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 109 | } 110 | }, 111 | '@discord/components': { 112 | get 'Tooltip'() { 113 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 114 | }, 115 | get 'TooltipContainer'() { 116 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 117 | }, 118 | get 'TextInput'() { 119 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 120 | }, 121 | get 'SlideIn'() { 122 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 123 | }, 124 | get 'SettingsNotice'() { 125 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 126 | }, 127 | get 'TransitionGroup'() { 128 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 129 | }, 130 | get 'Button'() { 131 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 132 | }, 133 | get 'Popout'() { 134 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 135 | }, 136 | get 'Flex'() { 137 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 138 | }, 139 | get 'Text'() { 140 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('LegacyText')) 141 | }, 142 | get 'Card'() { 143 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 144 | } 145 | }, 146 | '@discord/modules': { 147 | get 'Dispatcher'() { 148 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dispatch', 'isDispatching')) 149 | }, 150 | get 'ComponentDispatcher'() { 151 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 152 | }, 153 | get 'EmojiUtils'() { 154 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 155 | }, 156 | get 'PermissionUtils'() { 157 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 158 | }, 159 | get 'DMUtils'() { 160 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 161 | } 162 | }, 163 | '@discord/stores': { 164 | get 'Messages'() { 165 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 166 | }, 167 | get 'Channels'() { 168 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 169 | }, 170 | get 'Guilds'() { 171 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 172 | }, 173 | get 'SelectedGuilds'() { 174 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 175 | }, 176 | get 'SelectedChannels'() { 177 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 178 | }, 179 | get 'Info'() { 180 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 181 | }, 182 | get 'Status'() { 183 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 184 | }, 185 | get 'Users'() { 186 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 187 | }, 188 | get 'SettingsStore'() { 189 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 190 | }, 191 | get 'UserProfile'() { 192 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 193 | }, 194 | get 'Members'() { 195 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 196 | }, 197 | get 'Activities'() { 198 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 199 | }, 200 | get 'Games'() { 201 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 202 | }, 203 | get 'Auth'() { 204 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 205 | }, 206 | get 'TypingUsers'() { 207 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 208 | } 209 | }, 210 | '@discord/actions': { 211 | get 'ProfileActions'() { 212 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 213 | }, 214 | get 'GuildActions'() { 215 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 216 | } 217 | }, 218 | get '@discord/i18n'() { 219 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 220 | }, 221 | get '@discord/constants'() { 222 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 223 | }, 224 | get '@discord/contextmenu'() { 225 | return ___createMemoize___(this, '@discord/contextmenu', () => { 226 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 227 | ctx.Menu = ctx.default; 228 | return ctx; 229 | }) 230 | }, 231 | get '@discord/forms'() { 232 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 233 | }, 234 | get '@discord/scrollbars'() { 235 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 236 | }, 237 | get '@discord/native'() { 238 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 239 | }, 240 | get '@discord/flux'() { 241 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 242 | }, 243 | get '@discord/modal'() { 244 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 245 | }, 246 | get '@discord/connections'() { 247 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 248 | }, 249 | get '@discord/sanitize'() { 250 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 251 | }, 252 | get '@discord/icons'() { 253 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 254 | }, 255 | '@discord/classes': { 256 | get 'Timestamp'() { 257 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 258 | }, 259 | get 'Message'() { 260 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 261 | }, 262 | get 'User'() { 263 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 264 | }, 265 | get 'Channel'() { 266 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 267 | } 268 | } 269 | }; 270 | var __webpack_require__ = {}; 271 | (() => { 272 | __webpack_require__.n = module => { 273 | var getter = module && module.__esModule ? () => module["default"] : () => module; 274 | __webpack_require__.d(getter, { 275 | a: getter 276 | }); 277 | return getter; 278 | }; 279 | })(); 280 | (() => { 281 | __webpack_require__.d = (exports, definition) => { 282 | for (var key in definition) 283 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 284 | enumerable: true, 285 | get: definition[key] 286 | }); 287 | }; 288 | })(); 289 | (() => { 290 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 291 | })(); 292 | (() => { 293 | __webpack_require__.r = exports => { 294 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 295 | value: "Module" 296 | }); 297 | Object.defineProperty(exports, "__esModule", { 298 | value: true 299 | }); 300 | }; 301 | })(); 302 | var __webpack_exports__ = {}; 303 | __webpack_require__.r(__webpack_exports__); 304 | __webpack_require__.d(__webpack_exports__, { 305 | default: () => OldUpload 306 | }); 307 | const external_PluginApi_namespaceObject = PluginApi; 308 | const external_BasePlugin_namespaceObject = BasePlugin; 309 | var external_BasePlugin_default = __webpack_require__.n(external_BasePlugin_namespaceObject); 310 | const AttachMenu = external_PluginApi_namespaceObject.WebpackModules.find((m => "ChannelAttachMenu" === m.default?.displayName)); 311 | class OldUpload extends(external_BasePlugin_default()) { 312 | onStart() { 313 | this.patch(); 314 | } 315 | onStop() { 316 | external_PluginApi_namespaceObject.Patcher.unpatchAll(); 317 | } 318 | patch() { 319 | external_PluginApi_namespaceObject.Patcher.after(AttachMenu, "default", ((_this, [props], ret) => { 320 | const options = props.options; 321 | const uploadOption = ret.props.children.find((e => "upload-file" === e.key)); 322 | delete uploadOption.props.subtext; 323 | if (!options || "UPLOAD_A_FILE" !== options[0]?.type) return; 324 | props.onClose(); 325 | props.onFileUpload(); 326 | })); 327 | } 328 | } 329 | module.exports.LibraryPluginHack = __webpack_exports__; 330 | })(); 331 | const PluginExports = module.exports.LibraryPluginHack; 332 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 333 | } 334 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 335 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 336 | class { 337 | getName() { 338 | return config.info.name; 339 | } 340 | getAuthor() { 341 | return config.info.authors.map(a => a.name).join(", "); 342 | } 343 | getDescription() { 344 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 345 | } 346 | getVersion() { 347 | return config.info.version; 348 | } 349 | load() { 350 | BdApi.showConfirmationModal( 351 | "Library plugin is needed", 352 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 353 | confirmText: "Download", 354 | cancelText: "Cancel", 355 | onConfirm: () => { 356 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 357 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 358 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 359 | }); 360 | } 361 | } 362 | ); 363 | } 364 | start() {} 365 | stop() {} 366 | }; 367 | /*@end@*/ -------------------------------------------------------------------------------- /OldUpload/README.md: -------------------------------------------------------------------------------- 1 | # OldUpload 2 | 3 | > Reverts Discord upload button to work as it worked before the update (Quick Upload by default and not when Double-Clicking only) 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /QuickMessages/QuickMessages.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name QuickMessages 3 | * @version 1.2.5 4 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/blob/main/QuickMessages/QuickMessages.plugin.js 5 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/QuickMessages/QuickMessages.plugin.js 6 | * @website https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/QuickMessages 7 | * @invite zMnHFAKsu3 8 | */ 9 | 10 | const request = require("request"); 11 | const fs = require("fs"); 12 | const path = require("path"); 13 | 14 | const config = { 15 | info: { 16 | name: "QuickMessages", 17 | authors: [ 18 | { 19 | name: "QWERT", 20 | discord_id: "678556376640913408", 21 | } 22 | ], 23 | version: "1.2.5", 24 | description: "Save messages to quickly send them later, when you need.", 25 | github: "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/QuickMessages", 26 | github_raw: "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/QuickMessages/QuickMessages.plugin.js", 27 | }, 28 | changelog: [ 29 | { 30 | title: "Fixed", 31 | type: "Fixed", 32 | items: [ 33 | "Fix crash when creating a new Category", 34 | "Fix crash when deleting a Category", 35 | ], 36 | } 37 | ] 38 | }; 39 | 40 | module.exports = !global.ZeresPluginLibrary ? class { 41 | constructor() { 42 | this._config = config; 43 | } 44 | 45 | getName() { 46 | return config.info.name; 47 | } 48 | 49 | getAuthor() { 50 | return config.info.authors.map(author => author.name).join(", "); 51 | } 52 | 53 | getDescription() { 54 | return config.info.description; 55 | } 56 | 57 | getVersion() { 58 | return config.info.version; 59 | } 60 | 61 | load() { 62 | BdApi.showConfirmationModal("Library plugin is needed", 63 | `The library plugin needed for ${config.info.name} is missing. Please click Download Now to install it.`, { 64 | confirmText: "Download", 65 | cancelText: "Cancel", 66 | onConfirm: () => { 67 | request.get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", (error, response, body) => { 68 | if (error) { 69 | return electron.shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 70 | } 71 | 72 | fs.writeFileSync(path.join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body); 73 | }); 74 | } 75 | }); 76 | } 77 | 78 | start() { } 79 | 80 | stop() { } 81 | } : (([Plugin, Library]) => { 82 | const { DiscordModules, WebpackModules, Patcher, ContextMenu, Settings } = Library; 83 | const { SettingPanel, SettingGroup } = Settings; 84 | const { findModule: get } = BdApi; 85 | 86 | const { React } = DiscordModules; 87 | function configArrayPush(name, key, data) { 88 | const config = BdApi.getData(name, key) || []; 89 | if (config.includes(data)) { 90 | BdApi.showToast(`Already added "${data}"!`, { type: 'success' }); 91 | return; 92 | } 93 | config.push(data); 94 | BdApi.setData(name, key, config); 95 | BdApi.showToast(`Successfully created new Quick Message!`, { type: 'success' }); 96 | } 97 | 98 | const configArrayRemove = function (name, key, value) { 99 | const data = BdApi.getData(name, key) || []; 100 | const config = data.filter(function (x) { 101 | return x != value; 102 | }); 103 | BdApi.setData(name, key, config) 104 | } 105 | 106 | var messages = BdApi.getData('QuickMessages', 'messages') || []; 107 | 108 | function updateMessages() { 109 | messages = BdApi.getData('QuickMessages', 'messages') || []; 110 | } 111 | 112 | var categories = BdApi.getData('QuickMessages', 'categories') || []; 113 | 114 | function saveCategories() { 115 | BdApi.setData('QuickMessages', 'categories', categories); 116 | } 117 | 118 | class QuickMessages extends Plugin { 119 | constructor() { 120 | super(); 121 | } 122 | 123 | buildSettingsPanel() { 124 | const that = this; 125 | const settingGroup = new SettingGroup("Clear Quick Messages", { 126 | shown: true, 127 | collapsible: false 128 | }); 129 | const div = document.createElement("div"); 130 | div.innerHTML = '' 131 | div.onclick = _ => { 132 | BdApi.showConfirmationModal('Are you sure?', 'This action is undonable. You will not be able to restore the deleted data.', { 133 | confirmText: 'Delete', 134 | danger: true, 135 | onConfirm: function () { 136 | BdApi.setData(that.getName(), 'messages', []); 137 | that.forceUpdate(); 138 | BdApi.alert('QuickMessages', 'Successfully Removed All Quick Messages!'); 139 | } 140 | }) 141 | } 142 | settingGroup.append(div); 143 | return new SettingPanel(this.saveSettings.bind(this), settingGroup); 144 | } 145 | 146 | getSettingsPanel() { 147 | return this.buildSettingsPanel().getElement(); 148 | } 149 | 150 | async onStart() { 151 | this.patchTextAreaContextMenus(); 152 | } 153 | 154 | onStop() { 155 | Patcher.unpatchAll(); 156 | } 157 | 158 | forceUpdate() { 159 | saveCategories(); 160 | updateMessages(); 161 | Patcher.unpatchAll(); 162 | this.patchTextAreaContextMenus(); 163 | } 164 | 165 | 166 | async patchTextAreaContextMenus() { 167 | var shouldPaste = true; 168 | const SlateTextAreaContextMenu = await Library.DCM.getDiscordMenu("SlateTextAreaContextMenu"); 169 | const TrashIcon = BdApi.findModuleByDisplayName('Trash'); 170 | const ComponentDispatch = BdApi.findModuleByProps("ComponentDispatch").ComponentDispatch; 171 | const ChannelTextAreaContainer = WebpackModules.find(m => m.type && m.type.render && m.type.render.displayName === "ChannelTextAreaContainer").type; 172 | const TooltipContainer = WebpackModules.getByProps('TooltipContainer').TooltipContainer; 173 | const children = []; 174 | const saveToCategory = []; 175 | var text = ""; 176 | 177 | categories.forEach(cat => { 178 | saveToCategory.push( 179 | ContextMenu.buildMenuItem({ 180 | label: cat.name, 181 | action: _ => { 182 | if (text !== "") { 183 | const category = categories.filter(e => e.name === cat.name)[0]; 184 | if (categories[categories.indexOf(category)].items.includes(text)) { 185 | BdApi.showToast(`Already added "${text}"!`, { type: 'success' }); 186 | return; 187 | } 188 | categories[categories.indexOf(category)].items.push(text); 189 | this.forceUpdate(); 190 | BdApi.showToast(`Successfully created new Quick Message!`, { type: 'success' }); 191 | } else { 192 | BdApi.showToast(`You cannot save an empty message!`, { type: 'error' }); 193 | } 194 | } 195 | }) 196 | ) 197 | const catChildren = []; 198 | cat.items.forEach(e => { 199 | catChildren.push(ContextMenu.buildMenuItem({ 200 | label: e, 201 | action: _ => { 202 | if (!shouldPaste) return; 203 | ComponentDispatch.dispatch("INSERT_TEXT", { content: e, plainText: e }) 204 | }, 205 | hint: React.createElement(TooltipContainer, 206 | { 207 | text: "Delete" 208 | }, 209 | React.createElement(TrashIcon, { 210 | style: { color: "var(--status-danger)" }, 211 | onClick: _ => { 212 | shouldPaste = false; 213 | const category = categories.filter(e => e.name === cat.name)[0]; 214 | categories[categories.indexOf(category)].items = Library.Utilities.removeFromArray(categories[categories.indexOf(category)].items, e); 215 | this.forceUpdate(); 216 | BdApi.showToast(`Successfully removed Quick Message!`, { type: 'success' }); 217 | }, 218 | width: '15px', 219 | height: '15px' 220 | } 221 | ) 222 | ) 223 | })) 224 | }); 225 | catChildren.push(ContextMenu.buildMenuItem({ 226 | label: "Delete Category", danger: true, action: _ => { 227 | BdApi.showConfirmationModal(`Delete '${cat.name}'`, [ 228 | React.createElement(BdApi.findModuleByDisplayName("Card"), { 229 | children: [ 230 | React.createElement(BdApi.findModuleByDisplayName("LegacyText"), { 231 | children: ["Are you sure you want to delete ", React.createElement("strong", {}, cat.name), "? This action cannot be undone."], 232 | size: "size16-rrJ6ag" 233 | }) 234 | ], 235 | "type": "cardWarning", 236 | "className": "card-1LSSlz spacing-1JirW3 marginBottom20-315RVT", 237 | }) 238 | ], { 239 | danger: true, 240 | confirmText: "Delete", 241 | onConfirm: _ => { 242 | Library.Utilities.removeFromArray(categories, categories[categories.indexOf(cat)]); 243 | this.forceUpdate(); 244 | } 245 | }) 246 | } 247 | })) 248 | children.push(ContextMenu.buildMenuItem({ 249 | label: cat.name, 250 | children: catChildren 251 | })); 252 | }) 253 | 254 | messages.forEach(message => { 255 | if (messages.indexOf(message) === 0) children.push(ContextMenu.buildMenuItem({ type: 'separator' })) 256 | children.push(ContextMenu.buildMenuItem({ 257 | label: message, 258 | action: _ => { 259 | if (!shouldPaste) return; 260 | ComponentDispatch.dispatch("INSERT_TEXT", { content: message, plainText: message }) 261 | }, 262 | hint: React.createElement(TooltipContainer, 263 | { 264 | text: "Delete" 265 | }, 266 | React.createElement(TrashIcon, { 267 | style: { color: "var(--status-danger)" }, 268 | onClick: _ => { 269 | shouldPaste = false; 270 | configArrayRemove("QuickMessages", 'messages', message); 271 | this.forceUpdate(); 272 | BdApi.showToast(`Successfully removed Quick Message!`, { type: 'success' }); 273 | }, 274 | width: '15px', 275 | height: '15px' 276 | }) 277 | ) 278 | })); 279 | }) 280 | 281 | 282 | const patch = (_, [props], ret) => { 283 | Patcher.after(ChannelTextAreaContainer, "render", (_, [{ textValue }], ret) => { 284 | text = textValue; 285 | }); 286 | 287 | ret.props.children.push( 288 | ContextMenu.buildMenuItem({ 289 | type: "separator" 290 | }), 291 | ContextMenu.buildMenuItem({ 292 | label: "Save as Quick Message", 293 | // disabled: props.editor.containerRef.current.textContent.slice(0, -1) == props.editor.props.placeholder, 294 | action: _ => { 295 | if (text !== "") { 296 | configArrayPush("QuickMessages", "messages", text); 297 | this.forceUpdate(); 298 | } else { 299 | BdApi.showToast(`You cannot save an empty message!`, { type: 'error' }); 300 | } 301 | }, 302 | children: [ 303 | saveToCategory, 304 | ContextMenu.buildMenuItem({ type: 'separator' }), 305 | ContextMenu.buildMenuItem({ 306 | label: 'Create a category...', 307 | action: _ => { 308 | const FormItem = BdApi.findModuleByDisplayName("FormItem"); 309 | const TextInput = BdApi.findModuleByDisplayName("TextInput"); 310 | const Text = BdApi.findModuleByDisplayName("LegacyText"); 311 | let categoryName = ""; 312 | 313 | Library.Modals.showModal("Create Category", [ 314 | React.createElement(FormItem, { 315 | title: "Category Name", 316 | children: [ 317 | React.createElement(TextInput, { 318 | type: "text", 319 | placeholder: "New Category", 320 | onChange: e => { 321 | categoryName = e; 322 | } 323 | }), 324 | React.createElement(Text, { 325 | children: ["This field is required"], 326 | className: "marginTop8-24uXGp", 327 | style: { color: "var(--text-danger)" }, 328 | }) 329 | ] 330 | }) 331 | ], { 332 | danger: false, 333 | confirmText: "Create", 334 | onConfirm: _ => { 335 | const category = categories.filter(e => e.name === categoryName)[0]; 336 | if (category) { 337 | categories[categories.indexOf(category)].items.push(text); 338 | this.forceUpdate(); 339 | } else { 340 | categories.push({ 341 | name: categoryName, 342 | items: [text] 343 | }); 344 | this.forceUpdate(); 345 | } 346 | } 347 | 348 | }) 349 | } 350 | }) 351 | ] 352 | }), 353 | ContextMenu.buildMenuItem({ 354 | label: "Quick Messages", 355 | children: children.length > 0 ? children : ContextMenu.buildMenuItem({ label: 'None' }), 356 | })); 357 | }; 358 | Patcher.after(SlateTextAreaContextMenu, "default", patch) 359 | 360 | } 361 | } 362 | 363 | return QuickMessages; 364 | })(global.ZeresPluginLibrary.buildPlugin(config)); -------------------------------------------------------------------------------- /QuickMessages/README.md: -------------------------------------------------------------------------------- 1 | # QuickMessages [![Download][icon]][link] 2 | 3 | Save messages to quickly send them later, when you need 4 | ![example](https://i.gyazo.com/ef1e20d5074cd2a633015c5a72d2f063.gif) 5 | 6 | ## Changelogv1.2 7 | Added: 8 | * Added categories 🥳 Hover the "Save as Quick Message" button to use the categories. 9 | I still need ideas and suggestions, so if you have some, feel free to send them to me in the support server https://discord.gg/zJbXFXNAhJ 10 | 11 | [icon]: https://img.shields.io/badge/Download-QuickMessages-brightgreen.svg 12 | [link]: https://betterdiscord.net/ghdl?id=3557 13 | -------------------------------------------------------------------------------- /QuickToggler/README.md: -------------------------------------------------------------------------------- 1 | # QuickToggler 2 | 3 | > Allows you to open a toggle-able addon search with a keybind (default keybind: CTRL+D) 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /TypingUsersAvatars/README.md: -------------------------------------------------------------------------------- 1 | # Typing Users Avatars 2 | [![Download][icon]][link] 3 | 4 | Shows avatars of typing users. 5 | 6 | CSS provided by [David](https://github.com/dav1312). 7 | 8 | ### Preview 9 | [![Preview](https://i.gyazo.com/6c47a3fa4d3448f0aa4cc03c7953e434.gif)](https://gyazo.com/6c47a3fa4d3448f0aa4cc03c7953e434) 10 | 11 | [icon]: https://img.shields.io/badge/Download-Typing%20Users%20Avatars-brightgreen.svg 12 | [link]: https://betterdiscord.app/plugin/TypingUsersAvatars -------------------------------------------------------------------------------- /TypingUsersAvatars/TypingUsersAvatars.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name TypingUsersAvatars 3 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/blob/main/TypingUsersAvatars/TypingUsersAvatars.plugin.js 4 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/TypingUsersAvatars/TypingUsersAvatars.plugin.js 5 | * @website https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/TypingUsersAvatars 6 | * @version 1.0.5 7 | * @description Shows avatars of typing users. 8 | */ 9 | 10 | const request = require('request'); 11 | const fs = require('fs'); 12 | const path = require('path'); 13 | 14 | const config = { 15 | info: { 16 | name: 'TypingUsersAvatars', 17 | authors: [ 18 | { 19 | name: 'QWERT' 20 | } 21 | ], 22 | version: '1.0.5', 23 | description: 'Shows avatars of typing users.', 24 | github_raw: "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/TypingUsersAvatars/TypingUsersAvatars.plugin.js", 25 | }, 26 | changelog: [ 27 | { 28 | title: 'What\'s new?', 29 | type: 'added', 30 | items: [ 31 | 'Added option to show guild avatars of typing users', 32 | ] 33 | } 34 | ], 35 | defaultConfig: [ 36 | { 37 | type: 'switch', 38 | name: 'Show users status', 39 | id: 'showStatus', 40 | value: true 41 | }, 42 | { 43 | type: 'switch', 44 | name: 'Show guild avatars', 45 | id: 'showGuildAvatar', 46 | value: true 47 | } 48 | ] 49 | }; 50 | 51 | module.exports = !global.ZeresPluginLibrary ? class { 52 | constructor() { 53 | this._config = config; 54 | } 55 | 56 | load() { 57 | BdApi.showConfirmationModal('Library plugin is needed', 58 | `The library plugin needed for AQWERT'sPluginBuilder is missing. Please click Download Now to install it.`, { 59 | confirmText: 'Download', 60 | cancelText: 'Cancel', 61 | onConfirm: () => { 62 | request.get('https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js', (error, response, body) => { 63 | if (error) 64 | return electron.shell.openExternal('https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js'); 65 | 66 | fs.writeFileSync(path.join(BdApi.Plugins.folder, '0PluginLibrary.plugin.js'), body); 67 | }); 68 | } 69 | }); 70 | } 71 | 72 | start() { } 73 | 74 | stop() { } 75 | } : (([Plugin, Library]) => { 76 | const { DiscordModules, WebpackModules, PluginUtilities, Patcher, ReactComponents, Popouts, Utilities, DiscordSelectors } = Library; 77 | const { React, UserStore, RelationshipStore, UserStatusStore, Strings } = DiscordModules; 78 | const AssetUtils = WebpackModules.getByProps("getUserBannerURL"); 79 | const Avatar = WebpackModules.getByProps('AnimatedAvatar'); 80 | const VoiceUserSummary = WebpackModules.findByDisplayName("VoiceUserSummaryItem") 81 | 82 | class AvatarComponent extends React.Component { 83 | render() { 84 | const { user, status, guildId } = this.props; 85 | const guildAvatar = AssetUtils.getGuildMemberAvatarURL({ guildId: guildId, userId: user.id, avatar: user.guildMemberAvatars[guildId] }); 86 | return React.createElement(Avatar.default, { 87 | src: user?.guildMemberAvatars[guildId] ? guildAvatar : user.getAvatarURL(), 88 | status: status, 89 | size: Avatar.Sizes.SIZE_16, 90 | onClick() { 91 | Popouts.showUserPopout(document.getElementById(`typing-user-${user.id}`), user) 92 | } 93 | }) 94 | } 95 | } 96 | 97 | class plugin extends Plugin { 98 | constructor() { 99 | super(); 100 | this.getSettingsPanel = () => { 101 | return this.buildSettingsPanel().getElement(); 102 | }; 103 | } 104 | 105 | onStart() { 106 | Utilities.suppressErrors(this.patch.bind(this))(); 107 | 108 | PluginUtilities.addStyle('TypingUsersAvatars', ` 109 | .typing-2J1mQU .text-3S7XCz { 110 | margin: 0; 111 | } 112 | 113 | .typing-2J1mQU .wrapper-1VLyxH { 114 | display: flex; 115 | margin: 0 4px; 116 | } 117 | 118 | .typing-2J1mQU .text-3S7XCz, 119 | .typing-2J1mQU .text-3S7XCz > strong { 120 | display: contents; 121 | } 122 | 123 | .several-users { 124 | margin-left: 5px; 125 | margin-right: 5px; 126 | } 127 | 128 | .several-users .avatarSize-1KpZ5E { 129 | margin: 0; 130 | } 131 | `) 132 | } 133 | 134 | onStop() { 135 | Patcher.unpatchAll(); 136 | PluginUtilities.removeStyle('TypingUsersAvatars'); 137 | } 138 | 139 | filter(users) { 140 | return Object.keys(users).filter((user) => { 141 | return user != UserStore.getCurrentUser().id && !RelationshipStore.isBlocked(user); 142 | }) 143 | } 144 | 145 | /* code highly inspired by https://github.com/rauenzi/BetterDiscordAddons/blob/master/Plugins/BetterRoleColors/BetterRoleColors.plugin.js */ 146 | async patch() { 147 | const TypingUsers = await ReactComponents.getComponentByName('TypingUsers', DiscordSelectors.Typing.typing); 148 | Patcher.after(TypingUsers.component.prototype, 'render', (thisObject, [props], ret) => { 149 | const typingUsers = this.filter({ ...thisObject.props.typingUsers }); 150 | const guildId = thisObject.props?.guildId; 151 | 152 | for (let u = 0; u < typingUsers.length; u++) { 153 | const user = UserStore.getUser(typingUsers[u]); 154 | const status = this.settings.showStatus ? UserStatusStore.getStatus(user.id) : null; 155 | 156 | if (ret.props.children[0].props.children[1]?.props.children !== Strings.Messages.SEVERAL_USERS_TYPING) { 157 | const usersComponent = ret.props.children[0].props.children[1].props.children.filter(user => user.props); 158 | 159 | usersComponent[u].props.children.unshift(React.createElement("div", { 160 | id: `typing-user-${user.id}`, 161 | children: React.createElement(AvatarComponent, { user, status, guildId }) 162 | })); 163 | } else { 164 | ret.props.children[0].props.children = [ 165 | React.createElement(VoiceUserSummary, { 166 | className: "several-users", 167 | users: typingUsers.map(UserStore.getUser), 168 | max: 3 169 | }), 170 | ret.props.children[0].props.children 171 | ] 172 | } 173 | } 174 | 175 | if (!ret) return; 176 | const tree = ret.props.children; 177 | if (!tree) return; 178 | 179 | tree.map((child) => { 180 | const children = child?.props?.children; 181 | if (!children || typeof children !== 'object') return; 182 | 183 | child.props.style = { 184 | display: 'flex', 185 | alignItems: 'center' 186 | }; 187 | }) 188 | }) 189 | } 190 | 191 | } 192 | 193 | return plugin; 194 | })(global.ZeresPluginLibrary.buildPlugin(config)); 195 | -------------------------------------------------------------------------------- /UserVolumeBooster/README.md: -------------------------------------------------------------------------------- 1 | # UserVolumeBooster 2 | 3 | > Allows you to set a user's volume above the normal 200% 4 |
5 | 6 | 7 | Made with by BDBuilder -------------------------------------------------------------------------------- /UserVolumeBooster/UserVolumeBooster.plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name UserVolumeBooster 3 | * @description Allows you to set a user's volume above the normal 200% 4 | * @version 1.0.2 5 | * @author QWERT 6 | * @source https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/UserVolumeBooster 7 | * @updateUrl https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/UserVolumeBooster/UserVolumeBooster.plugin.js 8 | */ 9 | /*@cc_on 10 | @if (@_jscript) 11 | 12 | // Offer to self-install for clueless users that try to run this directly. 13 | var shell = WScript.CreateObject("WScript.Shell"); 14 | var fs = new ActiveXObject("Scripting.FileSystemObject"); 15 | var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins"); 16 | var pathSelf = WScript.ScriptFullName; 17 | // Put the user at ease by addressing them in the first person 18 | shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30); 19 | if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) { 20 | shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40); 21 | } else if (!fs.FolderExists(pathPlugins)) { 22 | shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10); 23 | } else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) { 24 | fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true); 25 | // Show the user where to put plugins in the future 26 | shell.Exec("explorer " + pathPlugins); 27 | shell.Popup("I'm installed!", 0, "Successfully installed", 0x40); 28 | } 29 | WScript.Quit(); 30 | @else@*/ 31 | /* Generated Code */ 32 | const config = { 33 | "info": { 34 | "name": "UserVolumeBooster", 35 | "description": "Allows you to set a user's volume above the normal 200%", 36 | "version": "1.0.2", 37 | "authors": [{ 38 | "name": "QWERT", 39 | "discord_id": "678556376640913408", 40 | "github_username": "QWERTxD" 41 | }], 42 | "github": "https://github.com/QWERTxD/BetterDiscordPlugins/tree/main/UserVolumeBooster", 43 | "github_raw": "https://raw.githubusercontent.com/QWERTxD/BetterDiscordPlugins/main/UserVolumeBooster/UserVolumeBooster.plugin.js" 44 | }, 45 | "build": { 46 | "zlibrary": true, 47 | "copy": true, 48 | "production": false, 49 | "scssHash": false, 50 | "alias": { 51 | "icons": "components/icons" 52 | }, 53 | "release": { 54 | "source": true, 55 | "readme": true 56 | } 57 | } 58 | }; 59 | function buildPlugin([BasePlugin, PluginApi]) { 60 | const module = { 61 | exports: {} 62 | }; 63 | (() => { 64 | "use strict"; 65 | class StyleLoader { 66 | static styles = ""; 67 | static element = null; 68 | static append(module, css) { 69 | this.styles += `/* ${module} */\n${css}`; 70 | } 71 | static inject(name = config.info.name) { 72 | if (this.element) this.element.remove(); 73 | this.element = document.head.appendChild(Object.assign(document.createElement("style"), { 74 | id: name, 75 | textContent: this.styles 76 | })); 77 | } 78 | static remove() { 79 | if (this.element) { 80 | this.element.remove(); 81 | this.element = null; 82 | } 83 | } 84 | } 85 | function ___createMemoize___(instance, name, value) { 86 | value = value(); 87 | Object.defineProperty(instance, name, { 88 | value, 89 | configurable: true 90 | }); 91 | return value; 92 | }; 93 | const Modules = { 94 | get 'react-spring'() { 95 | return ___createMemoize___(this, 'react-spring', () => BdApi.findModuleByProps('useSpring')) 96 | }, 97 | '@discord/utils': { 98 | get 'joinClassNames'() { 99 | return ___createMemoize___(this, 'joinClassNames', () => BdApi.findModule(e => e.toString().indexOf('return e.join(" ")') > 200)) 100 | }, 101 | get 'useForceUpdate'() { 102 | return ___createMemoize___(this, 'useForceUpdate', () => BdApi.findModuleByProps('useForceUpdate')?.useForceUpdate) 103 | }, 104 | get 'Logger'() { 105 | return ___createMemoize___(this, 'Logger', () => BdApi.findModuleByProps('setLogFn')?.default) 106 | }, 107 | get 'Navigation'() { 108 | return ___createMemoize___(this, 'Navigation', () => BdApi.findModuleByProps('replaceWith', 'currentRouteIsPeekView')) 109 | } 110 | }, 111 | '@discord/components': { 112 | get 'Tooltip'() { 113 | return ___createMemoize___(this, 'Tooltip', () => BdApi.findModuleByDisplayName('Tooltip')) 114 | }, 115 | get 'TooltipContainer'() { 116 | return ___createMemoize___(this, 'TooltipContainer', () => BdApi.findModuleByProps('TooltipContainer')?.TooltipContainer) 117 | }, 118 | get 'TextInput'() { 119 | return ___createMemoize___(this, 'TextInput', () => BdApi.findModuleByDisplayName('TextInput')) 120 | }, 121 | get 'SlideIn'() { 122 | return ___createMemoize___(this, 'SlideIn', () => BdApi.findModuleByDisplayName('SlideIn')) 123 | }, 124 | get 'SettingsNotice'() { 125 | return ___createMemoize___(this, 'SettingsNotice', () => BdApi.findModuleByDisplayName('SettingsNotice')) 126 | }, 127 | get 'TransitionGroup'() { 128 | return ___createMemoize___(this, 'TransitionGroup', () => BdApi.findModuleByDisplayName('TransitionGroup')) 129 | }, 130 | get 'Button'() { 131 | return ___createMemoize___(this, 'Button', () => BdApi.findModule(m => 'DropdownSizes' in m && typeof(m) === 'function')) 132 | }, 133 | get 'Popout'() { 134 | return ___createMemoize___(this, 'Popout', () => BdApi.findModuleByDisplayName('Popout')) 135 | }, 136 | get 'Flex'() { 137 | return ___createMemoize___(this, 'Flex', () => BdApi.findModuleByDisplayName('Flex')) 138 | }, 139 | get 'Text'() { 140 | return ___createMemoize___(this, 'Text', () => BdApi.findModuleByDisplayName('LegacyText')) 141 | }, 142 | get 'Card'() { 143 | return ___createMemoize___(this, 'Card', () => BdApi.findModuleByDisplayName('Card')) 144 | } 145 | }, 146 | '@discord/modules': { 147 | get 'Dispatcher'() { 148 | return ___createMemoize___(this, 'Dispatcher', () => BdApi.findModuleByProps('dispatch', 'isDispatching')) 149 | }, 150 | get 'ComponentDispatcher'() { 151 | return ___createMemoize___(this, 'ComponentDispatcher', () => BdApi.findModuleByProps('ComponentDispatch')?.ComponentDispatch) 152 | }, 153 | get 'EmojiUtils'() { 154 | return ___createMemoize___(this, 'EmojiUtils', () => BdApi.findModuleByProps('uploadEmoji')) 155 | }, 156 | get 'PermissionUtils'() { 157 | return ___createMemoize___(this, 'PermissionUtils', () => BdApi.findModuleByProps('computePermissions', 'canManageUser')) 158 | }, 159 | get 'DMUtils'() { 160 | return ___createMemoize___(this, 'DMUtils', () => BdApi.findModuleByProps('openPrivateChannel')) 161 | } 162 | }, 163 | '@discord/stores': { 164 | get 'Messages'() { 165 | return ___createMemoize___(this, 'Messages', () => BdApi.findModuleByProps('getMessage', 'getMessages')) 166 | }, 167 | get 'Channels'() { 168 | return ___createMemoize___(this, 'Channels', () => BdApi.findModuleByProps('getChannel', 'getDMFromUserId')) 169 | }, 170 | get 'Guilds'() { 171 | return ___createMemoize___(this, 'Guilds', () => BdApi.findModuleByProps('getGuild')) 172 | }, 173 | get 'SelectedGuilds'() { 174 | return ___createMemoize___(this, 'SelectedGuilds', () => BdApi.findModuleByProps('getGuildId', 'getLastSelectedGuildId')) 175 | }, 176 | get 'SelectedChannels'() { 177 | return ___createMemoize___(this, 'SelectedChannels', () => BdApi.findModuleByProps('getChannelId', 'getLastSelectedChannelId')) 178 | }, 179 | get 'Info'() { 180 | return ___createMemoize___(this, 'Info', () => BdApi.findModuleByProps('getSessionId')) 181 | }, 182 | get 'Status'() { 183 | return ___createMemoize___(this, 'Status', () => BdApi.findModuleByProps('getStatus', 'getActivities', 'getState')) 184 | }, 185 | get 'Users'() { 186 | return ___createMemoize___(this, 'Users', () => BdApi.findModuleByProps('getUser', 'getCurrentUser')) 187 | }, 188 | get 'SettingsStore'() { 189 | return ___createMemoize___(this, 'SettingsStore', () => BdApi.findModuleByProps('afkTimeout', 'status')) 190 | }, 191 | get 'UserProfile'() { 192 | return ___createMemoize___(this, 'UserProfile', () => BdApi.findModuleByProps('getUserProfile')) 193 | }, 194 | get 'Members'() { 195 | return ___createMemoize___(this, 'Members', () => BdApi.findModuleByProps('getMember')) 196 | }, 197 | get 'Activities'() { 198 | return ___createMemoize___(this, 'Activities', () => BdApi.findModuleByProps('getActivities')) 199 | }, 200 | get 'Games'() { 201 | return ___createMemoize___(this, 'Games', () => BdApi.findModuleByProps('getGame', 'games')) 202 | }, 203 | get 'Auth'() { 204 | return ___createMemoize___(this, 'Auth', () => BdApi.findModuleByProps('getId', 'isGuest')) 205 | }, 206 | get 'TypingUsers'() { 207 | return ___createMemoize___(this, 'TypingUsers', () => BdApi.findModuleByProps('isTyping')) 208 | } 209 | }, 210 | '@discord/actions': { 211 | get 'ProfileActions'() { 212 | return ___createMemoize___(this, 'ProfileActions', () => BdApi.findModuleByProps('fetchProfile')) 213 | }, 214 | get 'GuildActions'() { 215 | return ___createMemoize___(this, 'GuildActions', () => BdApi.findModuleByProps('requestMembersById')) 216 | } 217 | }, 218 | get '@discord/i18n'() { 219 | return ___createMemoize___(this, '@discord/i18n', () => BdApi.findModule(m => m.Messages?.CLOSE && typeof(m.getLocale) === 'function')) 220 | }, 221 | get '@discord/constants'() { 222 | return ___createMemoize___(this, '@discord/constants', () => BdApi.findModuleByProps('API_HOST')) 223 | }, 224 | get '@discord/contextmenu'() { 225 | return ___createMemoize___(this, '@discord/contextmenu', () => { 226 | const ctx = Object.assign({}, BdApi.findModuleByProps('openContextMenu'), BdApi.findModuleByProps('MenuItem')); 227 | ctx.Menu = ctx.default; 228 | return ctx; 229 | }) 230 | }, 231 | get '@discord/forms'() { 232 | return ___createMemoize___(this, '@discord/forms', () => BdApi.findModuleByProps('FormItem')) 233 | }, 234 | get '@discord/scrollbars'() { 235 | return ___createMemoize___(this, '@discord/scrollbars', () => BdApi.findModuleByProps('ScrollerAuto')) 236 | }, 237 | get '@discord/native'() { 238 | return ___createMemoize___(this, '@discord/native', () => BdApi.findModuleByProps('requireModule')) 239 | }, 240 | get '@discord/flux'() { 241 | return ___createMemoize___(this, '@discord/flux', () => Object.assign({}, BdApi.findModuleByProps('useStateFromStores').default, BdApi.findModuleByProps('useStateFromStores'))) 242 | }, 243 | get '@discord/modal'() { 244 | return ___createMemoize___(this, '@discord/modal', () => Object.assign({}, BdApi.findModuleByProps('ModalRoot'), BdApi.findModuleByProps('openModal', 'closeAllModals'))) 245 | }, 246 | get '@discord/connections'() { 247 | return ___createMemoize___(this, '@discord/connections', () => BdApi.findModuleByProps('get', 'isSupported', 'map')) 248 | }, 249 | get '@discord/sanitize'() { 250 | return ___createMemoize___(this, '@discord/sanitize', () => BdApi.findModuleByProps('stringify', 'parse', 'encode')) 251 | }, 252 | get '@discord/icons'() { 253 | return ___createMemoize___(this, '@discord/icons', () => BdApi.findAllModules(m => m.displayName && ~m.toString().indexOf('currentColor')).reduce((icons, icon) => (icons[icon.displayName] = icon, icons), {})) 254 | }, 255 | '@discord/classes': { 256 | get 'Timestamp'() { 257 | return ___createMemoize___(this, 'Timestamp', () => BdApi.findModuleByPrototypes('toDate', 'month')) 258 | }, 259 | get 'Message'() { 260 | return ___createMemoize___(this, 'Message', () => BdApi.findModuleByPrototypes('getReaction', 'isSystemDM')) 261 | }, 262 | get 'User'() { 263 | return ___createMemoize___(this, 'User', () => BdApi.findModuleByPrototypes('tag')) 264 | }, 265 | get 'Channel'() { 266 | return ___createMemoize___(this, 'Channel', () => BdApi.findModuleByPrototypes('isOwner', 'isCategory')) 267 | } 268 | } 269 | }; 270 | var __webpack_require__ = {}; 271 | (() => { 272 | __webpack_require__.d = (exports, definition) => { 273 | for (var key in definition) 274 | if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, { 275 | enumerable: true, 276 | get: definition[key] 277 | }); 278 | }; 279 | })(); 280 | (() => { 281 | __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 282 | })(); 283 | (() => { 284 | __webpack_require__.r = exports => { 285 | if ("undefined" !== typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, { 286 | value: "Module" 287 | }); 288 | Object.defineProperty(exports, "__esModule", { 289 | value: true 290 | }); 291 | }; 292 | })(); 293 | var __webpack_exports__ = {}; 294 | __webpack_require__.r(__webpack_exports__); 295 | __webpack_require__.d(__webpack_exports__, { 296 | default: () => Plugin 297 | }); 298 | const { 299 | React, 300 | ReactDOM, 301 | Patcher, 302 | findModule: get, 303 | findModuleByProps: getByProps, 304 | findModuleByDisplayName: getByName, 305 | getData, 306 | setData 307 | } = BdApi; 308 | const Slider = getByName("Slider"); 309 | const FormItem = getByName("FormItem"); 310 | class Plugin { 311 | start() { 312 | console.log("%cUser Volume Booster", "background: #61DBFB; color: black; padding: 2px; border-radius: 4px; font-weight: bold;", "Successfully started."); 313 | this.patch(); 314 | } 315 | stop() { 316 | Patcher.unpatchAll("slider"); 317 | console.log("%cUser Volume Booster", "background: #61DBFB; color: black; padding: 2px; border-radius: 4px; font-weight: bold;", "Stopped."); 318 | } 319 | patch() { 320 | Patcher.after("slider", Slider.prototype, "render", ((_this, [props]) => { 321 | if ("slider-BEB8u7" !== _this?.props?.className) return; 322 | _this.props.maxValue = 200 * this.getMultiplier(); 323 | _this.state.range = 200 * this.getMultiplier(); 324 | _this.state.max = 200 * this.getMultiplier(); 325 | _this.state.value = _this.state.initialValueProp; 326 | })); 327 | } 328 | getMultiplier() { 329 | return getData("UserVolumeBooster", "multiplier") ?? 2; 330 | } 331 | getSettingsPanel() { 332 | return React.createElement(FormItem, { 333 | title: "Volume Multiplier" 334 | }, React.createElement(Slider, { 335 | initialValue: this.getMultiplier(), 336 | max: 5, 337 | min: 1, 338 | markers: [1, 2, 3, 4, 5], 339 | stickToMarkers: true, 340 | onValueChange: value => { 341 | setData("UserVolumeBooster", "multiplier", value); 342 | } 343 | })); 344 | } 345 | } 346 | module.exports.LibraryPluginHack = __webpack_exports__; 347 | })(); 348 | const PluginExports = module.exports.LibraryPluginHack; 349 | return PluginExports?.__esModule ? PluginExports.default : PluginExports; 350 | } 351 | module.exports = window.hasOwnProperty("ZeresPluginLibrary") ? 352 | buildPlugin(window.ZeresPluginLibrary.buildPlugin(config)) : 353 | class { 354 | getName() { 355 | return config.info.name; 356 | } 357 | getAuthor() { 358 | return config.info.authors.map(a => a.name).join(", "); 359 | } 360 | getDescription() { 361 | return `${config.info.description}. __**ZeresPluginLibrary was not found! This plugin will not work!**__`; 362 | } 363 | getVersion() { 364 | return config.info.version; 365 | } 366 | load() { 367 | BdApi.showConfirmationModal( 368 | "Library plugin is needed", 369 | [`The library plugin needed for ${config.info.name} is missing. Please click Download to install it.`], { 370 | confirmText: "Download", 371 | cancelText: "Cancel", 372 | onConfirm: () => { 373 | require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", async (error, response, body) => { 374 | if (error) return require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"); 375 | await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r)); 376 | }); 377 | } 378 | } 379 | ); 380 | } 381 | start() {} 382 | stop() {} 383 | }; 384 | /*@end@*/ --------------------------------------------------------------------------------