Remove BetterDiscord

master
kageru 3 years ago
parent 9e12149fdf
commit 5df0be31a3
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2

File diff suppressed because it is too large Load Diff

@ -1,6 +0,0 @@
{
"currentVersionInfo": {
"version": "0.1.2",
"hasShownChangelog": true
}
}

@ -1,141 +0,0 @@
//META{"name":"AccountDetailsPlus","displayName":"AccountDetailsPlus","website":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/AccountDetailsPlus","source":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/AccountDetailsPlus/AccountDetailsPlus.plugin.js"}*//
var AccountDetailsPlus = (() => {
const config = {"info":{"name":"AccountDetailsPlus","authors":[{"name":"Zerebos","discord_id":"249746236008169473","github_username":"rauenzi","twitter_username":"ZackRauen"}],"version":"0.1.2","description":"Lets you view popout, nickname and more from your account panel at the bottom. Support Server: bit.ly/ZeresServer","github":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/AccountDetailsPlus","github_raw":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/AccountDetailsPlus/AccountDetailsPlus.plugin.js"},"defaultConfig":[{"type":"category","id":"popout","name":"User Popout","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"avatar","name":"Avatar","note":"Opens your popout when clicking your avatar.","value":true},{"type":"switch","id":"username","name":"Username","note":"Opens your popout when clicking your username.","value":true}]},{"type":"category","id":"statusPicker","name":"Status Picker","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"avatar","name":"Avatar","note":"Opens your popout when right clicking your avatar.","value":true},{"type":"switch","id":"username","name":"Username","note":"Opens your popout when right clicking your username.","value":true}]},{"type":"category","id":"nickname","name":"Nickname","collapsible":true,"shown":false,"settings":[{"type":"dropdown","id":"showNickname","name":"Name Shown","value":true,"options":[{"label":"Username","value":false},{"label":"Nickname","value":true}]},{"type":"switch","id":"oppositeOnHover","name":"Opposite On Hover","note":"Shows the opposite on hover. e.g. if you are showing nickname, hovering will show your username.","value":true}]}],"changelog":[{"title":"Bugs Squashed","type":"fixed","items":["Fixed that one issue where it didn't work."]}],"main":"index.js"};
return !global.ZeresPluginLibrary ? class {
getName() {return config.info.name;}
getAuthor() {return config.info.authors.map(a => a.name).join(", ");}
getDescription() {return config.info.description;}
getVersion() {return config.info.version;}
load() {window.BdApi.alert("Library Missing",`The library plugin needed for ${config.info.name} is missing.<br /><br /> <a href="https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js" target="_blank">Click here to download the library!</a>`);}
start() {}
stop() {}
} : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const {PluginUtilities, DiscordModules, DiscordSelectors, ReactTools, DOMTools} = Api;
return class AccountDetailsPlus extends Plugin {
constructor() {
super();
this.usernameCSS = `.container-iksrDt .nameTag-26T3kW { cursor: pointer; }`;
this.popoutOpen = false;
}
async onStart() {
await new Promise(resolve => setTimeout(resolve, 1000));
this.FluxContainer = DiscordModules.UserPopout;
this.currentUser = DiscordModules.UserStore.getCurrentUser();
this.popoutWrapper = ReactTools.getReactProperty(document.querySelector(DiscordSelectors.AccountDetails.container + " .inner-1W0Bkn"), "return.return.return.return.return.return.return.stateNode");
this.originalRender = this.popoutWrapper.props.render;
this.activateShit();
}
onStop() {
this.popoutWrapper.props.render = this.originalRender;
PluginUtilities.removeStyle(this.getName() + "-css");
DOMTools.off(".AccountDetailsPlus");
this.saveSettings();
}
activateShit() {
document.querySelector(DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag).off("." + this.getName());
document.querySelector(DiscordSelectors.AccountDetails.container + " .inner-1W0Bkn").off("." + this.getName());
this.usernameCSS = DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag + "{ cursor: pointer; }";
PluginUtilities.removeStyle(this.getName() + "-css");
DOMTools.off(document, "mousemove." + this.getName());
document.querySelector(DiscordSelectors.AccountDetails.container.descend(".username")).textContent = this.currentUser.username;
if (this.settings.nickname.showNickname || this.settings.nickname.oppositeOnHover) {
DOMTools.on(document, "mousemove." + this.getName(), (e) => { this.adjustNickname(e); });
}
if (this.settings.popout.username) {
PluginUtilities.addStyle(this.getName() + "-css", this.usernameCSS);
document.querySelector(DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag).on("mousedown." + this.getName(), () => { this.popoutOpen = this.popoutWrapper.state.isOpen; });
document.querySelector(DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag).on("click." + this.getName(), (e) => { if (!this.popoutOpen) this.showUserPopout(e); });
}
if (this.settings.popout.avatar) {
document.querySelector(DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag).on("mousedown." + this.getName(), () => { this.popoutOpen = this.popoutWrapper.state.isOpen; });
document.querySelector(DiscordSelectors.AccountDetails.container + " .inner-1W0Bkn").on("click." + this.getName(), (e) => { if (!this.popoutOpen) this.showUserPopout(e); });
}
if (this.settings.statusPicker.username) {
document.querySelector(DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag).on("mousedown." + this.getName(), () => { this.popoutOpen = this.popoutWrapper.state.isOpen; });
document.querySelector(DiscordSelectors.AccountDetails.container + DiscordSelectors.AccountDetails.nameTag).on("contextmenu." + this.getName(), (e) => {
if (!this.popoutOpen) this.showStatusPicker(e);
});
}
if (this.settings.statusPicker.avatar) {
document.querySelector(DiscordSelectors.AccountDetails.container + " .inner-1W0Bkn").on("mousedown." + this.getName(), () => { this.popoutOpen = this.popoutWrapper.state.isOpen; });
document.querySelector(DiscordSelectors.AccountDetails.container + " .inner-1W0Bkn").on("contextmenu." + this.getName(), (e) => {
if (!this.popoutOpen) this.showStatusPicker(e);
});
}
}
adjustNickname(e) {
if (!e || !e.target || !(e.target instanceof Element)) return;
let accountDetails = document.querySelector(DiscordSelectors.AccountDetails.container);
if (!accountDetails) return;
let isHovering = accountDetails.contains(e.target);
let nameElement = accountDetails.querySelector(".username");
let nick = DiscordModules.GuildMemberStore.getNick(DiscordModules.SelectedGuildStore.getGuildId(), this.currentUser.id);
nick = nick ? nick : this.currentUser.username;
if (isHovering && this.settings.nickname.oppositeOnHover) {
if (this.settings.nickname.showNickname) nameElement.textContent = this.currentUser.username;
else if (!this.settings.nickname.showNickname) nameElement.textContent = nick;
}
else {
if (this.settings.nickname.showNickname) nameElement.textContent = nick;
else nameElement.textContent = this.currentUser.username;
}
}
setRender(renderer, options = {}) {
this.popoutWrapper.props.render = renderer;
Object.assign(this.popoutWrapper.props, options);
}
showStatusPicker(e) {
e.preventDefault();
e.stopPropagation();
this.setRender(this.originalRender, {position: "top-left", animationType: "spring"});
this.popoutWrapper.toggle(e);
}
showUserPopout(e) {
e.preventDefault();
e.stopPropagation();
var element = document.querySelector(DiscordSelectors.AccountDetails.container);
// e.target = e.currentTarget = e.toElement = e.delegateTarget = document.querySelector(DiscordSelectors.AccountDetails.container);
this.setRender((props) => {
let guild = DiscordModules.SelectedGuildStore.getGuildId();
let channel = DiscordModules.SelectedChannelStore.getChannelId();
return DiscordModules.React.createElement(this.FluxContainer, Object.assign({}, props, {
user: this.currentUser,
guildId: guild,
channelId: channel
}));
}, {position: "top-left", animationType: "default"});
this.popoutWrapper.toggle(Object.assign({}, e, {
target: element,
toElement: element,
currentTarget: element,
delegateTarget: element
}));
}
getSettingsPanel() {
const panel = this.buildSettingsPanel();
panel.addListener(this.updateSettings.bind(this));
return panel.getElement();
}
};
};
return plugin(Plugin, Api);
})(global.ZeresPluginLibrary.buildPlugin(config));
})();

