535 lines
24 KiB
JavaScript
535 lines
24 KiB
JavaScript
//META{"name":"MultiUploads","source":"https://github.com/1Lighty/BetterDiscordPlugins/blob/master/Plugins/MultiUploads/MultiUploads.plugin.js","website":"https://1lighty.github.io/BetterDiscordStuff/?plugin=MultiUploads","authorId":"239513071272329217","invite":"NYvWdN5","donate":"https://paypal.me/lighty13"}*//
|
|
/*@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.\nJust go to settings, plugins and enable me.', 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!\nJust go to settings, plugins and enable me!', 0, 'Successfully installed', 0x40);
|
|
}
|
|
WScript.Quit();
|
|
|
|
@else@*/
|
|
/*
|
|
* Copyright © 2019-2020, _Lighty_
|
|
* All rights reserved.
|
|
* Code may not be redistributed, modified or otherwise taken without explicit permission.
|
|
*/
|
|
module.exports = (() => {
|
|
/* Setup */
|
|
const config = {
|
|
main: 'index.js',
|
|
info: {
|
|
name: 'MultiUploads',
|
|
authors: [
|
|
{
|
|
name: 'Lighty',
|
|
discord_id: '239513071272329217',
|
|
github_username: 'LightyPon',
|
|
twitter_username: ''
|
|
}
|
|
],
|
|
version: '1.1.4',
|
|
description: 'Multiple uploads send in a single message, like on mobile. Hold shift while pressing the upload button to only upload one. Adds ability to paste multiple times.',
|
|
github: 'https://github.com/1Lighty',
|
|
github_raw: 'https://raw.githubusercontent.com/1Lighty/BetterDiscordPlugins/master/Plugins/MultiUploads/MultiUploads.plugin.js'
|
|
},
|
|
changelog: [
|
|
{
|
|
title: 'RIP BBD on Canary',
|
|
type: 'fixed',
|
|
items: ['More canary fixes.']
|
|
}
|
|
]
|
|
};
|
|
|
|
/* Build */
|
|
const buildPlugin = ([Plugin, Api]) => {
|
|
const { Utilities, WebpackModules, DiscordModules, ReactComponents, Logger, PluginUtilities } = Api;
|
|
const { ChannelStore, DiscordConstants, Dispatcher, Permissions } = DiscordModules;
|
|
|
|
const rendererFunctionClass = (() => {
|
|
try {
|
|
const topContext = require('electron').webFrame.top.context;
|
|
if (topContext === window) return null;
|
|
return topContext.Function
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
const originalFunctionClass = Function;
|
|
function createSmartPatcher(patcher) {
|
|
const createPatcher = patcher => {
|
|
return (moduleToPatch, functionName, callback, options = {}) => {
|
|
try {
|
|
var origDef = moduleToPatch[functionName];
|
|
} catch (_) {
|
|
return Logger.error(`Failed to patch ${functionName}`);
|
|
}
|
|
if (rendererFunctionClass && origDef && !(origDef instanceof originalFunctionClass) && origDef instanceof rendererFunctionClass) window.Function = rendererFunctionClass;
|
|
const unpatches = [];
|
|
try {
|
|
unpatches.push(patcher(moduleToPatch, functionName, callback, options) || DiscordConstants.NOOP);
|
|
} catch (err) {
|
|
throw err;
|
|
} finally {
|
|
if (rendererFunctionClass) window.Function = originalFunctionClass;
|
|
}
|
|
try {
|
|
if (origDef && origDef.__isBDFDBpatched && moduleToPatch.BDFDBpatch && typeof moduleToPatch.BDFDBpatch[functionName].originalMethod === 'function') {
|
|
/* do NOT patch a patch by ZLIb, that'd be bad and cause double items in context menus */
|
|
if ((Utilities.getNestedProp(ZeresPluginLibrary, 'Patcher.patches') || []).findIndex(e => e.module === moduleToPatch) !== -1 && moduleToPatch.BDFDBpatch[functionName].originalMethod.__originalFunction) return;
|
|
unpatches.push(patcher(moduleToPatch.BDFDBpatch[functionName], 'originalMethod', callback, options));
|
|
}
|
|
} catch (err) {
|
|
Logger.stacktrace('Failed to patch BDFDB patches', err);
|
|
}
|
|
return function unpatch() {
|
|
unpatches.forEach(e => e());
|
|
};
|
|
};
|
|
};
|
|
return Object.assign({}, patcher, {
|
|
before: createPatcher(patcher.before),
|
|
instead: createPatcher(patcher.instead),
|
|
after: createPatcher(patcher.after)
|
|
});
|
|
};
|
|
|
|
const Patcher = createSmartPatcher(Api.Patcher);
|
|
|
|
const _ = WebpackModules.getByProps('bindAll', 'debounce');
|
|
const Upload = (WebpackModules.getByProps('Upload') || {}).Upload;
|
|
const MessageDraftUtils = WebpackModules.getByProps('saveDraft');
|
|
const FileUtils = WebpackModules.getByProps('anyFileTooLarge');
|
|
const GenericUploaderBase = WebpackModules.find(e => e.prototype && e.prototype.upload && e.prototype.cancel && !e.__proto__.prototype.cancel);
|
|
const MessageFileUploader = WebpackModules.find(e => e.prototype && e.prototype.upload && e.__proto__ === GenericUploaderBase);
|
|
const UploadUtils = WebpackModules.getByProps('upload', 'instantBatchUpload', 'cancel');
|
|
|
|
return class MultiUploads extends Plugin {
|
|
constructor() {
|
|
super();
|
|
try {
|
|
WebpackModules.getByProps('openModal', 'hasModalOpen').closeModal(`${this.name}_DEP_MODAL`);
|
|
} catch (e) { }
|
|
_.bindAll(this, ['UPLOAD_MODAL_POP_FILE', 'UPLOAD_MODAL_PUSH_FILES', 'UPLOAD_MODAL_CLEAR_ALL_FILES']);
|
|
}
|
|
onStart() {
|
|
this.promises = { cancelled: false };
|
|
this.patchAll();
|
|
this.uploads = [];
|
|
if (!Upload) throw 'Upload class could not be found';
|
|
Dispatcher.subscribe('UPLOAD_MODAL_POP_FILE', this.UPLOAD_MODAL_POP_FILE);
|
|
Dispatcher.subscribe('UPLOAD_MODAL_PUSH_FILES', this.UPLOAD_MODAL_PUSH_FILES);
|
|
Dispatcher.subscribe('UPLOAD_MODAL_CLEAR_ALL_FILES', this.UPLOAD_MODAL_CLEAR_ALL_FILES);
|
|
}
|
|
|
|
onStop() {
|
|
this.promises.cancelled = true;
|
|
Patcher.unpatchAll();
|
|
Dispatcher.unsubscribe('UPLOAD_MODAL_POP_FILE', this.UPLOAD_MODAL_POP_FILE);
|
|
Dispatcher.unsubscribe('UPLOAD_MODAL_PUSH_FILES', this.UPLOAD_MODAL_PUSH_FILES);
|
|
Dispatcher.unsubscribe('UPLOAD_MODAL_CLEAR_ALL_FILES', this.UPLOAD_MODAL_CLEAR_ALL_FILES);
|
|
}
|
|
|
|
// Replicate UploadModalStore so we keep track of our own instead
|
|
UPLOAD_MODAL_POP_FILE() {
|
|
this.uploads.shift();
|
|
}
|
|
UPLOAD_MODAL_PUSH_FILES({ files, channelId }) {
|
|
for (const file of files) this.uploads.push(new Upload(file, channelId));
|
|
}
|
|
UPLOAD_MODAL_CLEAR_ALL_FILES() {
|
|
this.uploads = [];
|
|
}
|
|
|
|
/* PATCHES */
|
|
|
|
patchAll() {
|
|
this.patchMessageFileUploader();
|
|
this.patchUploadModal(this.promises);
|
|
this.patchInstantBatchUpload();
|
|
}
|
|
|
|
patchMessageFileUploader() {
|
|
const superagent = WebpackModules.getByProps('getXHR');
|
|
// Reverse engineered, override it entirely with our own implementation
|
|
Patcher.instead(MessageFileUploader.prototype, 'upload', (_this, [file, message = {}]) => {
|
|
const noSpoilerMessage = Object.assign({}, message);
|
|
// hasSpoiler has no use here, only used to check if images should be spoilered
|
|
delete noSpoilerMessage.hasSpoiler;
|
|
// make a fale foče if it's multi upload, and set the name to represent how many files we're uploading
|
|
const fakeFile = Array.isArray(file) ? Object.assign({}, file[0], { name: `Uploading ${file.length} files...` }) : file;
|
|
// call super.upload(fakeFile, noSpoilerImage);
|
|
// since no access to super, this is the next best thing
|
|
GenericUploaderBase.prototype.upload.call(_this, fakeFile, noSpoilerMessage);
|
|
const req = superagent.post(_this._url);
|
|
// if it's multiple files, attach them, each having a different field name
|
|
// this was reversed by snooping mobile uploads, apparently each file is its own field
|
|
// each field being file(file index) so file0 file1 file2 file3 file4 etc, with file being the default single upload
|
|
if (Array.isArray(file)) {
|
|
const numMap = {};
|
|
file.forEach((e, idx) => {
|
|
let name = e.name;
|
|
// ensure no other file has the same name, otherwise we'll be in a world of pain
|
|
if (file.find((e_, idx_) => e_.name === name && idx_ < idx)) {
|
|
if (!numMap[name]) numMap[name] = 0;
|
|
numMap[name]++;
|
|
const split = name.split('.');
|
|
// no extention, just append the number
|
|
if (split.length === 1) name = `${numMap[name]}`;
|
|
else {
|
|
// extract everything before the extension, add number, then the extension
|
|
const beforeExt = split.slice(0, -1);
|
|
const ext = split.slice(-1);
|
|
name = `${beforeExt.join('.')}${numMap[name]}.${ext}`;
|
|
}
|
|
}
|
|
// attach, with its own unique file field
|
|
req.attach('file' + idx, e, (message.hasSpoiler ? 'SPOILER_' : '') + name);
|
|
});
|
|
}
|
|
else req.attach('file', file, (message.hasSpoiler ? 'SPOILER_' : '') + file.name);
|
|
// added on replies update, dunno why? throws error if it's not here
|
|
req.field('payload_json', JSON.stringify(noSpoilerMessage));
|
|
// attach all other fields, sometimes value is a non valid type though
|
|
_.each(noSpoilerMessage, (value, key) => {
|
|
if (!value) return;
|
|
req.field(key, value);
|
|
});
|
|
req.then(e => {
|
|
if (e.ok) _this._handleComplete()
|
|
else _this._handleError(e.body && e.body.code)
|
|
}, _ => _this._handleError());
|
|
const { xhr } = req;
|
|
if (xhr.upload) xhr.upload.onprogress = (...props) => _this._handleXHRProgress(...props);
|
|
xhr.addEventListener('progress', _this._handleXHRProgress, false);
|
|
_this._handleStart(_ => req.abort());
|
|
})
|
|
}
|
|
|
|
async patchUploadModal(promiseState) {
|
|
const Upload = await ReactComponents.getComponentByName('Upload', `.${WebpackModules.getByProps('uploadModal').uploadModal.split(' ')[0]}`);
|
|
if (promiseState.cancelled) return;
|
|
const ParseUtils = WebpackModules.getByProps('parsePreprocessor');
|
|
const WYSIWYGSerializeDeserialize = WebpackModules.getByProps('serialize', 'deserialize');
|
|
const UploadModalUtils = WebpackModules.getByProps('popFirstFile');
|
|
// our own function, just to check if we can send multiple messages at once
|
|
Patcher.instead(Upload.component.prototype, 'canSendBulk', _this => {
|
|
const { channel } = _this.props;
|
|
if (!channel.rateLimitPerUser) return true;
|
|
return Permissions.can(DiscordConstants.Permissions.MANAGE_CHANNELS, channel) || Permissions.can(DiscordConstants.Permissions.MANAGE_MESSAGES, channel);
|
|
});
|
|
// override this function in particular as it's easy to patch and is run after all checks are validated
|
|
// which are @everyone, slowmode, whatnot
|
|
Patcher.instead(Upload.component.prototype, 'submitUpload', (_this, [valid, content, upload, channel, hasSpoiler], orig) => {
|
|
if (!valid || upload === null || !_this.props.hasAdditionalUploads || _this.__MU_onlySingle) return orig(valid, content, upload, channel, hasSpoiler);
|
|
let parsed = ParseUtils.parse(channel, content);
|
|
MessageDraftUtils.saveDraft(channel.id, '');
|
|
_this.setState({
|
|
textFocused: false,
|
|
textValue: '',
|
|
richValue: WYSIWYGSerializeDeserialize.deserialize('')
|
|
});
|
|
|
|
const canSendAll = _this.canSendBulk();
|
|
|
|
// fetch group of files we can send in 1 message
|
|
let files = this.getNextMessageGroup(channel.id);
|
|
// upload them after a set timeout
|
|
const startUpload = e => setTimeout(_ => (UploadUtils.upload(channel.id, files, parsed, hasSpoiler), e && e()), 125);
|
|
if (canSendAll) {
|
|
// if we can send all of them, store the array locally because it'll be cleared at the end of this function
|
|
const uploads = [...this.uploads];
|
|
const start = _ => startUpload(_ => {
|
|
// clear parsed, so we don't send same text multiple times
|
|
parsed = { content: '', invalidEmojis: [], tts: false, validNonShortcutEmojis: [] };
|
|
// remove previously sent files
|
|
uploads.splice(0, files.length);
|
|
if (!uploads.length) return;
|
|
// fetch next group of files we can send in 1 message
|
|
files = this.getNextMessageGroup(channel.id, uploads);
|
|
start();
|
|
});
|
|
start();
|
|
} else startUpload();
|
|
|
|
// replica of the showNextFile function with only slight differences
|
|
if (!canSendAll && files.length !== this.uploads.length) {
|
|
_this.setState({
|
|
transitioning: true
|
|
});
|
|
setTimeout((function () {
|
|
// clear multiple times
|
|
for (let i = 0; i < files.length; i++) UploadModalUtils.popFirstFile();
|
|
}
|
|
), 100);
|
|
_this._transitionTimeout = setTimeout((() => {
|
|
return _this.setState({
|
|
transitioning: false
|
|
})
|
|
}
|
|
), 200);
|
|
} else {
|
|
// clear all instead of one
|
|
UploadModalUtils.clearAll();
|
|
_this.props.onClose();
|
|
}
|
|
});
|
|
Patcher.instead(Upload.component.prototype, '_confirm', (_this, [e]) => {
|
|
_this.__MU_onlySingle = e ? e.shiftKey : false;
|
|
return _this._olConfirm();
|
|
});
|
|
const patchId = _.uniqueId('MultiUploads');
|
|
Patcher.before(Upload.component.prototype, 'renderFooter', _this => {
|
|
if (_this.handleSubmit.__MU_patched === patchId) return;
|
|
if (!_this._olConfirm) _this._olConfirm = _this.confirm;
|
|
_this.confirm = _this._confirm.bind(_this);
|
|
_this.confirm.__MU_patched = patchId;
|
|
});
|
|
Patcher.after(Upload.component.prototype, 'renderFooter', (_this, _, ret) => {
|
|
if (!_this.props.hasAdditionalUploads) return;
|
|
const buttons = Utilities.findInReactTree(ret, e => Array.isArray(e) && e.find(e => e && e.props && e.props.onClick === _this.cancel));
|
|
const uploadButtonProps = Utilities.findInReactTree(buttons, e => e && typeof e.children === 'function');
|
|
if (!uploadButtonProps) return;
|
|
const oChildren = uploadButtonProps.children;
|
|
uploadButtonProps.children = e => {
|
|
try {
|
|
const ret = oChildren(e);
|
|
if (_this.props.hasAdditionalUploads) {
|
|
const uploadButton = Utilities.findInReactTree(ret, e => e && e.onClick === _this.confirm);
|
|
const group = this.getNextMessageGroup(_this.props.channel.id);
|
|
const { props } = uploadButton.children;
|
|
if (group.length === this.uploads.length || _this.canSendBulk()) props.children = 'Upload All';
|
|
else if (group.length > 1) props.children = `Upload ${group.length}`;
|
|
}
|
|
return ret;
|
|
} catch (err) {
|
|
Logger.stacktrace('Failed patching Upload button', err);
|
|
try {
|
|
return oChildren(e);
|
|
} catch (err) {
|
|
Logger.stacktrace('Failed calling original Upload button func', err);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
const promptToUpload = WebpackModules.getByString('.Messages.UPLOAD_AREA_TOO_LARGE_TITLE');
|
|
Patcher.after(Upload.component.prototype, 'render', (_this, _, ret) => {
|
|
const channelTextEditorContainer = Utilities.findInReactTree(ret, e => Utilities.getNestedProp(e, 'type.type.render.displayName') === 'ChannelTextAreaContainer');
|
|
if (!channelTextEditorContainer) return;
|
|
channelTextEditorContainer.props.promptToUpload = promptToUpload;
|
|
})
|
|
Upload.forceUpdateAll();
|
|
}
|
|
|
|
patchInstantBatchUpload() {
|
|
Patcher.instead(UploadUtils, 'instantBatchUpload', (_, [channelId, files], orig) => {
|
|
if (files.length === 1) return orig(channelId, files);
|
|
let fileGroup = this.getNextMessageGroup(channelId, files);
|
|
const startUpload = e => setTimeout(_ => (UploadUtils.upload(channelId, fileGroup), e && e()), 125);
|
|
const uploads = [...files];
|
|
const start = _ => startUpload(_ => {
|
|
uploads.splice(0, fileGroup.length);
|
|
if (!uploads.length) return;
|
|
fileGroup = this.getNextMessageGroup(channelId, uploads);
|
|
start();
|
|
});
|
|
start();
|
|
})
|
|
}
|
|
|
|
getNextMessageGroup(channelId, uploads = this.uploads) {
|
|
const { guild_id } = ChannelStore.getChannel(channelId);
|
|
const maxSize = FileUtils.maxFileSize(guild_id);
|
|
if (!uploads.length) return [];
|
|
const isUpload = !!uploads[0].file;
|
|
const retAccum = [isUpload ? uploads[0].file : uploads[0]];
|
|
let sizeAccum = isUpload ? uploads[0].file.size : uploads[0].size;
|
|
for (let i = 1, len = uploads.length; i < len; i++) {
|
|
const { file } = isUpload ? uploads[i] : { file: uploads[i] };
|
|
if (sizeAccum + file.size > maxSize) break;
|
|
retAccum.push(file);
|
|
sizeAccum += file.size
|
|
if (retAccum.length >= 10) break;
|
|
}
|
|
return retAccum;
|
|
}
|
|
|
|
/* PATCHES */
|
|
|
|
get [Symbol.toStringTag]() {
|
|
return 'Plugin';
|
|
}
|
|
get name() {
|
|
return config.info.name;
|
|
}
|
|
get short() {
|
|
let string = '';
|
|
|
|
for (let i = 0, len = config.info.name.length; i < len; i++) {
|
|
const char = config.info.name[i];
|
|
if (char === char.toUpperCase()) string += char;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
get author() {
|
|
return config.info.authors.map(author => author.name).join(', ');
|
|
}
|
|
get version() {
|
|
return config.info.version;
|
|
}
|
|
get description() {
|
|
return config.info.description;
|
|
}
|
|
};
|
|
};
|
|
|
|
/* Finalize */
|
|
|
|
let ZeresPluginLibraryOutdated = false;
|
|
try {
|
|
const a = (c, a) => ((c = c.split('.').map(b => parseInt(b))), (a = a.split('.').map(b => parseInt(b))), !!(a[0] > c[0])) || !!(a[0] == c[0] && a[1] > c[1]) || !!(a[0] == c[0] && a[1] == c[1] && a[2] > c[2]),
|
|
b = BdApi.Plugins.get('ZeresPluginLibrary');
|
|
((b, c) => b && b._config && b._config.info && b._config.info.version && a(b._config.info.version, c))(b, '1.2.27') && (ZeresPluginLibraryOutdated = !0);
|
|
} catch (e) {
|
|
console.error('Error checking if ZeresPluginLibrary is out of date', e);
|
|
}
|
|
|
|
return !global.ZeresPluginLibrary || ZeresPluginLibraryOutdated || window.BDModules
|
|
? class {
|
|
constructor() {
|
|
this._config = config;
|
|
this.start = this.load = this.handleMissingLib;
|
|
}
|
|
getName() {
|
|
return this.name.replace(/\s+/g, '');
|
|
}
|
|
getAuthor() {
|
|
return this.author;
|
|
}
|
|
getVersion() {
|
|
return this.version;
|
|
}
|
|
getDescription() {
|
|
return this.description + window.BDModules ? '' : 'You are missing ZeresPluginLibrary for this plugin, please enable the plugin and click Download Now.';
|
|
}
|
|
start() { }
|
|
stop() { }
|
|
handleMissingLib() {
|
|
if (window.BDModules) return;
|
|
const a = BdApi.findModuleByProps('openModal', 'hasModalOpen');
|
|
if (a && a.hasModalOpen(`${this.name}_DEP_MODAL`)) return;
|
|
const b = !global.ZeresPluginLibrary,
|
|
c = ZeresPluginLibraryOutdated ? 'Outdated Library' : 'Missing Library',
|
|
d = `The Library ZeresPluginLibrary required for ${this.name} is ${ZeresPluginLibraryOutdated ? 'outdated' : 'missing'}.`,
|
|
e = BdApi.findModuleByDisplayName('Text'),
|
|
f = BdApi.findModuleByDisplayName('ConfirmModal'),
|
|
g = () => BdApi.alert(c, BdApi.React.createElement('span', {}, BdApi.React.createElement('div', {}, d), `Due to a slight mishap however, you'll have to download the libraries yourself. This is not intentional, something went wrong, errors are in console.`, b || ZeresPluginLibraryOutdated ? BdApi.React.createElement('div', {}, BdApi.React.createElement('a', { href: 'https://betterdiscord.net/ghdl?id=2252', target: '_blank' }, 'Click here to download ZeresPluginLibrary')) : null));
|
|
if (!a || !f || !e) return console.error(`Missing components:${(a ? '' : ' ModalStack') + (f ? '' : ' ConfirmationModalComponent') + (e ? '' : 'TextElement')}`), g();
|
|
class h extends BdApi.React.PureComponent {
|
|
constructor(a) {
|
|
super(a), (this.state = { hasError: !1 });
|
|
}
|
|
componentDidCatch(a) {
|
|
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);
|
|
}
|
|
render() {
|
|
return this.state.hasError ? null : this.props.children;
|
|
}
|
|
}
|
|
let i = !1,
|
|
j = !1;
|
|
const k = a.openModal(
|
|
b => {
|
|
if (j) return null;
|
|
try {
|
|
return BdApi.React.createElement(
|
|
h,
|
|
{
|
|
label: 'missing dependency modal',
|
|
onError: () => {
|
|
a.closeModal(k), g();
|
|
}
|
|
},
|
|
BdApi.React.createElement(
|
|
f,
|
|
Object.assign(
|
|
{
|
|
header: c,
|
|
children: BdApi.React.createElement(e, { size: e.Sizes.SIZE_16, children: [`${d} Please click Download Now to download it.`] }),
|
|
red: !1,
|
|
confirmText: 'Download Now',
|
|
cancelText: 'Cancel',
|
|
onCancel: b.onClose,
|
|
onConfirm: () => {
|
|
if (i) return;
|
|
i = !0;
|
|
const b = require('request'),
|
|
c = require('fs'),
|
|
d = require('path');
|
|
b('https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js', (b, e, f) => {
|
|
try {
|
|
if (b || 200 !== e.statusCode) return a.closeModal(k), g();
|
|
c.writeFile(d.join(BdApi.Plugins && BdApi.Plugins.folder ? BdApi.Plugins.folder : window.ContentManager.pluginsFolder, '0PluginLibrary.plugin.js'), f, () => { });
|
|
} catch (b) {
|
|
console.error('Fatal error downloading ZeresPluginLibrary', b), a.closeModal(k), g();
|
|
}
|
|
});
|
|
}
|
|
},
|
|
b,
|
|
{ onClose: () => { } }
|
|
)
|
|
)
|
|
);
|
|
} catch (b) {
|
|
return console.error('There has been an error constructing the modal', b), (j = !0), a.closeModal(k), g(), null;
|
|
}
|
|
},
|
|
{ modalKey: `${this.name}_DEP_MODAL` }
|
|
);
|
|
}
|
|
get [Symbol.toStringTag]() {
|
|
return 'Plugin';
|
|
}
|
|
get name() {
|
|
return config.info.name;
|
|
}
|
|
get short() {
|
|
let string = '';
|
|
for (let i = 0, len = config.info.name.length; i < len; i++) {
|
|
const char = config.info.name[i];
|
|
if (char === char.toUpperCase()) string += char;
|
|
}
|
|
return string;
|
|
}
|
|
get author() {
|
|
return config.info.authors.map(author => author.name).join(', ');
|
|
}
|
|
get version() {
|
|
return config.info.version;
|
|
}
|
|
get description() {
|
|
return config.info.description;
|
|
}
|
|
}
|
|
: buildPlugin(global.ZeresPluginLibrary.buildPlugin(config));
|
|
})();
|
|
|
|
/*@end@*/
|