STR v2.0.10

This commit is contained in:
_Lighty_ 2020-02-27 21:04:39 +01:00
parent 7b9f56537c
commit b668463c39
2 changed files with 216 additions and 138 deletions

View File

@ -1,4 +1,10 @@
# [SaveToRedux](https://1lighty.github.io/BetterDiscordStuff/?plugin=SaveToRedux "SaveToRedux") Changelog # [SaveToRedux](https://1lighty.github.io/BetterDiscordStuff/?plugin=SaveToRedux "SaveToRedux") Changelog
### 2.0.10
- Fixed the append random option when a file conflicted not working properly.
- Most of the changes are under the hood and functionally don't make too much of a difference.
- Saving with Save As... or browsing for a folder no longer freezes Discord.
- In the event the plugin cannot start, it will warn you that it failed to start.
### 2.0.9 ### 2.0.9
- Added new conflict option. If a file already exists, it can open up the Save As... modal to set a custom name instead. - Added new conflict option. If a file already exists, it can open up the Save As... modal to set a custom name instead.
- Added a Randomize button to the Save As... modal. - Added a Randomize button to the Save As... modal.

View File

@ -41,16 +41,16 @@ var SaveToRedux = (() => {
twitter_username: '' twitter_username: ''
} }
], ],
version: '2.0.9', version: '2.0.10',
description: 'Allows you to save images, videos, profile icons, server icons, reactions, emotes and custom status emotes to any folder quickly.', description: 'Allows you to save images, videos, profile icons, server icons, reactions, emotes and custom status emotes to any folder quickly.',
github: 'https://github.com/1Lighty', github: 'https://github.com/1Lighty',
github_raw: 'https://raw.githubusercontent.com/1Lighty/BetterDiscordPlugins/master/Plugins/SaveToRedux/SaveToRedux.plugin.js' github_raw: 'https://raw.githubusercontent.com/1Lighty/BetterDiscordPlugins/master/Plugins/SaveToRedux/SaveToRedux.plugin.js'
}, },
changelog: [ changelog: [
{ {
title: 'QOL', title: 'heck',
type: 'fixed', type: 'added',
items: ['Added new conflict option. If a file already exists, it can open up the Save As... modal to set a custom name instead.', 'Added a Randomize button to the Save As... modal.', 'Properly sanitizing filenames now.'] items: ['Fixed the append random option when a file conflicted not working properly.', "Most of the changes are under the hood and functionally don't make too much of a difference.", 'Saving with Save As... or browsing for a folder no longer freezes Discord.', 'In the event the plugin cannot start, it will warn you that it failed to start.']
} }
], ],
defaultConfig: [ defaultConfig: [
@ -103,28 +103,26 @@ var SaveToRedux = (() => {
/* Build */ /* Build */
const buildPlugin = ([Plugin, Api]) => { const buildPlugin = ([Plugin, Api]) => {
const { ContextMenu, EmulatedTooltip, Toasts, Settings, Popouts, Modals, Utilities, WebpackModules, Filters, DiscordModules, ColorConverter, DOMTools, DiscordClasses, DiscordSelectors, ReactTools, ReactComponents, DiscordAPI, Logger, Patcher, PluginUpdater, PluginUtilities, DiscordClassModules, Structs } = Api; const { Settings, Modals, Utilities, WebpackModules, DiscordModules, DiscordClasses, ReactComponents, DiscordAPI, Logger, Patcher, PluginUpdater, PluginUtilities } = Api;
const { React, ModalStack, ContextMenuActions, ContextMenuItem, ContextMenuItemsGroup, ReactDOM, ChannelStore, GuildStore, UserStore, DiscordConstants, Dispatcher, GuildMemberStore, GuildActions, SwitchRow, EmojiUtils, RadioGroup } = DiscordModules; const { React, ContextMenuActions, ReactDOM, GuildStore, DiscordConstants, Dispatcher, SwitchRow, EmojiUtils, RadioGroup } = DiscordModules;
const TextComponent = Utilities.getNestedProp(DiscordModules, 'TextElement.default');
const getEmojiURL = Utilities.getNestedProp(WebpackModules.getByProps('getEmojiURL'), 'getEmojiURL');
const showAlertModal = Utilities.getNestedProp(
WebpackModules.find(m => m.show && m.show.toString().search(/\w\.minorText,\w=\w\.onConfirmSecondary/)),
'show'
);
const ContextMenuSubMenuItem = WebpackModules.getByDisplayName('FluxContainer(SubMenuItem)'); const dialog = Utilities.getNestedProp(require('electron'), 'remote.dialog');
const TextComponent = WebpackModules.getByDisplayName('Text'); const openItem = Utilities.getNestedProp(require('electron'), 'shell.openItem');
const getEmojiURL = WebpackModules.getByProps('getEmojiURL').getEmojiURL; const DelayedCall = Utilities.getNestedProp(WebpackModules.getByProps('DelayedCall'), 'DelayedCall');
const showAlertModal = WebpackModules.find(m => m.show && m.show.toString().search(/\w\.minorText,\w=\w\.onConfirmSecondary/)).show;
const dialog = require('electron').remote.dialog;
const openSaveDialog = dialog.showSaveDialogSync || dialog.showSaveDialog;
const openOpenDialog = dialog.showOpenDialogSync || dialog.showOpenDialog;
const openItem = require('electron').shell.openItem;
const DelayedCall = WebpackModules.getByProps('DelayedCall').DelayedCall;
const FsModule = require('fs'); const FsModule = require('fs');
const RequestModule = require('request'); const RequestModule = require('request');
const PathModule = require('path'); const PathModule = require('path');
const MimeTypesModule = require('mime-types'); const MimeTypesModule = require('mime-types');
const FormItem = WebpackModules.getByDisplayName('FormItem'); const FormItem = WebpackModules.getByDisplayName('FormItem');
const Messages = WebpackModules.getByProps('Messages').Messages; const Messages = Utilities.getNestedProp(WebpackModules.getByProps('Messages'), 'Messages');
const TextInput = WebpackModules.getByDisplayName('TextInput'); const TextInput = WebpackModules.getByDisplayName('TextInput');
const AvatarModule = WebpackModules.getByProps('getChannelIconURL'); const AvatarModule = WebpackModules.getByProps('getChannelIconURL');
const MessageShit = WebpackModules.find(m => m.default && m.getMessage); const MessageShit = WebpackModules.find(m => m.default && m.getMessage);
const TrustStore = WebpackModules.getByProps('isTrustedDomain'); const TrustStore = WebpackModules.getByProps('isTrustedDomain');
@ -135,7 +133,14 @@ var SaveToRedux = (() => {
isTrustedDomain.domains = [/\/\/steamuserimages-\w\.akamaihd\.net\//, /\/\/steamcdn-\w\.akamaihd\.net\//, /\/\/steamcommunity-\w\.akamaihd\.net\//, '//cdn.discordapp.com/', '//media.discordapp.net/', /\/\/images-ext-\d\.discordapp\.net\//, '//i.ytimg.com/', /\/\/static\d\.e621\.net\//, '//pbs.twimg.com/', '//preview.redd.it/', '//cdn.shopify.com/', '//discordapp.com/', '//i.imgur.com/', '//i.clouds.tf/', '//image.prntscr.com/', '//i.giphy.com/', '//media.tenor.co/']; isTrustedDomain.domains = [/\/\/steamuserimages-\w\.akamaihd\.net\//, /\/\/steamcdn-\w\.akamaihd\.net\//, /\/\/steamcommunity-\w\.akamaihd\.net\//, '//cdn.discordapp.com/', '//media.discordapp.net/', /\/\/images-ext-\d\.discordapp\.net\//, '//i.ytimg.com/', /\/\/static\d\.e621\.net\//, '//pbs.twimg.com/', '//preview.redd.it/', '//cdn.shopify.com/', '//discordapp.com/', '//i.imgur.com/', '//i.clouds.tf/', '//image.prntscr.com/', '//i.giphy.com/', '//media.tenor.co/'];
const MessageStrings = { const MessageStrings = {
UNTRUSTED_LINK: MessageShit.getMessage("If you see this, SaveToRedux has failed to get a safe proxied version of the image URL **!!{url}!!**. If you do not recognize the domain, it's best you don't download from it as it could potentially be an IP logger.\n\nAre you sure you want to download an image from this domain?", 'en-US') UNTRUSTED_LINK: (() => {
try {
return MessageShit.getMessage("If you see this, SaveToRedux has failed to get a safe proxied version of the image URL **!!{url}!!**. If you do not recognize the domain, it's best you don't download from it as it could potentially be an IP logger.\n\nAre you sure you want to download an image from this domain?", 'en-US');
} catch (e) {
Logger.stacktrace('Failed to create message', e);
return null;
}
})()
}; };
class FolderEditor extends React.Component { class FolderEditor extends React.Component {
@ -262,6 +267,14 @@ var SaveToRedux = (() => {
return '' === o ? l : n(l, ''); return '' === o ? l : n(l, '');
} }
const faultyVars = [];
{
const vars = { TextComponent, getEmojiURL, openItem, DelayedCall, FormItem, Messages, TextInput, AvatarModule, TrustStore };
for (const varName in vars) {
if (!vars[varName]) faultyVars.push(varName);
}
}
return class SaveToRedux extends Plugin { return class SaveToRedux extends Plugin {
constructor() { constructor() {
super(); super();
@ -276,8 +289,27 @@ var SaveToRedux = (() => {
}; };
XenoLib.DiscordUtils.bindAll(this, ['handleContextMenu', 'formatFilename']); XenoLib.DiscordUtils.bindAll(this, ['handleContextMenu', 'formatFilename']);
XenoLib.changeName(__filename, 'SaveToRedux'); XenoLib.changeName(__filename, 'SaveToRedux');
const oOnStart = this.onStart.bind(this);
this.onStart = () => {
try {
oOnStart();
} catch (e) {
Logger.stacktrace('Failed to start!', e);
PluginUpdater.checkForUpdate(this.name, this.version, this._config.info.github_raw);
XenoLib.Notifications.error(`[**${this.name}**] Failed to start! Please update it, press CTRL + R, or ${GuildStore.getGuild(XenoLib.supportServerId) ? 'go to <#639665366380838924>' : '[join my support server](https://discord.gg/NYvWdN5)'} for further assistance.`, { timeout: 0 });
try {
this.onStop();
} catch (e) {}
}
};
} }
onStart() { onStart() {
this.promises = { state: { cancelled: false } };
if (faultyVars.length) {
Logger.error(`Following vars are invalid: ${faultyVars.map(e => '\n' + e).reduce((e, b) => e + b, '')}`);
PluginUpdater.checkForUpdate(this.name, this.version, this._config.info.github_raw);
return XenoLib.Notifications.error(`[**${this.name}**] Plugin is in a broken state. Please update it, press CTRL + R or ${GuildStore.getGuild(XenoLib.supportServerId) ? 'go to <#639665366380838924>' : '[join my support server](https://discord.gg/NYvWdN5)'} for further assistance.`, { timeout: 0 });
}
/* trigger settings migration */ /* trigger settings migration */
if (typeof this.settings.folders !== 'undefined') { if (typeof this.settings.folders !== 'undefined') {
const settings = Utilities.deepclone(this.defaultSettings); const settings = Utilities.deepclone(this.defaultSettings);
@ -293,7 +325,6 @@ var SaveToRedux = (() => {
this.saveSettings(); this.saveSettings();
this.saveFolders(); this.saveFolders();
} }
this.promises = { state: { cancelled: false } };
this.folders = XenoLib.loadData(this.name, 'folders', { this.folders = XenoLib.loadData(this.name, 'folders', {
data: [] data: []
}).data; }).data;
@ -567,7 +598,6 @@ var SaveToRedux = (() => {
), ),
{ {
confirmText: 'Save', confirmText: 'Save',
onCancel: e => console.log('oof'),
onConfirm: () => { onConfirm: () => {
const onDoShitOrWhateverFuckThisShitMan = val => { const onDoShitOrWhateverFuckThisShitMan = val => {
if (!folder || folder === -1) return onOk(val); if (!folder || folder === -1) return onOk(val);
@ -619,6 +649,7 @@ var SaveToRedux = (() => {
} }
case 3: { case 3: {
path = `${basePath}/${formattedurl.name}-${this.rand()}${formattedurl.extension ? '.' + formattedurl.extension : ''}`; path = `${basePath}/${formattedurl.name}-${this.rand()}${formattedurl.extension ? '.' + formattedurl.extension : ''}`;
break;
} }
case 4: case 4:
return handleSaveAs(true); return handleSaveAs(true);
@ -761,58 +792,64 @@ var SaveToRedux = (() => {
subItems.push( subItems.push(
...folderSubMenus, ...folderSubMenus,
XenoLib.createContextMenuItem('Add Folder', () => { XenoLib.createContextMenuItem('Add Folder', () => {
const path = openOpenDialog({ dialog
title: 'Add folder', .showOpenDialog({
properties: ['openDirectory', 'createDirectory'] title: 'Add folder',
}); properties: ['openDirectory', 'createDirectory']
if (!path) return BdApi.showToast('Maybe next time.'); })
let idx; .then(({ filePaths: [path] }) => {
if ((idx = this.folders.findIndex(m => m.path === path[0])) !== -1) return BdApi.showToast(`Folder already exists as ${this.folders[idx].name}!`, { type: 'error', timeout: 5000 }); if (!path) return BdApi.showToast('Maybe next time.');
const folderName = PathModule.basename(path[0]); let idx;
let __name = folderName; if ((idx = this.folders.findIndex(m => m.path === path)) !== -1) return BdApi.showToast(`Folder already exists as ${this.folders[idx].name}!`, { type: 'error', timeout: 5000 });
let __path = path[0].slice(0); const folderName = PathModule.basename(path);
const saveFolder = () => { let __name = folderName;
if (!__path || !__path.length) return BdApi.showToast('Invalid path', { type: 'error' }); let __path = path.slice(0);
this.folders.push({ const saveFolder = () => {
path: __path, if (!__path || !__path.length) return BdApi.showToast('Invalid path', { type: 'error' });
name: __name || 'Unnamed' this.folders.push({
path: __path,
name: __name || 'Unnamed'
});
this.saveFolders();
BdApi.showToast('Added!', { type: 'success' });
};
Modals.showModal(
'Create New Folder',
React.createElement(FolderEditor, {
name: folderName,
path: path,
onNameChange: e => (__name = e),
onPathChange: e => (__path = e)
}),
{
confirmText: 'Create',
onConfirm: saveFolder,
size: XenoLib.joinClassNames(Modals.ModalSizes.MEDIUM, 'ST-modal')
}
);
}); });
this.saveFolders();
BdApi.showToast('Added!', { type: 'success' });
};
Modals.showModal(
'Create New Folder',
React.createElement(FolderEditor, {
name: folderName,
path: path[0],
onNameChange: e => (__name = e),
onPathChange: e => (__path = e)
}),
{
confirmText: 'Create',
onConfirm: saveFolder,
size: XenoLib.joinClassNames(Modals.ModalSizes.MEDIUM, 'ST-modal')
}
);
}), }),
XenoLib.createContextMenuItem('Save As...', () => { XenoLib.createContextMenuItem('Save As...', () => {
const path = openSaveDialog({ dialog
defaultPath: formattedurl.fileName, .showSaveDialog({
filters: formattedurl.extension defaultPath: formattedurl.fileName,
? [ filters: formattedurl.extension
{ ? [
name: /\.{0,1}(png|jpe?g|webp|gif|svg)$/i.test(formattedurl.extension) ? 'Images' : /\.{0,1}(mp4|webm|mov)$/i.test(formattedurl.extension) ? 'Videos' : /\.{0,1}(mp3|ogg|wav|flac)$/i.test(formattedurl.extension) ? 'Audio' : 'Files', {
extensions: [formattedurl.extension] name: /\.{0,1}(png|jpe?g|webp|gif|svg)$/i.test(formattedurl.extension) ? 'Images' : /\.{0,1}(mp4|webm|mov)$/i.test(formattedurl.extension) ? 'Videos' : /\.{0,1}(mp3|ogg|wav|flac)$/i.test(formattedurl.extension) ? 'Audio' : 'Files',
}, extensions: [formattedurl.extension]
{ },
name: 'All Files', {
extensions: ['*'] name: 'All Files',
} extensions: ['*']
] }
: undefined ]
}); : undefined
if (!path) return BdApi.showToast('Maybe next time.'); })
saveFile(path, undefined, false, true); .then(({ filePath: path }) => {
if (!path) return BdApi.showToast('Maybe next time.');
saveFile(path, undefined, false, true);
});
}) })
); );
return createSubMenu(`Save ${type} To`, subItems, () => { return createSubMenu(`Save ${type} To`, subItems, () => {
@ -978,9 +1015,6 @@ var SaveToRedux = (() => {
get [Symbol.toStringTag]() { get [Symbol.toStringTag]() {
return 'Plugin'; return 'Plugin';
} }
get css() {
return this._css;
}
get name() { get name() {
return config.info.name; return config.info.name;
} }
@ -1008,7 +1042,22 @@ var SaveToRedux = (() => {
/* Finalize */ /* Finalize */
return !global.ZeresPluginLibrary || !global.XenoLib /* this new lib loader is lit */
let ZeresPluginLibraryOutdated = false;
let XenoLibOutdated = false;
try {
if (global.BdApi && 'function' == typeof BdApi.getPlugin) {
const i = (i, n) => ((i = i.split('.').map(i => parseInt(i))), (n = n.split('.').map(i => parseInt(i))), !!(n[0] > i[0]) || !!(n[0] == i[0] && n[1] > i[1]) || !!(n[0] == i[0] && n[1] == i[1] && n[2] > i[2])),
n = (n, e) => n && n._config && n._config.info && n._config.info.version && i(n._config.info.version, e),
e = BdApi.getPlugin('ZeresPluginLibrary'),
o = BdApi.getPlugin('XenoLib');
n(e, '1.2.10') && (ZeresPluginLibraryOutdated = !0), n(o, '1.3.10') && (XenoLibOutdated = !0);
}
} catch (i) {
console.error('Error checking if libraries are out of date', i);
}
return !global.ZeresPluginLibrary || !global.XenoLib || ZeresPluginLibraryOutdated || XenoLibOutdated
? class { ? class {
getName() { getName() {
return this.name.replace(/\s+/g, ''); return this.name.replace(/\s+/g, '');
@ -1024,71 +1073,94 @@ var SaveToRedux = (() => {
} }
stop() {} stop() {}
load() { load() {
const ezlibMissing = !global.XenoLib; const a = !global.XenoLib,
const zlibMissing = !global.ZeresPluginLibrary; b = !global.ZeresPluginLibrary,
const bothLibsMissing = ezlibMissing && zlibMissing; c = (a && b) || ((a || b) && (XenoLibOutdated || ZeresPluginLibraryOutdated)) || XenoLibOutdated || ZeresPluginLibraryOutdated,
const header = `Missing ${(bothLibsMissing && 'Libraries') || 'Library'}`; d = (() => {
const content = `The ${(bothLibsMissing && 'Libraries') || 'Library'} ${(zlibMissing && 'ZeresPluginLibrary') || ''} ${(ezlibMissing && (zlibMissing ? 'and XenoLib' : 'XenoLib')) || ''} required for ${this.name} ${(bothLibsMissing && 'are') || 'is'} missing.`; let d = '';
const ModalStack = BdApi.findModuleByProps('push', 'update', 'pop', 'popWithKey'); return a || b ? (d += `Missing${XenoLibOutdated || ZeresPluginLibraryOutdated ? ' and outdated' : ''} `) : (XenoLibOutdated || ZeresPluginLibraryOutdated) && (d += `Outdated `), (d += `${c ? 'Libraries' : 'Library'} `), d;
const TextElement = BdApi.findModuleByProps('Sizes', 'Weights'); })(),
const ConfirmationModal = BdApi.findModule(m => m.defaultProps && m.key && m.key() === 'confirm-modal'); e = (() => {
const onFail = () => BdApi.getCore().alert(header, `${content}<br/>Due to a slight mishap however, you'll have to download the libraries yourself. After opening the links, do CTRL + S to download the library.<br/>${(zlibMissing && '<br/><a href="https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js"target="_blank">Click here to download ZeresPluginLibrary</a>') || ''}${(zlibMissing && '<br/><a href="http://localhost:7474/XenoLib.js"target="_blank">Click here to download XenoLib</a>') || ''}`); let d = `The ${c ? 'libraries' : 'library'} `;
if (!ModalStack || !ConfirmationModal || !TextElement) return onFail(); return a || XenoLibOutdated ? ((d += 'XenoLib '), (b || ZeresPluginLibraryOutdated) && (d += 'and ZeresPluginLibrary ')) : (b || ZeresPluginLibraryOutdated) && (d += 'ZeresPluginLibrary '), (d += `required for ${this.name} ${c ? 'are' : 'is'} ${a || b ? 'missing' : ''}${XenoLibOutdated || ZeresPluginLibraryOutdated ? (a || b ? ' and/or outdated' : 'outdated') : ''}.`), d;
ModalStack.push(props => { })(),
return BdApi.React.createElement( f = BdApi.findModuleByProps('push', 'update', 'pop', 'popWithKey'),
ConfirmationModal, g = BdApi.findModuleByProps('Sizes', 'Weights'),
Object.assign( h = BdApi.findModule(a => a.defaultProps && a.key && 'confirm-modal' === a.key()),
{ i = () => BdApi.getCore().alert(d, `${e}<br/>Due to a slight mishap however, you'll have to download the libraries yourself. After opening the links, do CTRL + S to download the library.<br/>${b || ZeresPluginLibraryOutdated ? '<br/><a href="http://betterdiscord.net/ghdl/?url=https://github.com/rauenzi/BDPluginLibrary/blob/master/release/0PluginLibrary.plugin.js"target="_blank">Click here to download ZeresPluginLibrary</a>' : ''}${a || XenoLibOutdated ? '<br/><a href="http://betterdiscord.net/ghdl/?url=https://github.com/1Lighty/BetterDiscordPlugins/blob/master/Plugins/1XenoLib.plugin.js"target="_blank">Click here to download XenoLib</a>' : ''}`);
header, if (!f || !h || !g) return i();
children: [BdApi.React.createElement(TextElement, { color: TextElement.Colors.PRIMARY, children: [`${content} Please click Download Now to install ${(bothLibsMissing && 'them') || 'it'}.`] })], let j;
red: false, const k = (() => {
confirmText: 'Download Now', if (!global.pluginModule || !global.BDEvents) return;
cancelText: 'Cancel', if (a || XenoLibOutdated) {
onConfirm: () => { const a = () => {
const request = require('request'); BDEvents.off('xenolib-loaded', a), f.popWithKey(j), pluginModule.reloadPlugin(this.name);
const fs = require('fs'); };
const path = require('path'); return BDEvents.on('xenolib-loaded', a), () => BDEvents.off('xenolib-loaded', a);
const waitForLibLoad = callback => { }
if (!global.BDEvents) return callback(); const b = a => {
const onLoaded = e => { 'ZeresPluginLibrary' !== a || (BDEvents.off('plugin-loaded', b), BDEvents.off('plugin-reloaded', b), f.popWithKey(j), pluginModule.reloadPlugin(this.name));
if (e !== 'ZeresPluginLibrary') return; };
BDEvents.off('plugin-loaded', onLoaded); return BDEvents.on('plugin-loaded', b), BDEvents.on('plugin-reloaded', b), () => (BDEvents.off('plugin-loaded', b), BDEvents.off('plugin-reloaded', b));
callback(); })();
}; class l extends BdApi.React.PureComponent {
BDEvents.on('plugin-loaded', onLoaded); constructor(a) {
}; super(a), (this.state = { hasError: !1 });
const onDone = () => { }
if (!global.pluginModule || (!global.BDEvents && !global.XenoLib)) return; componentDidCatch(a, b) {
if (!global.BDEvents || global.XenoLib) pluginModule.reloadPlugin(this.name); console.error(`Error in ${this.props.label}, screenshot or copy paste the error above to Lighty for help.`), this.setState({ hasError: !0 }), 'function' == typeof this.props.onError && this.props.onError(a);
else { }
const listener = () => { render() {
pluginModule.reloadPlugin(this.name); return this.state.hasError ? null : this.props.children;
BDEvents.off('xenolib-loaded', listener); }
}; }
BDEvents.on('xenolib-loaded', listener); j = f.push(a =>
} BdApi.React.createElement(
}; l,
const downloadXenoLib = () => { {
if (global.XenoLib) return onDone(); label: 'missing dependency modal',
request('https://raw.githubusercontent.com/1Lighty/BetterDiscordPlugins/master/Plugins/1XenoLib.plugin.js', (error, response, body) => { onError: () => {
if (error) return onFail(); f.popWithKey(j), i();
onDone(); }
fs.writeFile(path.join(window.ContentManager.pluginsFolder, '1XenoLib.plugin.js'), body, () => {}); },
}); BdApi.React.createElement(
}; h,
if (!global.ZeresPluginLibrary) { Object.assign(
request('https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js', (error, response, body) => { {
if (error) return onFail(); header: d,
waitForLibLoad(downloadXenoLib); children: [BdApi.React.createElement(g, { color: g.Colors.PRIMARY, children: [`${e} Please click Download Now to download ${c ? 'them' : 'it'}.`] })],
fs.writeFile(path.join(window.ContentManager.pluginsFolder, '0PluginLibrary.plugin.js'), body, () => {}); red: !1,
}); confirmText: 'Download Now',
} else downloadXenoLib(); cancelText: 'Cancel',
} onConfirm: () => {
}, k();
props const a = require('request'),
b = require('fs'),
c = require('path'),
d = a => {
if (!global.BDEvents) return a();
const b = c => {
'ZeresPluginLibrary' !== c || (BDEvents.off('plugin-loaded', b), BDEvents.off('plugin-reloaded', b), a());
};
BDEvents.on('plugin-loaded', b), BDEvents.on('plugin-reloaded', b);
},
e = () => {
if (!global.pluginModule || (!global.BDEvents && !global.XenoLib)) return;
if ((global.XenoLib && !XenoLibOutdated) || !global.BDEvents) return pluginModule.reloadPlugin(this.name);
const a = () => {
BDEvents.off('xenolib-loaded', a), pluginModule.reloadPlugin(this.name);
};
BDEvents.on('xenolib-loaded', a);
},
f = () => (global.XenoLib && !XenoLibOutdated ? e() : void a('https://raw.githubusercontent.com/1Lighty/BetterDiscordPlugins/master/Plugins/1XenoLib.plugin.js', (a, d, f) => (a ? i() : void (e(), b.writeFile(c.join(window.ContentManager.pluginsFolder, '1XenoLib.plugin.js'), f, () => {})))));
!global.ZeresPluginLibrary || ZeresPluginLibraryOutdated ? a('https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js', (a, e, g) => (a ? i() : void (d(f), b.writeFile(c.join(window.ContentManager.pluginsFolder, '0PluginLibrary.plugin.js'), g, () => {})))) : f();
}
},
a
)
) )
); )
}); );
} }
start() {} start() {}