@ -1,3 +0,0 @@
{
"config": "{\"version\":1,\"direcotry\":\"none\"}"
}

@ -1,150 +0,0 @@
//META{"name":"BetterCustomCSS"}*//
/*globals BdApi*/
'use strict';
var BetterCustomCSS = function () {};
BetterCustomCSS.prototype.getAuthor = function () {
return "kosshi";
};
BetterCustomCSS.prototype.getName = function () {
return "BetterCustomCSS";
};
BetterCustomCSS.prototype.getDescription = function () {
return "Lets you edit CSS live with your favorite text editor. Like Custom CSS but better.";
};
BetterCustomCSS.prototype.getVersion = function () {
return "0.1.0";
};
BetterCustomCSS.prototype.start = function () {
let settings = this.loadSettings();
let fs = require('fs');
if(this.accessSync(settings.direcotry)){
let elem = document.createElement("style");
elem.id = "bettercustomcss";
document.head.appendChild(elem);
this.watcher = fs.watch(settings.direcotry, {}, this.appendFile.bind(this));
this.appendFile();
}
};
BetterCustomCSS.prototype.stop = function () {
if( document.getElementById('bettercustomcss') ){
this.watcher.close();
document.head.removeChild( document.getElementById('bettercustomcss') );
}
};
BetterCustomCSS.prototype.appendFile = function () {
let settings = this.loadSettings();
let fs = require('fs');
fs.readFile(settings.direcotry, "utf8", (err, file)=>{
if(err){
BdApi.getCore().alert(
"BetterCustomCSS Error",
"Failed to read '"+settings.direcotry+"'. The plugin will be disabled. Go to the plugin settings and set the path correctly. This usually happens when the file is deleted or renamed."
);
this.stop();
return;
}
document.getElementById('bettercustomcss').innerHTML = file;
});
};
BetterCustomCSS.prototype.load = function () {};
BetterCustomCSS.prototype.unload = function () {};
BetterCustomCSS.prototype.onMessage = function () {};
BetterCustomCSS.prototype.onSwitch = function () {};
BetterCustomCSS.prototype.accessSync = function(dir){
var fs = require('fs');
try {
fs.accessSync(dir, fs.F_OK);
return true;
} catch (e) {
return false;
}
};
BetterCustomCSS.prototype.observer = function () {};
BetterCustomCSS.prototype.saveSettings = function (button) {
var settings = this.loadSettings();
var dir = document.getElementById('qs_directory').value;
var plugin = BdApi.getPlugin('BetterCustomCSS');
var err = document.getElementById('qs_err');
if( plugin.accessSync(dir) ){
settings.direcotry = dir;
bdPluginStorage.set(this.getName(), 'config', JSON.stringify(settings));
plugin.stop();
plugin.start();
err.innerHTML = "";
button.innerHTML = "Saved and applied!";
} else {
err.innerHTML = "Error: Invalid directory!";
return;
}
setTimeout(()=>{button.innerHTML = "Save and apply";},1000);
};
BetterCustomCSS.prototype.settingsVersion = 1;
BetterCustomCSS.prototype.defaultSettings = function () {
return {
version: this.settingsVersion,
direcotry: "none"
};
};
BetterCustomCSS.prototype.resetSettings = function (button) {
var settings = this.defaultSettings();
bdPluginStorage.set(this.getName(), 'config', JSON.stringify(settings));
this.stop();
this.start();
button.innerHTML = "Settings resetted!";
setTimeout(function(){button.innerHTML = "Reset settings";},1000);
};
BetterCustomCSS.prototype.loadSettings = function() {
// Loads settings from localstorage
var settings = (bdPluginStorage.get(this.getName(), 'config')) ? JSON.parse(bdPluginStorage.get(this.getName(), 'config')) : {version:"0"};
if(settings.version != this.settingsVersion){
console.log('['+this.getName()+'] Settings were outdated/invalid/nonexistent. Using default settings.');
settings = this.defaultSettings();
bdPluginStorage.set(this.getName(), 'config', JSON.stringify(settings));
}
return settings;
};
BetterCustomCSS.prototype.import = function (string) {
bdPluginStorage.set(this.getName(), 'config', string);
this.stop();
this.start();
}
BetterCustomCSS.prototype.getSettingsPanel = function () {
var settings = this.loadSettings();
var html = "<h3>Settings Panel</h3><br>";
html += "BetterCustomCSS css file directory<br>";
html += "<input id='qs_directory' type='text' value=" + (settings.direcotry) + " style='width:100% !important;'> <br><br>";
html +="<br><button onclick=BdApi.getPlugin('"+this.getName()+"').saveSettings(this)>Save and apply</button>";
html +="<button onclick=BdApi.getPlugin('"+this.getName()+"').resetSettings(this)>Reset settings</button> <br><br>";
html += "<p style='color:red' id='qs_err'></p>";
html += "How to use:";
html += "<br>1) Create a CSS file that you want to use.";
html += "<br>2) Set the directory setting to the file. (eg C:/Users/youruser/Desktop/theme.css)";
html += "<br>3) The file will be now loaded to the DOM. The plugin attempts to reload the file when it is edited.";
html += "<br>4) You can now open the file in your favorite text editor, edit it, and see the results instantly after saving the file.";
return html;
};

