2019-05-28 23:27:25 +02:00
|
|
|
import Utilities from "./utilities";
|
2019-05-30 07:06:17 +02:00
|
|
|
import WebpackModules, {DiscordModules} from "./webpackmodules";
|
2019-05-28 23:27:25 +02:00
|
|
|
import DataStore from "./datastore";
|
2019-05-31 07:53:11 +02:00
|
|
|
import {Toasts, Modals} from "ui";
|
2019-05-28 23:27:25 +02:00
|
|
|
|
|
|
|
const BdApi = {
|
2019-05-30 07:06:17 +02:00
|
|
|
get React() { return DiscordModules.React; },
|
|
|
|
get ReactDOM() { return DiscordModules.ReactDOM; },
|
2019-05-28 20:19:48 +02:00
|
|
|
get WindowConfigFile() {
|
|
|
|
if (this._windowConfigFile) return this._windowConfigFile;
|
2019-05-30 07:06:17 +02:00
|
|
|
const electron = require("electron").remote.app;
|
2019-05-28 20:19:48 +02:00
|
|
|
const path = require("path");
|
2019-05-30 07:06:17 +02:00
|
|
|
const base = electron.getAppPath();
|
|
|
|
const roamingBase = electron.getPath("userData");
|
|
|
|
const roamingLocation = path.resolve(roamingBase, electron.getVersion(), "modules", "discord_desktop_core", "injector", "config.json");
|
2019-05-28 20:19:48 +02:00
|
|
|
const location = path.resolve(base, "..", "app", "config.json");
|
|
|
|
const fs = require("fs");
|
2019-05-30 07:06:17 +02:00
|
|
|
const realLocation = fs.existsSync(location) ? location : fs.existsSync(roamingLocation) ? roamingLocation : null;
|
|
|
|
if (!realLocation) return this._windowConfigFile = null;
|
|
|
|
return this._windowConfigFile = realLocation;
|
2019-05-28 20:19:48 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.getAllWindowPreferences = function() {
|
2019-05-30 07:06:17 +02:00
|
|
|
if (!this.WindowConfigFile) return {};
|
2019-05-28 23:27:25 +02:00
|
|
|
return __non_webpack_require__(this.WindowConfigFile);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.getWindowPreference = function(key) {
|
2019-05-30 07:06:17 +02:00
|
|
|
if (!this.WindowConfigFile) return undefined;
|
2019-05-28 20:19:48 +02:00
|
|
|
return this.getAllWindowPreferences()[key];
|
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.setWindowPreference = function(key, value) {
|
2019-05-30 07:06:17 +02:00
|
|
|
if (!this.WindowConfigFile) return;
|
2019-05-28 20:19:48 +02:00
|
|
|
const fs = require("fs");
|
|
|
|
const prefs = this.getAllWindowPreferences();
|
|
|
|
prefs[key] = value;
|
|
|
|
delete require.cache[this.WindowConfigFile];
|
|
|
|
fs.writeFileSync(this.WindowConfigFile, JSON.stringify(prefs, null, 4));
|
|
|
|
};
|
|
|
|
|
|
|
|
//Inject CSS to document head
|
|
|
|
//id = id of element
|
|
|
|
//css = custom css
|
|
|
|
BdApi.injectCSS = function (id, css) {
|
2019-05-28 23:27:25 +02:00
|
|
|
$("head").append($("<style>", {id: Utilities.escapeID(id), text: css}));
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
//Clear css/remove any element
|
|
|
|
//id = id of element
|
|
|
|
BdApi.clearCSS = function (id) {
|
2019-05-28 23:27:25 +02:00
|
|
|
$("#" + Utilities.escapeID(id)).remove();
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
//Inject CSS to document head
|
|
|
|
//id = id of element
|
|
|
|
//css = custom css
|
|
|
|
BdApi.linkJS = function (id, url) {
|
2019-05-28 23:27:25 +02:00
|
|
|
$("head").append($("<script>", {id: Utilities.escapeID(id), src: url, type: "text/javascript"}));
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
//Clear css/remove any element
|
|
|
|
//id = id of element
|
|
|
|
BdApi.unlinkJS = function (id) {
|
2019-05-28 23:27:25 +02:00
|
|
|
$("#" + Utilities.escapeID(id)).remove();
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows a generic but very customizable modal.
|
|
|
|
* @param {string} title - title of the modal
|
|
|
|
* @param {string} content - a string of text to display in the modal
|
|
|
|
*/
|
|
|
|
BdApi.alert = function (title, content) {
|
2019-05-31 07:53:11 +02:00
|
|
|
Modals.alert(title, content);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows a generic but very customizable confirmation modal with optional confirm and cancel callbacks.
|
|
|
|
* @param {string} title - title of the modal
|
|
|
|
* @param {(string|ReactElement|Array<string|ReactElement>)} children - a single or mixed array of react elements and strings. Everything is wrapped in Discord's `TextElement` component so strings will show and render properly.
|
|
|
|
* @param {object} [options] - options to modify the modal
|
|
|
|
* @param {boolean} [options.danger=false] - whether the main button should be red or not
|
|
|
|
* @param {string} [options.confirmText=Okay] - text for the confirmation/submit button
|
|
|
|
* @param {string} [options.cancelText=Cancel] - text for the cancel button
|
|
|
|
* @param {callable} [options.onConfirm=NOOP] - callback to occur when clicking the submit button
|
|
|
|
* @param {callable} [options.onCancel=NOOP] - callback to occur when clicking the cancel button
|
|
|
|
*/
|
|
|
|
BdApi.showConfirmationModal = function (title, content, options = {}) {
|
2019-05-31 07:53:11 +02:00
|
|
|
return Modals.showConfirmationModal(title, content, options);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
2019-06-03 22:25:08 +02:00
|
|
|
/**
|
|
|
|
* This shows a toast similar to android towards the bottom of the screen.
|
|
|
|
*
|
|
|
|
* @param {string} content The string to show in the toast.
|
|
|
|
* @param {object} options Options object. Optional parameter.
|
|
|
|
* @param {string} [options.type=""] Changes the type of the toast stylistically and semantically. Choices: "", "info", "success", "danger"/"error", "warning"/"warn". Default: ""
|
|
|
|
* @param {boolean} [options.icon=true] Determines whether the icon should show corresponding to the type. A toast without type will always have no icon. Default: true
|
|
|
|
* @param {number} [options.timeout=3000] Adjusts the time (in ms) the toast should be shown for before disappearing automatically. Default: 3000
|
|
|
|
* @param {boolean} [options.forceShow=false] Whether to force showing the toast and ignore the bd setting
|
|
|
|
*/
|
2019-05-28 20:19:48 +02:00
|
|
|
BdApi.showToast = function(content, options = {}) {
|
2019-05-31 07:53:11 +02:00
|
|
|
Toasts.show(content, options);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Finds module
|
|
|
|
BdApi.findModule = function(filter) {
|
2019-05-30 07:06:17 +02:00
|
|
|
return WebpackModules.getModule(filter);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Finds module
|
|
|
|
BdApi.findAllModules = function(filter) {
|
2019-05-30 07:06:17 +02:00
|
|
|
return WebpackModules.getModule(filter, false);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Finds module
|
|
|
|
BdApi.findModuleByProps = function(...props) {
|
2019-05-30 07:06:17 +02:00
|
|
|
return WebpackModules.getByProps(...props);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.findModuleByPrototypes = function(...protos) {
|
2019-05-30 07:06:17 +02:00
|
|
|
return WebpackModules.getByPrototypes(...protos);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.findModuleByDisplayName = function(name) {
|
2019-05-30 07:06:17 +02:00
|
|
|
return WebpackModules.getByDisplayName(name);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Gets react instance
|
|
|
|
BdApi.getInternalInstance = function(node) {
|
|
|
|
if (!(node instanceof window.jQuery) && !(node instanceof Element)) return undefined;
|
|
|
|
if (node instanceof jQuery) node = node[0];
|
2019-05-30 07:06:17 +02:00
|
|
|
return Utilities.getInternalInstance(node);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Gets data
|
|
|
|
BdApi.loadData = function(pluginName, key) {
|
|
|
|
return DataStore.getPluginData(pluginName, key);
|
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.getData = BdApi.loadData;
|
|
|
|
|
|
|
|
// Sets data
|
|
|
|
BdApi.saveData = function(pluginName, key, data) {
|
|
|
|
return DataStore.setPluginData(pluginName, key, data);
|
|
|
|
};
|
|
|
|
|
|
|
|
BdApi.setData = BdApi.saveData;
|
|
|
|
|
|
|
|
// Deletes data
|
|
|
|
BdApi.deleteData = function(pluginName, key) {
|
|
|
|
return DataStore.deletePluginData(pluginName, key);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Patches other functions
|
|
|
|
BdApi.monkeyPatch = function(what, methodName, options) {
|
2019-05-28 23:27:25 +02:00
|
|
|
return Utilities.monkeyPatch(what, methodName, options);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Event when element is removed
|
|
|
|
BdApi.onRemoved = function(node, callback) {
|
2019-05-28 23:27:25 +02:00
|
|
|
return Utilities.onRemoved(node, callback);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Wraps function in try..catch
|
|
|
|
BdApi.suppressErrors = function(method, message) {
|
2019-05-28 23:27:25 +02:00
|
|
|
return Utilities.suppressErrors(method, message);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Tests for valid JSON
|
|
|
|
BdApi.testJSON = function(data) {
|
2019-05-28 23:27:25 +02:00
|
|
|
return Utilities.testJSON(data);
|
2019-05-28 20:19:48 +02:00
|
|
|
};
|
|
|
|
|
2019-06-08 08:35:43 +02:00
|
|
|
//Get another plugin
|
|
|
|
//name = name of plugin
|
|
|
|
// BdApi.getPlugin = function (name) {
|
|
|
|
// if (Plugins.hasOwnProperty(name)) {
|
|
|
|
// return Plugins[name].plugin;
|
|
|
|
// }
|
|
|
|
// return null;
|
|
|
|
// };
|
|
|
|
|
|
|
|
// BdApi.isPluginEnabled = function(name) {
|
|
|
|
// return !!PluginCookie[name];
|
|
|
|
// };
|
|
|
|
|
|
|
|
// BdApi.isThemeEnabled = function(name) {
|
|
|
|
// return !!ThemeCookie[name];
|
|
|
|
// };
|
|
|
|
|
|
|
|
// BdApi.isSettingEnabled = function(id) {
|
|
|
|
// return !!SettingsCookie[id];
|
|
|
|
// };
|
2019-05-28 20:19:48 +02:00
|
|
|
|
|
|
|
// Gets data
|
|
|
|
BdApi.getBDData = function(key) {
|
|
|
|
return DataStore.getBDData(key);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Sets data
|
|
|
|
BdApi.setBDData = function(key, data) {
|
|
|
|
return DataStore.setBDData(key, data);
|
2019-05-28 23:27:25 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
export default BdApi;
|