This commit is contained in:
poslop
2023-03-24 21:55:03 -05:00
parent adfa36a4fd
commit a21e33aeb6
12 changed files with 0 additions and 14149 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
{
"currentVersionInfo": {
"version": "2.3.11",
"hasShownChangelog": true
},
"settings": {
"toolbar": {
"bold": true,
"italic": true,
"underline": true,
"strikethrough": true,
"spoiler": 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
}
},
"buttonOrder": [
"bold",
"italic",
"underline",
"strikethrough",
"spoiler",
"codeblock",
"code",
"superscript",
"smallcaps",
"fullwidth",
"upsidedown",
"varied",
"leet",
"thicc"
]
}

View File

@@ -1,15 +0,0 @@
{
"currentVersionInfo": {
"version": "1.0.2",
"hasShownChangelog": true
},
"blurred": [],
"sen": [],
"seen": [
"1004559719433764898",
"1006296543915155536",
"1006208838434828350",
"751477930021879808",
"732807937457782895"
]
}

View File

@@ -1,276 +0,0 @@
/**
* @name BlurNSFW
* @description Blurs images and videos until you hover over them.
* @version 1.0.2
* @author Zerebos
* @authorId 249746236008169473
* @website https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/BlurNSFW
* @source https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/BlurNSFW/BlurNSFW.plugin.js
*/
/*@cc_on
@if (@_jscript)
// Offer to self-install for clueless users that try to run this directly.
var shell = WScript.CreateObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\\BetterDiscord\\plugins");
var pathSelf = WScript.ScriptFullName;
// Put the user at ease by addressing them in the first person
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);
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
} else if (!fs.FolderExists(pathPlugins)) {
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
// Show the user where to put plugins in the future
shell.Exec("explorer " + pathPlugins);
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
}
WScript.Quit();
@else@*/
const config = {
info: {
name: "BlurNSFW",
authors: [
{
name: "Zerebos",
discord_id: "249746236008169473",
github_username: "rauenzi",
twitter_username: "ZackRauen"
}
],
version: "1.0.2",
description: "Blurs images and videos until you hover over them.",
github: "https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/BlurNSFW",
github_raw: "https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/BlurNSFW/BlurNSFW.plugin.js"
},
changelog: [
{
title: "What's New?",
type: "fixed",
items: [
"Can join voice channels without causing loading issues!"
]
}
],
defaultConfig: [
{
type: "switch",
id: "blurNSFW",
name: "Blur NSFW Channels",
note: "This setting automatically blurs media in channels marked NSFW.",
value: true
},
{
type: "slider",
id: "blurSize",
name: "Blur Size",
note: "The size (in px) of the blurred pixels.",
value: 10,
min: 0,
max: 50,
units: "px"
},
{
type: "slider",
id: "blurTime",
name: "Blur Time",
note: "The time (in ms) it takes for the blur to disappear and reappear.",
value: 200,
min: 0,
max: 5000,
units: "ms"
},
{
type: "switch",
id: "blurOnFocus",
name: "Blur When Focused",
note: "This setting keeps the blur when clicking on/expanding an image.",
value: true
}
],
main: "index.js"
};
class Dummy {
constructor() {this._config = config;}
start() {}
stop() {}
}
if (!global.ZeresPluginLibrary) {
BdApi.showConfirmationModal("Library Missing", `The library plugin needed for ${config.name ?? config.info.name} is missing. Please click Download Now to install it.`, {
confirmText: "Download Now",
cancelText: "Cancel",
onConfirm: () => {
require("request").get("https://betterdiscord.app/gh-redirect?id=9", async (err, resp, body) => {
if (err) return require("electron").shell.openExternal("https://betterdiscord.app/Download?id=9");
if (resp.statusCode === 302) {
require("request").get(resp.headers.location, async (error, response, content) => {
if (error) return require("electron").shell.openExternal("https://betterdiscord.app/Download?id=9");
await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), content, r));
});
}
else {
await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r));
}
});
}
});
}
module.exports = !global.ZeresPluginLibrary ? Dummy : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const {ContextMenu, DOM, Webpack, Patcher} = window.BdApi;
const SelectedChannelStore = Webpack.getModule(m => m.getCurrentlySelectedChannelId);
const ChannelStore = Webpack.getModule(m => m.getDMFromUserId);
const InlineMediaWrapper = Webpack.getModule(m => m.toString().includes("renderAccessory"));
const WrapperClasses = Webpack.getModule(m => m.wrapperPlaying);
const Events = require("events");
const Dispatcher = new Events();
const formatString = (string, values) => {
for (const val in values) {
let replacement = values[val];
if (Array.isArray(replacement)) replacement = JSON.stringify(replacement);
if (typeof(replacement) === "object" && replacement !== null) replacement = replacement.toString();
string = string.replace(new RegExp(`{{${val}}}`, "g"), replacement);
}
return string;
};
/* globals BdApi:false */
return class BlurMedia extends Plugin {
constructor(meta) {
super();
this.meta = meta;
this.styleTemplate = `
{{blurOnFocus}}
.${WrapperClasses.wrapperPlaying.split(" ").join(".")} video,
.${WrapperClasses.wrapperControlsHidden.split(" ").join(".")} video,
.blur:hover img,
.blur:hover video,
a:hover + div > .blur {
transition: {{time}}ms cubic-bezier(.2, .11, 0, 1) !important;
filter: blur(0px) !important;
}
.blur img,
.blur video {
filter: blur({{size}}px) !important;
transition: {{time}}ms cubic-bezier(.2, .11, 0, 1) !important;
}`;
this.channelChange = this.channelChange.bind(this);
}
onStart() {
/** @type {Set<string>} */
this.blurredChannels = new Set(BdApi.loadData(this.meta.name, "blurred") ?? []);
/** @type {Set<string>} */
this.seenChannels = new Set(BdApi.loadData(this.meta.name, "seen") ?? []);
Patcher.after(this.meta.name, InlineMediaWrapper.prototype, "render", (thisObject, _, retVal) => {
const channel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());
if (!this.hasBlur(channel)) return;
if (retVal.props.className) retVal.props.className = retVal.props.className + " blur";
else retVal.props.className = "blur";
});
Patcher.after(this.meta.name, InlineMediaWrapper.prototype, "componentDidMount", (thisObject) => {
if (thisObject.cancelBlurListener) return;
const listener = () => thisObject.forceUpdate();
Dispatcher.on("blur", listener);
thisObject.cancelBlurListener = () => Dispatcher.off("blur", listener);
});
Patcher.after(this.meta.name, InlineMediaWrapper.prototype, "componentWillUnmount", (thisObject) => {
if (!thisObject.cancelBlurListener) return;
thisObject.cancelBlurListener();
delete thisObject.cancelBlurListener;
});
this.addStyle();
SelectedChannelStore.addChangeListener(this.channelChange);
this.promises = {state: {cancelled: false}, cancel() {this.state.cancelled = true;}};
this.patchChannelContextMenu();
}
onStop() {
BdApi.saveData(this.meta.name, "blurred", this.blurredChannels);
BdApi.saveData(this.meta.name, "seen", this.seenChannels);
this.contextMenuPatch?.();
this.removeStyle();
SelectedChannelStore.removeChangeListener(this.channelChange);
}
hasBlur(channel) {
return this.blurredChannels.has(channel.id);
}
addBlur(channel) {
this.blurredChannels.add(channel.id);
Dispatcher.emit("blur");
}
removeBlur(channel) {
this.blurredChannels.delete(channel.id);
Dispatcher.emit("blur");
}
channelChange() {
const channel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());
if (this.seenChannels.has(channel.id)) return;
this.seenChannels.add(channel.id);
if (this.settings.blurNSFW && channel.nsfw) this.addBlur(channel);
}
patchChannelContextMenu() {
this.contextMenuPatch = ContextMenu.patch("channel-context", (retVal, props) => {
const newItem = ContextMenu.buildItem({
type: "toggle",
label: "Blur Media",
active: this.hasBlur(props.channel),
action: () => {
if (this.hasBlur(props.channel)) this.removeBlur(props.channel);
else this.addBlur(props.channel);
}
});
retVal.props.children.splice(1, 0, newItem);
});
}
addStyle() {
const styleString = formatString(this.styleTemplate, {
size: Math.round(this.settings.blurSize),
time: Math.round(this.settings.blurTime),
blurOnFocus: this.settings.blurOnFocus ? "" : ".layer-1Ixpg3 .blur img,"
});
DOM.addStyle(this.meta.name, styleString);
}
removeStyle() {
DOM.removeStyle(this.meta.name);
}
getSettingsPanel() {
const panel = this.buildSettingsPanel();
panel.addListener(() => {
this.removeStyle();
this.addStyle();
});
return panel.getElement();
}
};
};
return plugin(Plugin, Api);
})(global.ZeresPluginLibrary.buildPlugin(config));
/*@end@*/