@ -1,57 +0,0 @@
{
"currentVersionInfo": {
"version": "2.3.1",
"hasShownChangelog": true
},
"settings": {
"toolbar": {
"bold": true,
"italic": true,
"underline": true,
"strikethrough": true,
"code": true,
"codeblock": true,
"superscript": true,
"smallcaps": true,
"fullwidth": true,
"upsidedown": true,
"varied": true,
"leet": false,
"thicc": false
},
"formats": {
"superscript": true,
"smallcaps": true,
"fullwidth": true,
"upsidedown": true,
"varied": true,
"leet": false,
"thicc": false
},
"wrappers": {
"superscript": "^^",
"smallcaps": "%%",
"fullwidth": "##",
"upsidedown": "&&",
"varied": "||",
"leet": "++",
"thicc": "$$"
},
"formatting": {
"fullWidthMap": true,
"reorderUpsidedown": true,
"fullwidth": true
},
"plugin": {
"hoverOpen": true,
"chainFormats": true,
"closeOnSend": true
},
"style": {
"icons": true,
"rightSide": true,
"toolbarOpacity": 1,
"fontSize": 85
}
}
}

File diff suppressed because one or more lines are too long

@ -1,6 +0,0 @@
{
"currentVersionInfo": {
"version": "0.7.6",
"hasShownChangelog": true
}
}

@ -1,267 +0,0 @@
//META{"name":"BetterRoleColors","displayName":"BetterRoleColors","website":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/BetterRoleColors","source":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/BetterRoleColors/BetterRoleColors.plugin.js"}*//
var BetterRoleColors = (() => {
const config = {"info":{"name":"BetterRoleColors","authors":[{"name":"Zerebos","discord_id":"249746236008169473","github_username":"rauenzi","twitter_username":"ZackRauen"}],"version":"0.7.6","description":"Adds server-based role colors to typing, voice, popouts, modals and more! Support Server: bit.ly/ZeresServer","github":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/BetterRoleColors","github_raw":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/BetterRoleColors/BetterRoleColors.plugin.js"},"defaultConfig":[{"type":"category","id":"modules","name":"Module Settings","collapsible":true,"shown":true,"settings":[{"type":"switch","id":"typing","name":"Typing","note":"Toggles colorizing of typing notifications.","value":true},{"type":"switch","id":"voice","name":"Voice","note":"Toggles colorizing of voice users.","value":true},{"type":"switch","id":"mentions","name":"Mentions","note":"Toggles colorizing of user mentions in chat.","value":true},{"type":"switch","id":"botTags","name":"Bot Tags","note":"Toggles coloring the background of bot tags to match role.","value":true},{"type":"switch","id":"memberList","name":"Memberlist Headers","note":"Toggles coloring role names in the member list.","value":true}]},{"type":"category","id":"popouts","name":"Popout Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in popouts.","value":false},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in popouts.","value":false},{"type":"switch","id":"nickname","name":"Nickname","note":"Toggles coloring on the nickname in popouts.","value":true},{"type":"switch","id":"fallback","name":"Enable Fallback","note":"If nickname is on and username is off, enabling this will automatically color the username.","value":true}]},{"type":"category","id":"modals","name":"Modal Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in modals.","value":true},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in modals.","value":false}]},{"type":"category","id":"auditLog","name":"Audit Log Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in audit log.","value":true},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in audit log.","value":false}]},{"type":"category","id":"account","name":"Account Details Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"username","name":"Username","note":"Toggles coloring on the username in account details.","value":true},{"type":"switch","id":"discriminator","name":"Discriminator","note":"Toggles coloring on the discriminator in account details.","value":false}]},{"type":"category","id":"mentions","name":"Mention Options","collapsible":true,"shown":false,"settings":[{"type":"switch","id":"changeOnHover","name":"Hover Color","note":"Turning this on adjusts the color on hover to match role color, having it off defers to your theme.","value":true}]}],"changelog":[{"title":"What's New?","items":["Role headers in the memberlist now match the role color! (You can turn this off in settings)"]}],"main":"index.js"};
return !global.ZeresPluginLibrary ? class {
getName() {return config.info.name;}
getAuthor() {return config.info.authors.map(a => a.name).join(", ");}
getDescription() {return config.info.description;}
getVersion() {return config.info.version;}
load() {window.BdApi.alert("Library Missing",`The library plugin needed for ${config.info.name} is missing.<br /><br /> <a href="https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js" target="_blank">Click here to download the library!</a>`);}
start() {}
stop() {}
} : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const {DiscordSelectors, WebpackModules, DiscordModules, PluginUtilities, Patcher, ColorConverter, ReactTools} = Api;
const ReactDOM = DiscordModules.ReactDOM;
const GuildMemberStore = DiscordModules.GuildMemberStore;
const SelectedGuildStore = DiscordModules.SelectedGuildStore;
const UserStore = DiscordModules.UserStore;
const RelationshipStore = DiscordModules.RelationshipStore;
const PopoutWrapper = WebpackModules.getByProps("Positions", "Animations");
const VoiceUser = WebpackModules.find(m => typeof(m) === "function" && m.List);
const UserPopout = DiscordModules.UserPopout;
const UserModal = DiscordModules.UserProfileModal;
const AuditLogItem = WebpackModules.getByPrototypes("renderPermissionUpdate");
const TypingUsers = WebpackModules.findByDisplayName("FluxContainer(TypingUsers)");
return class BetterRoleColors extends Plugin {
constructor() {
super();
this.cancels = [];
}
onStart() {
this.patchVoiceUsers();
this.patchMentions();
this.patchAccountDetails();
this.patchUserPopouts();
this.patchUserModals();
this.patchAuditLog();
this.patchTypingUsers();
this.patchMemberList();
}
onStop() {
Patcher.unpatchAll();
for (const cancel of this.cancels) cancel();
}
getSettingsPanel() {
return this.buildSettingsPanel().getElement();
}
patchAccountDetails() {
const colorize = () => {
if (!this.settings.account.username && !this.settings.account.discriminator) return;
const account = document.querySelector(DiscordSelectors.AccountDetails.accountDetails);
if (!account) return;
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), UserStore.getCurrentUser().id);
const color = member && member.colorString ? member.colorString : "";
if (this.settings.account.username) account.querySelector(".username").style.setProperty("color", color, "important");
if (this.settings.account.discriminator) {
account.querySelector(".discriminator").style.setProperty("color", color, "important");
account.querySelector(".discriminator").style.setProperty("opacity", "1");
}
};
PluginUtilities.addOnSwitchListener(colorize);
this.cancels.push(() => {
PluginUtilities.removeOnSwitchListener(colorize);
const account = document.querySelector(DiscordSelectors.AccountDetails.accountDetails);
account.querySelector(".username").style.setProperty("color", "");
account.querySelector(".discriminator").style.setProperty("color", "");
account.querySelector(".discriminator").style.setProperty("opacity", "");
});
colorize();
}
filterTypingUsers(typingUsers) {
if (!typingUsers) return [];
return Object.keys(typingUsers).filter((e) => {
return e != UserStore.getCurrentUser().id;
}).filter((e) => {
return !RelationshipStore.isBlocked(e);
}).map((e) => {
return UserStore.getUser(e);
}).filter(function(e) {
return e != null;
});
}
patchTypingUsers() {
const brc = this;
Patcher.after(TypingUsers.prototype, "componentDidUpdate", (thisObject) => {
if (!brc.settings.modules.typing) return;
setImmediate(() => {
const typingUsers = this.filterTypingUsers(Object.assign({}, thisObject.state.typingUsers));
document.querySelectorAll(DiscordSelectors.Typing.typing.descend("strong")).forEach((elem, index) => {
if (!typingUsers[index]) return;
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), typingUsers[index].id);
if (!member) return;
elem.style.setProperty("color", member.colorString ? member.colorString : "");
});
});
});
}
patchVoiceUsers() {
const brc = this;
const voiceUserMount = function() {
if (!brc.settings.modules.voice) return;
if (!this || !this.props || !this.props.user) return;
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), this.props.user.id);
if (!member || !member.colorString) return;
const elem = ReactDOM.findDOMNode(this);
elem.querySelector("[class*=\"name\"]").style.setProperty("color", member.colorString);
};
Patcher.after(VoiceUser.prototype, "componentDidMount", (thisObject) => {
const bound = voiceUserMount.bind(thisObject); bound();
});
}
patchMentions() {
const brc = this;
const mentionMount = function() {
if (!brc.settings.modules.mentions) return;
if (!this || !this.props || !this.props.children || !this.props.children.props || this.props.children.props.className != "mention") return;
const props = this.props.render().props;
if (!props || !props.user) return;
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), props.user.id);
if (!member || !member.colorString) return;
const elem = ReactDOM.findDOMNode(this);
elem.style.setProperty("color", member.colorString, "important");
elem.style.setProperty("background", ColorConverter.rgbToAlpha(member.colorString,0.1), "important");
if (!brc.settings.mentions.changeOnHover) return;
elem.addEventListener("mouseenter", (e) =>{
e.target.style.setProperty("color", "#FFFFFF", "important");
e.target.style.setProperty("background", ColorConverter.rgbToAlpha(member.colorString,0.7), "important");
});
elem.addEventListener("mouseleave", (e) => {
e.target.style.setProperty("color", member.colorString, "important");
e.target.style.setProperty("background", ColorConverter.rgbToAlpha(member.colorString,0.1), "important");
});
};
Patcher.after(PopoutWrapper.prototype, "componentDidMount", (thisObject) => {
const bound = mentionMount.bind(thisObject); bound();
});
}
patchUserPopouts() {
const brc = this;
const popoutMount = function() {
if (!brc.settings.popouts.username && !brc.settings.popouts.discriminator && !brc.settings.popouts.nickname) return;
if (!this || !this.props || !this.props.user) return;
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), this.props.user.id);
if (!member || !member.colorString) return;
const elem = ReactDOM.findDOMNode(this);
const hasNickname = Boolean(this.state.nickname);
if (brc.settings.popouts.username || (!hasNickname && brc.settings.popouts.fallback)) elem.querySelector(".username").style.setProperty("color", member.colorString, "important");
if (brc.settings.popouts.discriminator) elem.querySelector(".discriminator").style.setProperty("color", member.colorString, "important");
if (brc.settings.popouts.nickname && hasNickname) elem.querySelector(DiscordSelectors.UserPopout.headerName).style.setProperty("color", member.colorString, "important");
};
Patcher.after(UserPopout.prototype, "componentDidMount", (thisObject) => {
const bound = popoutMount.bind(thisObject); bound();
});
}
patchUserModals() {
const brc = this;
const modalMount = function() {
if (!brc.settings.modals.username && !brc.settings.modals.discriminator) return;
if (!this || !this.props || !this.props.user) return;
const member = GuildMemberStore.getMember(SelectedGuildStore.getGuildId(), this.props.user.id);
if (!member || !member.colorString) return;
const elem = ReactDOM.findDOMNode(this);
if (brc.settings.modals.username) elem.querySelector(".username").style.setProperty("color", member.colorString, "important");
if (brc.settings.modals.discriminator) elem.querySelector(".discriminator").style.setProperty("color", member.colorString, "important");
};
Patcher.after(UserModal.prototype, "componentDidMount", (thisObject) => {
const bound = modalMount.bind(thisObject); bound();
});
}
patchAuditLog() {
const brc = this;
const auditlogMount = function() {
if (!brc.settings.auditLog.username && !brc.settings.auditLog.discriminator) return;
if (!this || !this.props || !this.props.log || !this.props.log.user) return;
const elem = ReactDOM.findDOMNode(this);
const hooks = elem.querySelectorAll(DiscordSelectors.AuditLog.userHook);
const member = GuildMemberStore.getMember(this._reactInternalFiber.return.memoizedProps.guildId, this.props.log.user.id);
if (member && member.colorString) {
if (member.colorString && brc.settings.auditLog.username) hooks[0].children[0].style.color = member.colorString;
if (member.colorString && brc.settings.auditLog.discriminator) { hooks[0].querySelector(DiscordSelectors.AuditLog.discrim).style.color = member.colorString;hooks[0].querySelector(DiscordSelectors.AuditLog.discrim).style.opacity = 1;}
}
if (hooks.length < 2 || this.props.log.targetType != "USER") return;
const member2 = GuildMemberStore.getMember(this._reactInternalFiber.return.memoizedProps.guildId, this.props.log.target.id);
if (!member2 || !member2.colorString) return;
if (brc.settings.auditLog.username) hooks[1].children[0].style.color = member2.colorString;
if (brc.settings.auditLog.discriminator) { hooks[1].querySelector(DiscordSelectors.AuditLog.discrim).style.color = member2.colorString;hooks[1].querySelector(DiscordSelectors.AuditLog.discrim).style.opacity = 1;}
};
Patcher.after(AuditLogItem.prototype, "componentDidMount", (thisObject) => {
const bound = auditlogMount.bind(thisObject); bound();
});
}
getMemberGroup() {
return new Promise(resolve => {
const memberList = document.querySelector(DiscordSelectors.MemberList.membersWrap);
if (memberList) {resolve(ReactTools.getOwnerInstance(memberList, {include: ["ChannelMembers"]}).constructor);}
else {
const channel = WebpackModules.find(m => m.prototype && m.prototype.renderEmptyChannel);
const unpatch = Patcher.before(channel.prototype, "componentDidUpdate", (t) => {
const elem = DiscordModules.ReactDOM.findDOMNode(t);
if (!elem) return;
const memberList = elem.querySelector(DiscordSelectors.MemberList.membersWrap);
if (!memberList) return;
unpatch();
resolve(ReactTools.getOwnerInstance(memberList, {include: ["ChannelMembers"]}).constructor);
});
}
});
}
forceUpdateMemberList() {
const memberList = document.querySelector(DiscordSelectors.MemberList.membersWrap);
if (memberList) ReactTools.getOwnerInstance(memberList, {include: ["ChannelMembers"]}).forceUpdate();
}
async patchMemberList() {
const MemberList = await this.getMemberGroup();
Patcher.after(MemberList.prototype, "render", (memberList) => {
if (memberList.renderSection.__patched) return;
Patcher.after(memberList, "renderSection", (_, __, section) => {
if (!this.settings.modules.memberList) return;
const guild = DiscordModules.GuildStore.getGuild(memberList.props.channel.guild_id);
if (!guild) return;
const roleColor = guild.roles[section.props.id] ? guild.roles[section.props.id].colorString : "";
if (!roleColor) return;
const originalType = section.type;
section.type = function() {
const label = originalType(...arguments);
label.props.style = {color: roleColor};
return label;
};
return section;
});
memberList.renderSection.__patched = true;
});
this.forceUpdateMemberList();
}
};
};
return plugin(Plugin, Api);
})(global.ZeresPluginLibrary.buildPlugin(config));
})();