View File

@@ -1,14 +0,0 @@
{
"all": {
"dates": {
"creationDate": {}
},
"general": {
"displayText": true
},
"places": {
"userPopout": true,
"userProfile": true
}
}
}

View File

@@ -1,208 +0,0 @@
/**
* @name FreeEmojis
* @author An0
* @version 1.6
* @description Link emojis if you don't have nitro! Type them out or use the emoji picker! [64px]
* @source https://github.com/An00nymushun/DiscordFreeEmojis
* @updateUrl https://raw.githubusercontent.com/An00nymushun/DiscordFreeEmojis/master/DiscordFreeEmojis64px.plugin.js
*/
/*@cc_on
@if (@_jscript)
var shell = WScript.CreateObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\\BetterDiscord\\plugins");
var pathSelf = WScript.ScriptFullName;
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);
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
} else if (!fs.FolderExists(pathPlugins)) {
shell.Popup("I can't find the BetterDiscord plugins folder.\\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
// Show the user where to put plugins in the future
shell.Exec("explorer " + pathPlugins);
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
}
WScript.Quit();
@else @*/
var FreeEmojis = (() => {
'use strict';
const BaseColor = "#0cf";
var Discord;
var Utils = {
Log: (message) => { console.log(`%c[FreeEmojis] %c${message}`, `color:${BaseColor};font-weight:bold`, "") },
Warn: (message) => { console.warn(`%c[FreeEmojis] %c${message}`, `color:${BaseColor};font-weight:bold`, "") },
Error: (message) => { console.error(`%c[FreeEmojis] %c${message}`, `color:${BaseColor};font-weight:bold`, "") },
Webpack: () => {
let webpackExports;
if(typeof BdApi !== "undefined" && BdApi?.findModuleByProps && BdApi?.findModule) {
return { findModule: BdApi.findModule, findModuleByUniqueProperties: (props) => BdApi.findModuleByProps.apply(null, props) };
}
else if(Discord.window.webpackChunkdiscord_app != null) {
Discord.window.webpackChunkdiscord_app.push([
['__extra_id__'],
{},
req => webpackExports = req
]);
}
else if(Discord.window.webpackJsonp != null) {
webpackExports = typeof(Discord.window.webpackJsonp) === 'function' ?
Discord.window.webpackJsonp(
[],
{ '__extra_id__': (module, _export_, req) => { _export_.default = req } },
[ '__extra_id__' ]
).default :
Discord.window.webpackJsonp.push([
[],
{ '__extra_id__': (_module_, exports, req) => { _module_.exports = req } },
[ [ '__extra_id__' ] ]
]);
}
else return null;
delete webpackExports.m['__extra_id__'];
delete webpackExports.c['__extra_id__'];
const findModule = (filter) => {
for(let i in webpackExports.c) {
if(webpackExports.c.hasOwnProperty(i)) {
let m = webpackExports.c[i].exports;
if(!m) continue;
if(m.__esModule && m.default) m = m.default;
if(filter(m)) return m;
}
}
return null;
};
const findModuleByUniqueProperties = (propNames) => findModule(module => propNames.every(prop => module[prop] !== undefined));
return { findModule, findModuleByUniqueProperties };
}
};
var Initialized = false;
var searchHook;
var parseHook;
var useEmojiSelectHandlerHook;
function Init()
{
Discord = { window: (typeof(unsafeWindow) !== 'undefined') ? unsafeWindow : window };
const webpackUtil = Utils.Webpack();
if(webpackUtil == null) { Utils.Error("Webpack not found."); return 0; }
const { findModule, findModuleByUniqueProperties } = webpackUtil;
let emojisModule = findModuleByUniqueProperties([ 'getDisambiguatedEmojiContext', 'searchWithoutFetchingLatest' ]);
if(emojisModule == null) { Utils.Error("emojisModule not found."); return 0; }
let messageEmojiParserModule = findModuleByUniqueProperties([ 'parse', 'parsePreprocessor', 'unparse' ]);
if(messageEmojiParserModule == null) { Utils.Error("messageEmojiParserModule not found."); return 0; }
let emojiPickerModule = findModuleByUniqueProperties([ 'useEmojiSelectHandler' ]);
if(emojiPickerModule == null) { Utils.Error("emojiPickerModule not found."); return 0; }
searchHook = Discord.original_searchWithoutFetchingLatest = emojisModule.searchWithoutFetchingLatest;
emojisModule.searchWithoutFetchingLatest = function() { return searchHook.apply(this, arguments); };
parseHook = Discord.original_parse = messageEmojiParserModule.parse;
messageEmojiParserModule.parse = function() { return parseHook.apply(this, arguments); };
useEmojiSelectHandlerHook = Discord.original_useEmojiSelectHandler = emojiPickerModule.useEmojiSelectHandler;
emojiPickerModule.useEmojiSelectHandler = function() { return useEmojiSelectHandlerHook.apply(this, arguments); };
Utils.Log("initialized");
Initialized = true;
return 1;
}
function Start() {
if(!Initialized && Init() !== 1) return;
const { original_parse, original_useEmojiSelectHandler } = Discord;
searchHook = function() {
let result = Discord.original_searchWithoutFetchingLatest.apply(this, arguments);
result.unlocked.push(...result.locked);
result.locked = [];
return result;
}
function replaceEmoji(parseResult, emoji) {
parseResult.content = parseResult.content.replace(`<${emoji.animated ? "a" : ""}:${emoji.originalName || emoji.name}:${emoji.id}>`, emoji.url.split("?")[0] + "?size=64");
}
parseHook = function() {
let result = original_parse.apply(this, arguments);
if(result.invalidEmojis.length !== 0) {
for(let emoji of result.invalidEmojis) {
replaceEmoji(result, emoji);
}
result.invalidEmojis = [];
}
let validNonShortcutEmojis = result.validNonShortcutEmojis;
for (let i = 0; i < validNonShortcutEmojis.length; i++) {
const emoji = validNonShortcutEmojis[i];
if(!emoji.available) {
replaceEmoji(result, emoji);
validNonShortcutEmojis.splice(i, 1);
i--;
}
}
return result;
};
useEmojiSelectHandlerHook = function(args) {
const { onSelectEmoji, closePopout } = args;
const originalHandler = original_useEmojiSelectHandler.apply(this, arguments);
return function(data, state) {
if(state.toggleFavorite)
return originalHandler.apply(this, arguments);
const emoji = data.emoji;
if(emoji != null) {
onSelectEmoji(emoji, state.isFinalSelection);
if(state.isFinalSelection) closePopout();
}
};
};
}
function Stop() {
if(!Initialized) return;
searchHook = Discord.original_searchWithoutFetchingLatest;
parseHook = Discord.original_parse;
useEmojiSelectHandlerHook = Discord.original_useEmojiSelectHandler;
}
return function() { return {
getName: () => "DiscordFreeEmojis",
getShortName: () => "FreeEmojis",
getDescription: () => "Link emojis if you don't have nitro! Type them out or use the emoji picker! [64px]",
getVersion: () => "1.6",
getAuthor: () => "An0",
start: Start,
stop: Stop
}};
})();
module.exports = FreeEmojis;
/*@end @*/