@ -1,6 +0,0 @@
{
"currentVersionInfo": {
"version": "0.0.3",
"hasShownChangelog": true
}
}

@ -1,47 +0,0 @@
//META{"name":"DoNotTrack","displayName":"DoNotTrack","website":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/DoNotTrack","source":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/DoNotTrack/DoNotTrack.plugin.js"}*//
var DoNotTrack = (() => {
const config = {"info":{"name":"DoNotTrack","authors":[{"name":"Zerebos","discord_id":"249746236008169473","github_username":"rauenzi","twitter_username":"ZackRauen"}],"version":"0.0.3","description":"Stops Discord from tracking everything you do like Sentry and Analytics. Support Server: bit.ly/ZeresServer","github":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/DoNotTrack","github_raw":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/DoNotTrack/DoNotTrack.plugin.js"},"changelog":[{"title":"What's New?","items":["Use only local lib loading."]}],"main":"index.js"};
return !global.ZeresPluginLibrary ? class {
getName() {return config.info.name;}
getAuthor() {return config.info.authors.map(a => a.name).join(", ");}
getDescription() {return config.info.description;}
getVersion() {return config.info.version;}
load() {window.BdApi.alert("Library Missing",`The library plugin needed for ${config.info.name} is missing.<br /><br /> <a href="https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js" target="_blank">Click here to download the library!</a>`);}
start() {}
stop() {}
} : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const {Patcher, WebpackModules} = Api;
return class DoNotTrack extends Plugin {
onStart() {
const Analytics = WebpackModules.getByProps("AnalyticEventConfigs");
Patcher.instead(Analytics.default, "track", () => {});
const Warning = WebpackModules.getByProps("consoleWarning");
Patcher.instead(Warning, "consoleWarning", () => {});
const MethodWrapper = WebpackModules.getByProps("wrapMethod");
Patcher.instead(MethodWrapper, "wrapMethod", () => {});
const Sentry = WebpackModules.getByProps("_originalConsoleMethods", "_wrappedBuiltIns");
Sentry.uninstall();
Patcher.instead(Sentry, "_breadcrumbEventHandler", () => () => {});
Patcher.instead(Sentry, "captureBreadcrumb", () => {});
Patcher.instead(Sentry, "_makeRequest", () => {});
Patcher.instead(Sentry, "_sendProcessedPayload", () => {});
Patcher.instead(Sentry, "_send", () => {});
Object.assign(window.console, Sentry._originalConsoleMethods);
}
onStop() {
Patcher.unpatchAll();
}
};
};
return plugin(Plugin, Api);
})(global.ZeresPluginLibrary.buildPlugin(config));
})();

@ -1,6 +0,0 @@
{
"currentVersionInfo": {
"version": "1.0.8",
"hasShownChangelog": true
}
}

@ -1,95 +0,0 @@
//META { "name": "HighlightSelf", "website": "https://inve1951.github.io/BetterDiscordStuff/" } *//
var HighlightSelf;
HighlightSelf = function () {
var MessageComponents, UserStore, cancel, css, getOwnerInstance, install;
class HighlightSelf {
getName() {
return "Highlight Self";
}
getDescription() {
return "Highlights your own username in message headers.";
}
getAuthor() {
return "square";
}
getVersion() {
return "1.1.0";
}
load() {
return window.SuperSecretSquareStuff != null ? window.SuperSecretSquareStuff : window.SuperSecretSquareStuff = new Promise(function (c, r) {
return require("request").get("https://raw.githubusercontent.com/Inve1951/BetterDiscordStuff/master/plugins/0circle.plugin.js", function (err, res, body) {
if (err || 200 !== (res != null ? res.statusCode : void 0)) {
return r(err != null ? err : res);
}
Object.defineProperties(window.SuperSecretSquareStuff, {
libLoaded: {
value: c
},
code: {
value: body
}
});
return (0, eval)(body);
});
});
}
async start() {
({ getOwnerInstance } = await SuperSecretSquareStuff);
if (!install()) {
this.onSwitch = install;
}
return BdApi.injectCSS("css_highlightSelf", css);
}
stop() {
if (cancel) {
cancel();
cancel = null;
}
return BdApi.clearCSS("css_highlightSelf");
}
};
MessageComponents = UserStore = cancel = getOwnerInstance = null;
install = function () {
var i, len, n, ref;
MessageComponents || (MessageComponents = BDV2.WebpackModules.find(function (m) {
return m.MessageUsername;
}));
UserStore || (UserStore = BDV2.WebpackModules.findByUniqueProperties(["getCurrentUser"]));
if (!(MessageComponents && UserStore)) {
return false;
}
delete this.onSwitch;
cancel = Utils.monkeyPatch(MessageComponents.MessageUsername.prototype, "render", {
after: function ({ returnValue, thisObject }) {
var props, ref;
({ props } = returnValue.props.children);
if (UserStore.getCurrentUser() === thisObject.props.message.author && !((ref = props.className) != null ? ref.endsWith(" highlight-self") : void 0)) {
return props.className = props.className ? props.className + " highlight-self" : "highlight-self";
}
}
});
try {
ref = document.querySelectorAll(".message-1PNnaP h2 > span");
for (i = 0, len = ref.length; i < len; i++) {
n = ref[i];
getOwnerInstance(n).forceUpdate();
}
} catch (error) {}
return true;
};
css = ".highlight-self .username-_4ZSMR {\n text-decoration: underline;\n}";
return HighlightSelf;
}.call(this);

@ -1,6 +0,0 @@
{
"currentVersionInfo": {
"version": "0.1.3",
"hasShownChangelog": true
}
}