View File

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

View File

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

View File

@@ -1,913 +0,0 @@
/**
* @name PermissionsViewer
* @description Allows you to view a user's permissions. Thanks to Noodlebox for the idea!
* @version 0.2.6
* @author Zerebos
* @authorId 249746236008169473
* @website https://github.com/rauenzi/BetterDiscordAddons/tree/master/Plugins/PermissionsViewer
* @source https://raw.githubusercontent.com/rauenzi/BetterDiscordAddons/master/Plugins/PermissionsViewer/PermissionsViewer.plugin.js
*/
/*@cc_on
@if (@_jscript)
// Offer to self-install for clueless users that try to run this directly.
var shell = WScript.CreateObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\\BetterDiscord\\plugins");
var pathSelf = WScript.ScriptFullName;
// Put the user at ease by addressing them in the first person
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);
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
} else if (!fs.FolderExists(pathPlugins)) {
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
// Show the user where to put plugins in the future
shell.Exec("explorer " + pathPlugins);
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
}
WScript.Quit();
@else@*/
const config = {
info: {
name: "PermissionsViewer",
authors: [
{
name: "Zerebos",
discord_id: "249746236008169473",
github_username: "rauenzi",
twitter_username: "ZackRauen"
}
],
version: "0.2.6",
description: "Allows you to view a user's permissions. Thanks to Noodlebox for the idea!",
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: "Fixes",
type: "fixed",
items: [
"Popouts and context menus should all work once again!"
]
}
],
defaultConfig: [
{
type: "switch",
id: "contextMenus",
name: "Context Menus",
value: true
},
{
type: "switch",
id: "popouts",
name: "Popouts",
value: true
},
{
type: "radio",
id: "displayMode",
name: "Modal Display Mode",
value: "compact",
options: [
{
name: "Cozy",
value: "cozy"
},
{
name: "Compact",
value: "compact"
}
]
}
],
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."
},
displayMode: {
name: "Modal Display Mode"
}
}
},
ru: {
contextMenuLabel: "Полномочия",
popoutLabel: "Полномочия",
modal: {
header: "Полномочия ${name}",
rolesLabel: "Роли",
permissionsLabel: "Полномочия",
owner: "Владелец"
},
settings: {
popouts: {
name: "Показать во всплывающих окнах",
note: "Отображает полномочия пользователя в их всплывающем окне, аналогичном ролям."
},
contextMenus: {
name: "Кнопка контекстного меню",
note: "Добавить кнопку для отображения полномочий с помощью контекстных меню."
}
}
}
},
main: "index.js"
};
class Dummy {
constructor() {this._config = config;}
start() {}
stop() {}
}
if (!global.ZeresPluginLibrary) {
BdApi.showConfirmationModal("Library Missing", `The library plugin needed for ${config.name ?? config.info.name} is missing. Please click Download Now to install it.`, {
confirmText: "Download Now",
cancelText: "Cancel",
onConfirm: () => {
require("request").get("https://betterdiscord.app/gh-redirect?id=9", async (err, resp, body) => {
if (err) return require("electron").shell.openExternal("https://betterdiscord.app/Download?id=9");
if (resp.statusCode === 302) {
require("request").get(resp.headers.location, async (error, response, content) => {
if (error) return require("electron").shell.openExternal("https://betterdiscord.app/Download?id=9");
await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), content, r));
});
}
else {
await new Promise(r => require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body, r));
}
});
}
});
}
module.exports = !global.ZeresPluginLibrary ? Dummy : (([Plugin, Api]) => {
const plugin = (Plugin, Api) => {
const {ContextMenu, DOM, Utils} = window.BdApi;
const {DiscordModules, WebpackModules, Toasts, DiscordClasses, Utilities, DOMTools, ColorConverter, Structs, ReactTools} = Api;
const GuildStore = DiscordModules.GuildStore;
const SelectedGuildStore = DiscordModules.SelectedGuildStore;
const MemberStore = DiscordModules.GuildMemberStore;
const UserStore = DiscordModules.UserStore;
const DiscordPerms = Object.assign({}, DiscordModules.DiscordPermissions);
const AvatarDefaults = WebpackModules.getByProps("DEFAULT_AVATARS");
const ModalClasses = WebpackModules.getByProps("root", "header", "small");
const Strings = WebpackModules.getModule(m => m.Messages && m.Messages.COPY_ID).Messages;
const UserPopoutClasses = Object.assign({}, WebpackModules.getByProps("userPopout"), WebpackModules.getByProps("rolesList"), WebpackModules.getByProps("eyebrow"));
const UserPopoutSelectors = {};
for (const key in UserPopoutClasses) UserPopoutSelectors[key] = new Structs.Selector(UserPopoutClasses[key]);
const RoleClasses = Object.assign({}, DiscordClasses.PopoutRoles, WebpackModules.getByProps("rolesList"), WebpackModules.getByProps("roleName", "roleIcon"));
if (DiscordPerms.STREAM) {
DiscordPerms.VIDEO = DiscordPerms.STREAM;
delete DiscordPerms.STREAM;
}
if (DiscordPerms.MANAGE_GUILD) {
DiscordPerms.MANAGE_SERVER = DiscordPerms.MANAGE_GUILD;
delete DiscordPerms.MANAGE_GUILD;
}
return class PermissionsViewer extends Plugin {
constructor() {
super();
this.css = `.perm-user-avatar {
border-radius: 50%;
width: 16px;
height: 16px;
margin-right: 3px;
}
.member-perms-header {
color: var(--header-secondary);
display: flex;
justify-content: space-between;
}
.member-perms {
display: flex;
flex-wrap: wrap;
margin-top: 2px;
max-height: 160px;
overflow-y: auto;
overflow-x: hidden;
}
.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 {
z-index: 100;
}
#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 {
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: 273px;
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;
}
.theme-light #permissions-modal-wrapper #permissions-modal {
background: #fff;
}
.theme-light #permissions-modal-wrapper .modal-body {
background: transparent;
}
.theme-light #permissions-modal-wrapper .header {
background: transparent;
color: #000;
}
.theme-light #permissions-modal-wrapper .role-side {
background: rgba(0,0,0,.2);
}
.theme-light #permissions-modal-wrapper .perm-side {
background: rgba(0,0,0,.1);
}
.theme-light #permissions-modal-wrapper .role-item,
.theme-light #permissions-modal-wrapper .perm-name {
color: #000;
}
#permissions-modal-wrapper #permissions-modal {
width: auto;
}`;
this.jumbo = `#permissions-modal-wrapper #permissions-modal {
height: 840px;
}
#permissions-modal-wrapper #permissions-modal .perm-side {
width: 500px;
}
#permissions-modal .perm-scroller {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
#permissions-modal .perm-item {
width: 50%;
}`;
this.listHTML = `<div id="permissions-popout">
<div class="member-perms-header \${bodyTitle} \${eyebrow}">
<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.skinHTML = `<div class="section-3FmfOT" id="permissions-popout">
<h2 class="member-perms-header defaultColor-24IHKz eyebrow-Ejf06y defaultColor-HXu-5n title-1r9MQ6" data-text-variant="eyebrow">
<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>
</h2>
<div class="member-perms root-jbEB5E flex-3BkGQD wrap-7NZuTn roles-3zC7MX"></div>
</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">
<div id="permissions-modal" class="\${root} \${small}">
<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 perm-user-avatar" 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.cancelUserPopout = () => {};
this.contextMenuPatches = [];
}
onStart() {
DOM.addStyle(this.name, this.css);
this.listHTML = Utilities.formatTString(this.listHTML, DiscordClasses.UserPopout);
this.listHTML = Utilities.formatTString(this.listHTML, RoleClasses);
this.listHTML = Utilities.formatTString(this.listHTML, UserPopoutClasses);
this.skinHTML = Utilities.formatTString(this.skinHTML, DiscordClasses.UserPopout);
this.skinHTML = Utilities.formatTString(this.skinHTML, RoleClasses);
this.skinHTML = Utilities.formatTString(this.skinHTML, UserPopoutClasses);
this.itemHTML = Utilities.formatTString(this.itemHTML, RoleClasses);
this.modalHTML = Utilities.formatTString(this.modalHTML, DiscordClasses.Backdrop);
this.modalHTML = Utilities.formatTString(this.modalHTML, {root: ModalClasses.root, small: ModalClasses.small});
this.promises = {state: {cancelled: false}, cancel() {this.state.cancelled = true;}};
if (this.settings.popouts) this.bindPopouts();
if (this.settings.contextMenus) this.bindContextMenus();
this.setDisplayMode(this.settings.displayMode);
}
onStop() {
DOM.removeStyle(this.name);
this.promises.cancel();
this.unbindPopouts();
this.unbindContextMenus();
}
setDisplayMode(mode) {
if (mode === "cozy") DOM.addStyle(this.name + "-jumbo", this.jumbo);
else DOM.removeStyle(this.name + "-jumbo");
}
patchPopouts(e) {
const popoutMount = (props) => {
const popout = document.querySelector(`[class*="userPopout-"], [class*="userPopoutOuter-"]`);
if (!popout || popout.querySelector("#permissions-popout")) return;
const user = MemberStore.getMember(props.guildId, props.user.id);
const guild = GuildStore.getGuild(props.guildId);
const name = MemberStore.getNick(props.guildId, props.user.id) ?? props.user.username;
if (!user || !guild || !name) return;
const userRoles = user.roles.slice(0);
userRoles.push(guild.id);
userRoles.reverse();
let perms = 0n;
const isSkin = popout.className.includes("userPopoutOuter");
const permBlock = DOMTools.createElement(Utilities.formatTString(isSkin ? this.skinHTML : this.listHTML, {label: this.strings.popoutLabel}));
const memberPerms = permBlock.querySelector(".member-perms");
const strings = Strings;
for (let r = 0; r < userRoles.length; r++) {
const role = userRoles[r];
if (!guild.roles[role]) continue;
perms = perms | guild.roles[role].permissions;
for (const perm in DiscordPerms) {
const permName = strings[perm] || perm.split("_").map(n => n[0].toUpperCase() + n.slice(1).toLowerCase()).join(" ");
const hasPerm = (perms & DiscordPerms[perm]) == DiscordPerms[perm];
if (hasPerm && !memberPerms.querySelector(`[data-name="${permName}"]`)) {
const element = DOMTools.createElement(this.itemHTML);
if (isSkin) element.classList.add("rolePill-2Lo5dd");
let roleColor = guild.roles[role].colorString;
element.querySelector(".name").textContent = permName;
element.setAttribute("data-name", permName);
if (!roleColor) roleColor = "#B9BBBE";
element.querySelector(".perm-circle").style.backgroundColor = ColorConverter.rgbToAlpha(roleColor, 1);
element.style.borderColor = ColorConverter.rgbToAlpha(roleColor, 0.6);
memberPerms.prepend(element);
}
}
}
permBlock.querySelector(".perm-details").addEventListener("click", () => {
this.showModal(this.createModalUser(name, user, guild));
});
let roleList = popout.querySelector(isSkin ? ".roles-3zC7MX" : UserPopoutSelectors.rolesList);
if (isSkin) roleList = roleList.parentElement;
roleList?.parentNode?.insertBefore(permBlock, roleList.nextSibling);
const popoutInstance = ReactTools.getOwnerInstance(popout, {include: ["Popout"]});
if (!popoutInstance || !popoutInstance.updateOffsets) return;
popoutInstance.updateOffsets();
};
if (!e.addedNodes.length || !(e.addedNodes[0] instanceof Element)) return;
// console.log(e)
const element = e.addedNodes[0];
const popout = element.querySelector(`[class*="userPopout-"], [class*="userPopoutOuter-"]`) ?? element;
if (!popout || !popout.matches(`[class*="userPopout-"], [class*="userPopoutOuter-"]`)) return;
const props = Utilities.findInTree(ReactTools.getReactInstance(popout), m => m && m.user, {walkable: ["return", "memoizedProps"]});
popoutMount(props);
}
bindPopouts() {
this.observer = this.patchPopouts.bind(this);
}
unbindPopouts() {
this.observer = undefined;
}
async bindContextMenus() {
this.patchChannelContextMenu();
this.patchGuildContextMenu();
this.patchUserContextMenu();
}
unbindContextMenus() {
for (const cancel of this.contextMenuPatches) cancel();
}
patchGuildContextMenu() {
this.contextMenuPatches.push(ContextMenu.patch("guild-context", (retVal, props) => {
const newItem = ContextMenu.buildItem({
label: this.strings.contextMenuLabel,
action: () => {
this.showModal(this.createModalGuild(props.guild.name, props.guild));
}
});
retVal.props.children.splice(1, 0, newItem);
}));
}
patchChannelContextMenu() {
this.contextMenuPatches.push(ContextMenu.patch("channel-context", (retVal, props) => {
const newItem = ContextMenu.buildItem({
label: this.strings.contextMenuLabel,
action: () => {
if (!Object.keys(props.channel.permissionOverwrites).length) return Toasts.info(`#${props.channel.name} has no permission overrides`);
this.showModal(this.createModalChannel(props.channel.name, props.channel, props.guild));
}
});
retVal.props.children.splice(1, 0, newItem);
}));
}
patchUserContextMenu() {
this.contextMenuPatches.push(ContextMenu.patch("user-context", (retVal, props) => {
const guild = GuildStore.getGuild(props.guildId);
if (!guild) return;
const newItem = ContextMenu.buildItem({
label: this.strings.contextMenuLabel,
action: () => {
const user = MemberStore.getMember(props.guildId, props.user.id);
const name = user.nick ? user.nick : props.user.username;
this.showModal(this.createModalUser(name, user, guild));
}
});
retVal?.props?.children[0]?.props?.children.splice(2, 0, newItem);
}));
}
showModal(modal) {
const popout = document.querySelector(UserPopoutSelectors.userPopout);
if (popout) popout.style.display = "none";
const app = document.querySelector(".app-19_DXt");
if (app) app.append(modal);
else document.querySelector("#app-mount").append(modal);
}
createModalChannel(name, channel, guild) {
return this.createModal(`#${name}`, channel.permissionOverwrites, guild.roles, true);
}
createModalUser(name, user, guild) {
const guildRoles = Object.assign({}, guild.roles);
const userRoles = user.roles.slice(0).filter(r => typeof(guildRoles[r]) !== "undefined");
userRoles.push(guild.id);
userRoles.sort((a, b) => {return guildRoles[b].position - guildRoles[a].position;});
if (user.userId == guild.ownerId) {
const ALL_PERMISSIONS = Object.values(DiscordModules.DiscordPermissions).reduce((all, p) => all | p);
userRoles.push(user.userId);
guildRoles[user.userId] = {name: this.strings.modal.owner, permissions: ALL_PERMISSIONS};
}
return this.createModal(name, userRoles, guildRoles);
}
createModalGuild(name, guild) {
return this.createModal(name, guild.roles);
}
createModal(title, displayRoles, referenceRoles, isOverride = false) {
if (!referenceRoles) referenceRoles = displayRoles;
const modal = DOMTools.createElement(Utilities.formatTString(Utilities.formatTString(this.modalHTML, this.strings.modal), {name: Utils.escapeHTML(title)}));
modal.querySelector(".callout-backdrop").addEventListener("click", () => {
modal.classList.add("closing");
setTimeout(() => {modal.remove();}, 300);
});
const strings = Strings || {};
for (const r in displayRoles) {
const role = Array.isArray(displayRoles) ? displayRoles[r] : r;
const user = UserStore.getUser(role) || {getAvatarURL: () => AvatarDefaults.DEFAULT_AVATARS[Math.floor(Math.random() * AvatarDefaults.DEFAULT_AVATARS.length)], username: role};
const member = MemberStore.getMember(SelectedGuildStore.getGuildId(), role) || {colorString: ""};
const item = DOMTools.createElement(!isOverride || displayRoles[role].type == 0 ? this.modalButton : Utilities.formatTString(this.modalButtonUser, {avatarUrl: user.getAvatarURL(null, 16, true)})); // getAvatarURL(guildId, size, canAnimate);
if (!isOverride || displayRoles[role].type == 0) item.style.color = referenceRoles[role].colorString;
else item.style.color = member.colorString;
if (isOverride) item.querySelector(".role-name").innerHTML = Utils.escapeHTML(displayRoles[role].type == 0 ? referenceRoles[role].name : user.username);
else item.querySelector(".role-name").innerHTML = Utils.escapeHTML(referenceRoles[role].name);
modal.querySelector(".role-scroller").append(item);
item.addEventListener("click", () => {
modal.querySelectorAll(".role-item.selected").forEach(e => e.classList.remove("selected"));
item.classList.add("selected");
const allowed = isOverride ? displayRoles[role].allow : referenceRoles[role].permissions;
const denied = isOverride ? displayRoles[role].deny : null;
const permList = modal.querySelector(".perm-scroller");
permList.innerHTML = "";
for (const perm in DiscordPerms) {
const element = DOMTools.createElement(this.modalItem);
const permAllowed = (allowed & DiscordPerms[perm]) == DiscordPerms[perm];
const permDenied = isOverride ? (denied & DiscordPerms[perm]) == DiscordPerms[perm] : !permAllowed;
if (!permAllowed && !permDenied) continue;
if (permAllowed) {
element.classList.add("allowed");
element.prepend(DOMTools.createElement(this.permAllowedIcon));
}
if (permDenied) {
element.classList.add("denied");
element.prepend(DOMTools.createElement(this.permDeniedIcon));
}
element.querySelector(".perm-name").textContent = strings[perm] || perm.split("_").map(n => n[0].toUpperCase() + n.slice(1).toLowerCase()).join(" ");
permList.append(element);
}
});
item.addEventListener("contextmenu", (e) => {
ContextMenu.open(e, ContextMenu.buildMenu([
{label: Strings.COPY_ID ?? "Copy Id", action: () => {DiscordModules.ElectronModule.copy(role);}}
]));
});
}
modal.querySelector(".role-item").click();
return modal;
}
getSettingsPanel() {
const panel = this.buildSettingsPanel();
panel.addListener((id, checked) => {
if (id == "popouts") {
if (checked) this.bindPopouts();
else this.unbindPopouts();
}
if (id == "contextMenus") {
if (checked) this.bindContextMenus();
this.unbindContextMenus();
}
if (id == "displayMode") this.setDisplayMode(checked);
});
return panel.getElement();
}
};
};
return plugin(Plugin, Api);
})(global.ZeresPluginLibrary.buildPlugin(config));
/*@end@*/

View File

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

View File

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

File diff suppressed because it is too large Load Diff