@ -1,589 +0,0 @@
//META{"name":"PermissionsViewer","displayName":"PermissionsViewer","website":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/PermissionsViewer","source":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/PermissionsViewer/PermissionsViewer.plugin.js"}*//
var PermissionsViewer = (() => {
const config = {"info":{"name":"PermissionsViewer","authors":[{"name":"Zerebos","discord_id":"249746236008169473","github_username":"rauenzi","twitter_username":"ZackRauen"}],"version":"0.1.3","description":"Allows you to view a user's permissions. Thanks to Noodlebox for the idea! Support Server: bit.ly/ZeresServer","github":"https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/PermissionsViewer","github_raw":"https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/PermissionsViewer/PermissionsViewer.plugin.js"},"changelog":[{"title":"Bug Fixes","type":"fixes","items":["Permissions button showing in DMs","Owner pseudo-role having no permissions"]}],"defaultConfig":[{"type":"switch","id":"contextMenus","name":"Context Menus","note":"Toggles colorizing of typing notifications.","value":true},{"type":"switch","id":"popouts","name":"Popouts","note":"Toggles colorizing of typing notifications.","value":true}],"strings":{"es":{"contextMenuLabel":"Permisos","popoutLabel":"Permisos","modal":{"header":"Permisos de ${name}","rolesLabel":"Roles","permissionsLabel":"Permisos","owner":"@propietario"},"settings":{"popouts":{"name":"Mostrar en Popouts","note":"Mostrar los permisos de usuario en popouts como los roles."},"contextMenus":{"name":"Botón de menú contextual","note":"Añadir un botón para ver permisos en los menús contextuales."}}},"pt":{"contextMenuLabel":"Permissões","popoutLabel":"Permissões","modal":{"header":"Permissões de ${name}","rolesLabel":"Cargos","permissionsLabel":"Permissões","owner":"@dono"},"settings":{"popouts":{"name":"Mostrar em Popouts","note":"Mostrar as permissões em popouts como os cargos."},"contextMenus":{"name":"Botão do menu de contexto","note":"Adicionar um botão parar ver permissões ao menu de contexto."}}},"de":{"contextMenuLabel":"Berechtigungen","popoutLabel":"Berechtigungen","modal":{"header":"${name}s Berechtigungen","rolesLabel":"Rollen","permissionsLabel":"Berechtigungen","owner":"@eigentümer"},"settings":{"popouts":{"name":"In Popouts anzeigen","note":"Zeigt die Gesamtberechtigungen eines Benutzers in seinem Popup ähnlich den Rollen an."},"contextMenus":{"name":"Kontextmenü-Schaltfläche","note":"Fügt eine Schaltfläche hinzu, um die Berechtigungen mithilfe von Kontextmenüs anzuzeigen."}}},"en":{"contextMenuLabel":"Permissions","popoutLabel":"Permissions","modal":{"header":"${name}'s Permissions","rolesLabel":"Roles","permissionsLabel":"Permissions","owner":"@owner"},"settings":{"popouts":{"name":"Show In Popouts","note":"Shows a user's total permissions in their popout similar to roles."},"contextMenus":{"name":"Context Menu Button","note":"Adds a button to view the permissions modal to select context menus."}}}},"main":"index.js"};
return !global.ZeresPluginLibrary ? class {
getName() {return config.info.name;}
getAuthor() {return config.info.authors.map(a => a.name).join(", ");}
getDescription() {return config.info.description;}
getVersion() {return config.info.version;}
load() {window.BdApi.alert("Library Missing",`The library plugin needed for ${config.info.name} is missing.<br /><br /> <a href="https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js" target="_blank">Click here to download the library!</a>`);}
start() {}
stop() {}
} : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const {Patcher, DiscordModules, PluginUtilities, Toasts, DiscordClasses, DiscordSelectors, Utilities, DOMTools, ReactTools, ContextMenu, ColorConverter} = Api;
const GuildStore = DiscordModules.GuildStore;
const SelectedGuildStore = DiscordModules.SelectedGuildStore;
const MemberStore = DiscordModules.GuildMemberStore;
const UserStore = DiscordModules.UserStore;
const DiscordPerms = Object.assign({}, DiscordModules.DiscordConstants.Permissions);
if (DiscordPerms.SEND_TSS_MESSAGES) {
DiscordPerms.SEND_TTS_MESSAGES = DiscordPerms.SEND_TSS_MESSAGES;
delete DiscordPerms.SEND_TSS_MESSAGES;
}
if (DiscordPerms.MANAGE_GUILD) {
DiscordPerms.MANAGE_SERVER = DiscordPerms.MANAGE_GUILD;
delete DiscordPerms.MANAGE_GUILD;
}
return class PermissionsViewer extends Plugin {
constructor() {
super();
this.css = `.member-perms-header {
display: flex;
justify-content: space-between;
}
.member-perms {
display: flex;
flex-wrap: wrap;
margin-top: 2px;
max-height: 160px;
overflow-y: auto;
}
.member-perms .member-perm .perm-circle {
border-radius: 50%;
height: 12px;
margin-right: 4px;
width: 12px;
}
.member-perms .member-perm .name {
margin-right: 4px;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.perm-details-button {
cursor: pointer;
height: 12px;
}
.perm-details {
display: flex;
justify-content: flex-end;
}
.member-perm-details {
cursor: pointer;
}
.member-perm-details-button {
fill: #72767d;
height: 10px;
}
/* Modal */
@keyframes permissions-backdrop {
to { opacity: 0.85; }
}
@keyframes permissions-modal-wrapper {
to { transform: scale(1); opacity: 1; }
}
@keyframes permissions-backdrop-closing {
to { opacity: 0; }
}
@keyframes permissions-modal-wrapper-closing {
to { transform: scale(0.7); opacity: 0; }
}
#permissions-modal-wrapper .callout-backdrop {
animation: permissions-backdrop 250ms ease;
animation-fill-mode: forwards;
opacity: 0;
background-color: rgb(0, 0, 0);
transform: translateZ(0px);
}
#permissions-modal-wrapper.closing .callout-backdrop {
animation: permissions-backdrop-closing 200ms linear;
animation-fill-mode: forwards;
animation-delay: 50ms;
opacity: 0.85;
}
#permissions-modal-wrapper.closing .modal-wrapper {
animation: permissions-modal-wrapper-closing 250ms cubic-bezier(0.19, 1, 0.22, 1);
animation-fill-mode: forwards;
opacity: 1;
transform: scale(1);
}
#permissions-modal-wrapper .modal-wrapper {
animation: permissions-modal-wrapper 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
animation-fill-mode: forwards;
transform: scale(0.7);
transform-origin: 50% 50%;
display: flex;
align-items: center;
box-sizing: border-box;
contain: content;
justify-content: center;
top: 0;
left: 0;
bottom: 0;
right: 0;
opacity: 0;
pointer-events: none;
position: absolute;
user-select: none;
z-index: 1000;
}
#permissions-modal-wrapper .modal-body {
background-color: #36393f;
height: 440px;
width: auto;
/*box-shadow: 0 0 0 1px rgba(32,34,37,.6), 0 2px 10px 0 rgba(0,0,0,.2);*/
flex-direction: row;
overflow: hidden;
display: flex;
flex: 1;
contain: layout;
position: relative;
}
#permissions-modal-wrapper #permissions-modal {
display: flex;
contain: layout;
flex-direction: column;
pointer-events: auto;
border: 1px solid rgba(28,36,43,.6);
border-radius: 5px;
box-shadow: 0 2px 10px 0 rgba(0,0,0,.2);
overflow: hidden;
}
#permissions-modal-wrapper .header {
background-color: #35393e;
box-shadow: 0 2px 3px 0 rgba(0,0,0,.2);
padding: 12px 20px;
z-index: 1;
color: #fff;
font-size: 16px;
font-weight: 700;
line-height: 19px;
}
.role-side, .perm-side {
flex-direction: column;
padding-left: 6px;
}
.role-scroller, .perm-scroller {
contain: layout;
flex: 1;
min-height: 1px;
overflow-y: scroll;
}
#permissions-modal-wrapper .scroller-title {
color: #fff;
padding: 8px 0 4px 4px;
margin-right: 8px;
border-bottom: 1px solid rgba(0,0,0,0.3);
display: none;
}
#permissions-modal-wrapper .role-side {
width: auto;
min-width: 150px;
background: #2f3136;
flex: 0 0 auto;
overflow: hidden;
display: flex;
height: 100%;
min-height: 1px;
position: relative;
}
#permissions-modal-wrapper .role-scroller {
contain: layout;
flex: 1;
min-height: 1px;
overflow-y: scroll;
padding-top: 8px;
}
#permissions-modal-wrapper .role-item {
display: flex;
border-radius: 2px;
padding: 6px;
margin-bottom: 5px;
cursor: pointer;
color: #dcddde;
}
#permissions-modal-wrapper .role-item:hover {
background-color: rgba(0,0,0,0.1);
}
#permissions-modal-wrapper .role-item.selected {
background-color: rgba(0,0,0,0.2);
}
#permissions-modal-wrapper .perm-side {
width: 250px;
background-color: #36393f;
flex: 0 0 auto;
display: flex;
height: 100%;
min-height: 1px;
position: relative;
padding-left: 10px;
}
#permissions-modal-wrapper .perm-item {
box-shadow: inset 0 -1px 0 rgba(79,84,92,.3);
box-sizing: border-box;
height: 44px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-direction: row;
justify-content: flex-start;
align-items: center;
display: flex;
}
#permissions-modal-wrapper .perm-item.allowed svg {
fill: #43B581;
}
#permissions-modal-wrapper .perm-item.denied svg {
fill: #F04747;
}
#permissions-modal-wrapper .perm-name {
display: inline;
flex: 1;
font-size: 16px;
font-weight: 400;
overflow: hidden;
text-overflow: ellipsis;
user-select: text;
color: #dcddde;
margin-left: 10px;
}
.member-perms::-webkit-scrollbar-thumb, .member-perms::-webkit-scrollbar-track,
#permissions-modal-wrapper *::-webkit-scrollbar-thumb, #permissions-modal-wrapper *::-webkit-scrollbar-track {
background-clip: padding-box;
border-radius: 7.5px;
border-style: solid;
border-width: 3px;
visibility: hidden;
}
.member-perms:hover::-webkit-scrollbar-thumb, .member-perms:hover::-webkit-scrollbar-track,
#permissions-modal-wrapper *:hover::-webkit-scrollbar-thumb, #permissions-modal-wrapper *:hover::-webkit-scrollbar-track {
visibility: visible;
}
.member-perms::-webkit-scrollbar-track,
#permissions-modal-wrapper *::-webkit-scrollbar-track {
border-width: initial;
background-color: transparent;
border: 2px solid transparent;
}
.member-perms::-webkit-scrollbar-thumb,
#permissions-modal-wrapper *::-webkit-scrollbar-thumb {
border: 2px solid transparent;
border-radius: 4px;
cursor: move;
background-color: rgba(32,34,37,.6);
}
.member-perms::-webkit-scrollbar,
#permissions-modal-wrapper *::-webkit-scrollbar {
height: 8px;
width: 8px;
}`;
this.listHTML = `<div id="permissions-popout">
<div class="member-perms-header \${bodyTitle}">
<div class="member-perms-title">\${label}</div>
<span class="perm-details">
<svg name="Details" viewBox="0 0 24 24" class="perm-details-button" fill="currentColor">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
</svg>
</span>
</div>
<ul class="member-perms \${root} \${rolesList} \${endBodySection}"></ul>
</div>`;
this.itemHTML = `<li class="member-perm \${role}">
<div class="perm-circle \${roleCircle}"></div>
<div class="name \${roleName}"></div>
</li>`;
this.modalHTML = `<div id="permissions-modal-wrapper">
<div class="callout-backdrop \${backdrop}"></div>
<div class="modal-wrapper \${modal}">
<div id="permissions-modal" class="\${inner}">
<div class="header"><div class="title">\${header}</div></div>
<div class="modal-body">
<div class="role-side">
<span class="scroller-title role-list-title">\${rolesLabel}</span>
<div class="role-scroller">
</div>
</div>
<div class="perm-side">
<span class="scroller-title perm-list-title">\${permissionsLabel}</span>
<div class="perm-scroller">
</div>
</div>
</div>
</div>
</div>
</div>`;
this.modalItem = `<div class="perm-item"><span class="perm-name"></span></div>`;
this.modalButton = `<div class="role-item"><span class="role-name"></span></div>`;
this.modalButtonUser = `<div class="role-item"><div class="wrapper-2F3Zv8 xsmall-3afG_L"><div class="image-33JSyf xsmall-3afG_L" style="background-image: url('\${avatarUrl}');"></div></div><span class="role-name marginLeft8-1YseBe"></span></div>`;
this.permAllowedIcon = `<svg height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>`;
this.permDeniedIcon = `<svg height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31C15.55 19.37 13.85 20 12 20zm6.31-3.1L7.1 5.69C8.45 4.63 10.15 4 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z"/></svg>`;
this.contextObserver = new MutationObserver((changes) => {
for (let change in changes) this.observeContextMenus(changes[change]);
});
this.cancelUserPopout = () => {};
}
onStart() {
PluginUtilities.addStyle(this.getName(), this.css);
this.listHTML = Utilities.formatTString(this.listHTML, DiscordClasses.UserPopout);
this.listHTML = Utilities.formatTString(this.listHTML, DiscordClasses.PopoutRoles);
this.itemHTML = Utilities.formatTString(this.itemHTML, DiscordClasses.PopoutRoles);
this.modalHTML = Utilities.formatTString(this.modalHTML, DiscordClasses.Backdrop);
this.modalHTML = Utilities.formatTString(this.modalHTML, DiscordClasses.Modals);
if (this.settings.popouts) this.bindPopouts();
if (this.settings.contextMenus) this.bindContextMenus();
}
onStop() {
PluginUtilities.removeStyle(this.getName());
this.unbindPopouts();
this.unbindContextMenus();
}
bindPopouts() {
let pViewer = this;
let UserPopout = DiscordModules.UserPopout;
let popoutMount = function() {
const user = this.state.guildMember;
const guild = this.state.guild;
const name = this.state.nickname ? this.state.nickname : this.props.user.username;
if (!user || !guild || !name) return;
const userRoles = user.roles.slice(0);
userRoles.push(guild.id);
userRoles.reverse();
let perms = 0;
const permBlock = DOMTools.createElement(Utilities.formatTString(pViewer.listHTML, {label: pViewer.strings.popoutLabel}));
const memberPerms = permBlock.find(".member-perms");
const strings = DiscordModules.Strings;
for (let r = 0; r < userRoles.length; r++) {
const role = userRoles[r];
perms = perms | guild.roles[role].permissions;
for (let perm in DiscordPerms) {
var permName = strings[perm];
const hasPerm = (perms & DiscordPerms[perm]) == DiscordPerms[perm];
if (hasPerm && !memberPerms.find(`[data-name="${permName}"]`)) {
const element = DOMTools.createElement(pViewer.itemHTML);
let roleColor = guild.roles[role].colorString;
element.find(".name").textContent = permName;
element.setAttribute("data-name", permName);
if (!roleColor) roleColor = "#B9BBBE";
element.find(".perm-circle").css("background-color", ColorConverter.rgbToAlpha(roleColor, 1));
element.css("border-color", ColorConverter.rgbToAlpha(roleColor, 0.6));
memberPerms.prepend(element);
}
}
}
const popout = DiscordModules.ReactDOM.findDOMNode(this);
permBlock.find(".perm-details").on("click", () => {
pViewer.showModal(pViewer.createModalUser(name, user, guild));
});
permBlock.insertAfter(popout.querySelector(DiscordSelectors.UserPopout.rolesList));
};
this.cancelUserPopout = Patcher.after(UserPopout.prototype, "componentDidMount", (thisObject) => {
let bound = popoutMount.bind(thisObject); bound();
});
}
unbindPopouts() {
this.cancelUserPopout();
}
bindContextMenus() {
this.contextObserver.observe(document.querySelector("#app-mount"), {childList: true, subtree: true});
}
unbindContextMenus() {
this.contextObserver.disconnect();
}
observeContextMenus(e) {
if (!e.addedNodes.length || !(e.addedNodes[0] instanceof Element) || !e.addedNodes[0].classList) return;
const elem = e.addedNodes[0];
const isContextMenu = elem.matches(DiscordSelectors.ContextMenu.contextMenu);
if (!isContextMenu) return;
const contextMenu = elem;
const memberContext = ReactTools.getReactProperty(contextMenu, "return.return.return.return.memoizedProps.user");
const messageUser = ReactTools.getReactProperty(contextMenu, "return.return.return.return.memoizedProps.guildId");
let menuItem = null;
if (memberContext || messageUser) menuItem = this.userContextMenu(contextMenu, memberContext.id);
let isGuildContext = ReactTools.getReactProperty(contextMenu, "return.memoizedProps.type") == "GUILD_ICON_BAR";