start to convert emotemenu
This commit is contained in:
parent
e06d2d9d9e
commit
b64f35fa88
|
@ -19,7 +19,7 @@
|
||||||
"semi": 2,
|
"semi": 2,
|
||||||
"space-infix-ops": ["error", {"int32Hint": false}],
|
"space-infix-ops": ["error", {"int32Hint": false}],
|
||||||
"quotes": ["error", "double", {"allowTemplateLiterals": true}],
|
"quotes": ["error", "double", {"allowTemplateLiterals": true}],
|
||||||
"no-console": 0,
|
"no-console": 2,
|
||||||
"brace-style": ["error", "stroustrup", {"allowSingleLine": true}],
|
"brace-style": ["error", "stroustrup", {"allowSingleLine": true}],
|
||||||
"keyword-spacing": 2,
|
"keyword-spacing": 2,
|
||||||
"no-else-return": 2,
|
"no-else-return": 2,
|
||||||
|
|
16
css/main.css
16
css/main.css
|
@ -308,7 +308,7 @@
|
||||||
|
|
||||||
#bda-qem-twitch-container, #bda-qem-favourite-container {
|
#bda-qem-twitch-container, #bda-qem-favourite-container {
|
||||||
width: 346px;
|
width: 346px;
|
||||||
height: 327px;
|
height: 329px;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
border-radius: 0 0 5px 5px;
|
border-radius: 0 0 5px 5px;
|
||||||
}
|
}
|
||||||
|
@ -739,12 +739,12 @@ body .ace_closeButton {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
body .ace_closeButton::before {
|
body .ace_closeButton::before {
|
||||||
content: "✖";
|
content: "✖";
|
||||||
color: #36393f;
|
color: #36393f;
|
||||||
}
|
}
|
||||||
|
|
||||||
body .ace_closeButton:active {
|
body .ace_closeButton:active {
|
||||||
transform: translateY(2px);
|
transform: translateY(2px);
|
||||||
}
|
}
|
||||||
|
@ -1780,11 +1780,11 @@ body .ace_closeButton:active {
|
||||||
border-color: #202020;
|
border-color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar,
|
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar,
|
||||||
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar-track,
|
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar-track,
|
||||||
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar-track-piece,
|
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar-track-piece,
|
||||||
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar,
|
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar,
|
||||||
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar-track,
|
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar-track,
|
||||||
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar-track-piece,
|
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar-track-piece,
|
||||||
.bda-dark .emojiPicker-3m1S-j .scroller-3vODG7::-webkit-scrollbar,
|
.bda-dark .emojiPicker-3m1S-j .scroller-3vODG7::-webkit-scrollbar,
|
||||||
.bda-dark .emojiPicker-3m1S-j .scroller-3vODG7::-webkit-scrollbar-track,
|
.bda-dark .emojiPicker-3m1S-j .scroller-3vODG7::-webkit-scrollbar-track,
|
||||||
|
@ -1793,7 +1793,7 @@ body .ace_closeButton:active {
|
||||||
border-color: #303030 !important;
|
border-color: #303030 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar-thumb,
|
.bda-dark #bda-qem-twitch-container .scroller::-webkit-scrollbar-thumb,
|
||||||
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar-thumb,
|
.bda-dark #bda-qem-favourite-container .scroller::-webkit-scrollbar-thumb,
|
||||||
.bda-dark .emojiPicker-3g68GS .scroller-3vODG7::-webkit-scrollbar-thumb {
|
.bda-dark .emojiPicker-3g68GS .scroller-3vODG7::-webkit-scrollbar-thumb {
|
||||||
border-color: #202020 !important;
|
border-color: #202020 !important;
|
||||||
|
|
1454
js/main.js
1454
js/main.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -5,4 +5,6 @@ export {default as PublicServers} from "./publicservers";
|
||||||
export {default as DarkMode} from "./darkmode";
|
export {default as DarkMode} from "./darkmode";
|
||||||
export {default as MinimalMode} from "./minimalmode";
|
export {default as MinimalMode} from "./minimalmode";
|
||||||
export {default as TwentyFourHour} from "./24hour";
|
export {default as TwentyFourHour} from "./24hour";
|
||||||
export {default as ColoredText} from "./coloredtext";
|
export {default as ColoredText} from "./coloredtext";
|
||||||
|
export {default as VoiceDisconnect} from "./voicedisconnect";
|
||||||
|
export {default as EmoteMenu} from "./emotemenu";
|
|
@ -0,0 +1,204 @@
|
||||||
|
import Builtin, {onSettingChange} from "../structs/builtin";
|
||||||
|
import {SettingsCookie, Emotes} from "data";
|
||||||
|
import {DataStore, Utilities, Events} from "modules";
|
||||||
|
|
||||||
|
const headerHTML = `<div id="bda-qem">
|
||||||
|
<button class="active" id="bda-qem-twitch">Twitch</button>
|
||||||
|
<button id="bda-qem-favourite">Favourite</button>
|
||||||
|
<button id="bda-qem-emojis">Emojis</buttond>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
const twitchEmoteHTML = `<div id="bda-qem-twitch-container">
|
||||||
|
<div class="scroller-wrap scrollerWrap-2lJEkd fade">
|
||||||
|
<div class="scroller scroller-2FKFPG">
|
||||||
|
<div class="emote-menu-inner">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
const favoritesHTML = `<div id="bda-qem-favourite-container">
|
||||||
|
<div class="scroller-wrap scrollerWrap-2lJEkd fade">
|
||||||
|
<div class="scroller scroller-2FKFPG">
|
||||||
|
<div class="emote-menu-inner">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
const makeEmote = (emote, url, options = {}) => {
|
||||||
|
const {onContextMenu, onClick} = options;
|
||||||
|
const emoteContainer = $(`<div class="emote-container">
|
||||||
|
<img class="emote-icon" alt="${emote}" src="${url}" title="${emote}">
|
||||||
|
</div>`)[0];
|
||||||
|
if (onContextMenu) emoteContainer.addEventListener("contextmenu", onContextMenu);
|
||||||
|
emoteContainer.addEventListener("click", onClick);
|
||||||
|
return emoteContainer;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default new class EmoteMenu extends Builtin {
|
||||||
|
get name() {return "EmoteMenu";}
|
||||||
|
get category() {return "Modules";}
|
||||||
|
get id() {return "bda-es-0";}
|
||||||
|
get hideEmojisID() {return "bda-es-9";}
|
||||||
|
get hideEmojis() {return SettingsCookie[this.hideEmojisID];}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.lastTab = "bda-qem-emojis";
|
||||||
|
this.favoriteEmotes = {};
|
||||||
|
|
||||||
|
this.qmeHeader = $(headerHTML)[0];
|
||||||
|
for (const button of this.qmeHeader.getElementsByTagName("button")) button.addEventListener("click", this.switchMenu.bind(this));
|
||||||
|
|
||||||
|
this.teContainer = $(twitchEmoteHTML)[0];
|
||||||
|
this.teContainerInner = this.teContainer.querySelector(".emote-menu-inner");
|
||||||
|
|
||||||
|
this.faContainer = $(favoritesHTML)[0];
|
||||||
|
this.faContainerInner = this.faContainer.querySelector(".emote-menu-inner");
|
||||||
|
|
||||||
|
this.observer = new MutationObserver(mutations => {for (const mutation of mutations) this.observe(mutation);});
|
||||||
|
this.enableHideEmojis = this.enableHideEmojis.bind(this);
|
||||||
|
this.disableHideEmojis = this.disableHideEmojis.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
super.initialize();
|
||||||
|
const fe = DataStore.getBDData("bdfavemotes");
|
||||||
|
if (fe !== "" && fe !== null) this.favoriteEmotes = JSON.parse(atob(fe));
|
||||||
|
this.updateFavorites();
|
||||||
|
}
|
||||||
|
|
||||||
|
async enabled() {
|
||||||
|
await new Promise(resolve => {
|
||||||
|
Events.on("emotes-loaded", resolve);
|
||||||
|
});
|
||||||
|
this.updateTwitchEmotes();
|
||||||
|
this.log("Starting to observe");
|
||||||
|
this.observer.observe(document.getElementById("app-mount"), {
|
||||||
|
childList: true,
|
||||||
|
subtree: true
|
||||||
|
});
|
||||||
|
this.hideEmojiCancel = onSettingChange(this.category, this.hideEmojisID, this.enableHideEmojis, this.disableHideEmojis);
|
||||||
|
if (this.hideEmojis) this.enableHideEmojis();
|
||||||
|
}
|
||||||
|
|
||||||
|
disabled() {
|
||||||
|
this.observer.disconnect();
|
||||||
|
this.disableHideEmojis();
|
||||||
|
if (this.hideEmojiCancel) this.hideEmojiCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
enableHideEmojis() {
|
||||||
|
$(".emojiPicker-3m1S-j").addClass("bda-qme-hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
disableHideEmojis() {
|
||||||
|
$(".emojiPicker-3m1S-j").removeClass("bda-qme-hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
insertEmote(emote) {
|
||||||
|
const ta = Utilities.getTextArea();
|
||||||
|
Utilities.insertText(ta[0], ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote);
|
||||||
|
}
|
||||||
|
|
||||||
|
favContext(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
const em = e.target.closest(".emote-container").children[0];
|
||||||
|
const menu = $(`<div id="removemenu" class="bd-context-menu context-menu theme-dark">Remove</div>`);
|
||||||
|
menu.css({
|
||||||
|
top: e.pageY - $("#bda-qem-favourite-container").offset().top,
|
||||||
|
left: e.pageX - $("#bda-qem-favourite-container").offset().left
|
||||||
|
});
|
||||||
|
$(em).parent().append(menu);
|
||||||
|
menu.on("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
$(em).remove();
|
||||||
|
delete this.favoriteEmotes[$(em).attr("title")];
|
||||||
|
this.updateFavorites();
|
||||||
|
$(document).off("mousedown.emotemenu");
|
||||||
|
});
|
||||||
|
$(document).on("mousedown.emotemenu", function(e) {
|
||||||
|
if (e.target.id == "removemenu") return;
|
||||||
|
$("#removemenu").remove();
|
||||||
|
$(document).off("mousedown.emotemenu");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
switchMenu(e) {
|
||||||
|
let id = typeof(e) == "string" ? e : $(e.target).attr("id");
|
||||||
|
if (id == "bda-qem-emojis" && this.hideEmojis) id = "bda-qem-favourite";
|
||||||
|
const twitch = $("#bda-qem-twitch");
|
||||||
|
const fav = $("#bda-qem-favourite");
|
||||||
|
const emojis = $("#bda-qem-emojis");
|
||||||
|
twitch.removeClass("active");
|
||||||
|
fav.removeClass("active");
|
||||||
|
emojis.removeClass("active");
|
||||||
|
|
||||||
|
$(".emojiPicker-3m1S-j").hide();
|
||||||
|
$("#bda-qem-favourite-container").hide();
|
||||||
|
$("#bda-qem-twitch-container").hide();
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case "bda-qem-twitch":
|
||||||
|
twitch.addClass("active");
|
||||||
|
$("#bda-qem-twitch-container").show();
|
||||||
|
break;
|
||||||
|
case "bda-qem-favourite":
|
||||||
|
fav.addClass("active");
|
||||||
|
$("#bda-qem-favourite-container").show();
|
||||||
|
break;
|
||||||
|
case "bda-qem-emojis":
|
||||||
|
emojis.addClass("active");
|
||||||
|
$(".emojiPicker-3m1S-j").show();
|
||||||
|
$(".emojiPicker-3m1S-j input").focus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (id) this.lastTab = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
observe(mutation) {
|
||||||
|
if (!mutation.addedNodes.length || !(mutation.addedNodes[0] instanceof Element)) return;
|
||||||
|
const node = mutation.addedNodes[0];
|
||||||
|
if (!node.classList.contains("popout-3sVMXz") || node.classList.contains("popoutLeft-30WmrD") || !node.getElementsByClassName("emojiPicker-3m1S-j").length) return;
|
||||||
|
|
||||||
|
const e = $(node);
|
||||||
|
if (this.hideEmojis) e.addClass("bda-qme-hidden");
|
||||||
|
else e.removeClass("bda-qme-hidden");
|
||||||
|
|
||||||
|
e.prepend(this.qmeHeader);
|
||||||
|
e.append(this.teContainer);
|
||||||
|
e.append(this.faContainer);
|
||||||
|
|
||||||
|
this.switchMenu(this.lastTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
favorite(name, url) {
|
||||||
|
if (!this.favoriteEmotes.hasOwnProperty(name)) this.favoriteEmotes[name] = url;
|
||||||
|
this.updateFavorites();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTwitchEmotes() {
|
||||||
|
while (this.teContainerInner.firstChild) this.teContainerInner.firstChild.remove();
|
||||||
|
for (const emote in Emotes.TwitchGlobal) {
|
||||||
|
if (!Emotes.TwitchGlobal.hasOwnProperty(emote)) continue;
|
||||||
|
const url = Emotes.TwitchGlobal[emote];
|
||||||
|
const emoteElement = makeEmote(emote, url, {onClick: this.insertEmote.bind(this, emote)});
|
||||||
|
this.teContainerInner.append(emoteElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFavorites() {
|
||||||
|
while (this.faContainerInner.firstChild) this.faContainerInner.firstChild.remove();
|
||||||
|
for (const emote in this.favoriteEmotes) {
|
||||||
|
const url = this.favoriteEmotes[emote];
|
||||||
|
const emoteElement = makeEmote(emote, url, {onClick: this.insertEmote.bind(this, emote), onContextMenu: this.favContext.bind(this)});
|
||||||
|
this.faContainerInner.append(emoteElement);
|
||||||
|
}
|
||||||
|
DataStore.setBDData("bdfavemotes", btoa(JSON.stringify(this.favoriteEmotes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -43,7 +43,6 @@ export default new class PublicServers extends Builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// BdApi.alert("Broken", "Sorry but the Public Servers modules is currently broken, I recommend disabling this feature for now.");
|
|
||||||
const root = this.root;
|
const root = this.root;
|
||||||
if (!root) {
|
if (!root) {
|
||||||
console.log("FAILED TO LOCATE ROOT: .layers");
|
console.log("FAILED TO LOCATE ROOT: .layers");
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import Builtin from "../structs/builtin";
|
||||||
|
import {DiscordModules} from "modules";
|
||||||
|
|
||||||
|
export default new class DarkMode extends Builtin {
|
||||||
|
get name() {return "VoiceDisconnect";}
|
||||||
|
get category() {return "Modules";}
|
||||||
|
get id() {return "bda-dc-0";}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.beforeUnload = this.beforeUnload.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled() {
|
||||||
|
window.addEventListener("beforeunload", this.beforeUnload);
|
||||||
|
}
|
||||||
|
|
||||||
|
disabled() {
|
||||||
|
window.removeEventListener("beforeunload", this.beforeUnload);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeUnload() {
|
||||||
|
DiscordModules.ChannelActions.selectVoiceChannel(null, null);
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
import {SettingsCookie, SettingsInfo, PluginCookie, ThemeCookie, Plugins, Themes, Emotes, EmoteBlacklist} from "data";
|
import {SettingsCookie, SettingsInfo, Config, PluginCookie, ThemeCookie, Plugins, Themes, Emotes, EmoteBlacklist} from "data";
|
||||||
import proxyLocalStorage from "./localstorage";
|
import proxyLocalStorage from "./localstorage";
|
||||||
import Core from "./modules/core";
|
import Core from "./modules/core";
|
||||||
import BdApi from "./modules/pluginapi";
|
import BdApi from "./modules/pluginapi";
|
||||||
|
@ -27,7 +27,10 @@ window.bdplugins = Plugins;
|
||||||
window.bdEmotes = Emotes;
|
window.bdEmotes = Emotes;
|
||||||
window.bemotes = EmoteBlacklist;
|
window.bemotes = EmoteBlacklist;
|
||||||
window.bdPluginStorage = bdPluginStorage;
|
window.bdPluginStorage = bdPluginStorage;
|
||||||
|
|
||||||
|
|
||||||
window.BDEvents = Events;
|
window.BDEvents = Events;
|
||||||
|
window.bdConfig = Config;
|
||||||
|
|
||||||
export default class CoreWrapper {
|
export default class CoreWrapper {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
|
|
|
@ -85,4 +85,12 @@ export default new class {
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// lc = WebpackModules.getByDisplayName("FluxContainer(Layers)")
|
||||||
|
// Patcher.after(lc.prototype, "render", (t,a,r) => {console.log(t,a,r);})
|
||||||
|
// return.type
|
||||||
|
// Patcher.after(temp3.prototype, "renderLayers", (t,a,r) => {
|
||||||
|
// console.log(t,a,r);
|
||||||
|
// if (t.props.layers.includes("USER_SETTINGS")) r[1].props.className = "user-settings-prop";
|
||||||
|
// })
|
|
@ -2,15 +2,13 @@ import BDV2 from "./bdv2";
|
||||||
import Utilities from "./utilities";
|
import Utilities from "./utilities";
|
||||||
import {Config, SettingsCookie} from "data";
|
import {Config, SettingsCookie} from "data";
|
||||||
import EmoteModule from "./emotes";
|
import EmoteModule from "./emotes";
|
||||||
import QuickEmoteMenu from "./emotemenu";
|
// import QuickEmoteMenu from "../builtins/emotemenu";
|
||||||
// import VoiceMode from "./voicemode";
|
|
||||||
// import DevMode from "./devmode";
|
|
||||||
import PluginManager from "./pluginmanager";
|
import PluginManager from "./pluginmanager";
|
||||||
import ThemeManager from "./thememanager";
|
import ThemeManager from "./thememanager";
|
||||||
import DataStore from "./datastore";
|
|
||||||
// import PublicServers from "./publicservers";
|
|
||||||
import SettingsPanel from "./settingspanel";
|
import SettingsPanel from "./settingspanel";
|
||||||
import * as Builtins from "builtins";
|
import * as Builtins from "builtins";
|
||||||
|
import {Modals} from "ui";
|
||||||
|
import Events from "./emitter";
|
||||||
|
|
||||||
function Core() {
|
function Core() {
|
||||||
}
|
}
|
||||||
|
@ -21,25 +19,26 @@ Core.prototype.setConfig = function(config) {
|
||||||
|
|
||||||
Core.prototype.init = async function() {
|
Core.prototype.init = async function() {
|
||||||
if (Config.version < Config.minSupportedVersion) {
|
if (Config.version < Config.minSupportedVersion) {
|
||||||
this.alert("Not Supported", "BetterDiscord v" + Config.version + " (your version)" + " is not supported by the latest js (" + Config.bbdVersion + ").<br><br> Please download the latest version from <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>GitHub</a>");
|
Modals.alert("Not Supported", "BetterDiscord v" + Config.version + " (your version)" + " is not supported by the latest js (" + Config.bbdVersion + ").<br><br> Please download the latest version from <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>GitHub</a>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
|
const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
|
||||||
if (latestLocalVersion > Config.version) {
|
if (latestLocalVersion > Config.version) {
|
||||||
this.alert("Update Available", `
|
Modals.alert("Update Available", `
|
||||||
An update for BandagedBD is available (${latestLocalVersion})! Please Reinstall!<br /><br />
|
An update for BandagedBD is available (${latestLocalVersion})! Please Reinstall!<br /><br />
|
||||||
<a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>Download Installer</a>
|
<a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>Download Installer</a>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utilities.log("Startup", "Initializing Settings");
|
Utilities.log("Startup", "Initializing Settings");
|
||||||
this.initSettings();
|
SettingsPanel.initialize();
|
||||||
Utilities.log("Startup", "Initializing EmoteModule");
|
Utilities.log("Startup", "Initializing EmoteModule");
|
||||||
window.emotePromise = EmoteModule.init().then(() => {
|
window.emotePromise = EmoteModule.init().then(() => {
|
||||||
EmoteModule.initialized = true;
|
EmoteModule.initialized = true;
|
||||||
Utilities.log("Startup", "Initializing QuickEmoteMenu");
|
Utilities.log("Startup", "Initializing QuickEmoteMenu");
|
||||||
QuickEmoteMenu.init();
|
Events.dispatch("emotes-loaded");
|
||||||
|
// QuickEmoteMenu.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.injectExternals();
|
this.injectExternals();
|
||||||
|
@ -58,10 +57,6 @@ Core.prototype.init = async function() {
|
||||||
|
|
||||||
$("#customcss").detach().appendTo(document.head);
|
$("#customcss").detach().appendTo(document.head);
|
||||||
|
|
||||||
window.addEventListener("beforeunload", function() {
|
|
||||||
if (SettingsCookie["bda-dc-0"]) document.querySelector(".btn.btn-disconnect").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
// PublicServers.initialize();
|
// PublicServers.initialize();
|
||||||
EmoteModule.autoCapitalize();
|
EmoteModule.autoCapitalize();
|
||||||
|
|
||||||
|
@ -73,13 +68,8 @@ Core.prototype.init = async function() {
|
||||||
// Show loading errors
|
// Show loading errors
|
||||||
if (SettingsCookie["fork-ps-1"]) {
|
if (SettingsCookie["fork-ps-1"]) {
|
||||||
Utilities.log("Startup", "Collecting Startup Errors");
|
Utilities.log("Startup", "Collecting Startup Errors");
|
||||||
this.showContentErrors({plugins: pluginErrors, themes: themeErrors});
|
Modals.showContentErrors({plugins: pluginErrors, themes: themeErrors});
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!DataStore.getBDData(bbdVersion)) {
|
|
||||||
// BdApi.alert("BBD Updated!", ["Lots of things were fixed in this update like Public Servers, Minimal Mode, Dark Mode and 24 Hour Timestamps.", BdApi.React.createElement("br"), BdApi.React.createElement("br"), "Feel free to test them all out!"]);
|
|
||||||
// DataStore.setBDData(bbdVersion, true);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Core.prototype.checkForGuilds = function() {
|
Core.prototype.checkForGuilds = function() {
|
||||||
|
@ -102,26 +92,6 @@ Core.prototype.injectExternals = async function() {
|
||||||
if (window.require.original) window.require = window.require.original;
|
if (window.require.original) window.require = window.require.original;
|
||||||
};
|
};
|
||||||
|
|
||||||
Core.prototype.initSettings = function () {
|
|
||||||
DataStore.initialize();
|
|
||||||
if (!DataStore.getSettingGroup("settings")) return this.saveSettings();
|
|
||||||
const savedSettings = this.loadSettings();
|
|
||||||
$("<style id=\"customcss\">").text(atob(DataStore.getBDData("bdcustomcss"))).appendTo(document.head);
|
|
||||||
for (const setting in savedSettings) {
|
|
||||||
if (savedSettings[setting] !== undefined) SettingsCookie[setting] = savedSettings[setting];
|
|
||||||
}
|
|
||||||
this.saveSettings();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Core.prototype.saveSettings = function () {
|
|
||||||
DataStore.setSettingGroup("settings", SettingsCookie);
|
|
||||||
};
|
|
||||||
|
|
||||||
Core.prototype.loadSettings = function () {
|
|
||||||
return DataStore.getSettingGroup("settings");
|
|
||||||
};
|
|
||||||
|
|
||||||
Core.prototype.initObserver = function () {
|
Core.prototype.initObserver = function () {
|
||||||
const mainObserver = new MutationObserver((mutations) => {
|
const mainObserver = new MutationObserver((mutations) => {
|
||||||
|
|
||||||
|
@ -143,10 +113,6 @@ Core.prototype.initObserver = function () {
|
||||||
if (!document.getElementById("bd-settings-sidebar")) SettingsPanel.renderSidebar();
|
if (!document.getElementById("bd-settings-sidebar")) SettingsPanel.renderSidebar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emoji Picker
|
|
||||||
if (node.classList.contains("popout-3sVMXz") && !node.classList.contains("popoutLeft-30WmrD") && node.getElementsByClassName("emojiPicker-3m1S-j").length) QuickEmoteMenu.obsCallback(node);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -156,147 +122,5 @@ Core.prototype.initObserver = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Core.prototype.alert = function(title, content) {
|
|
||||||
const modal = $(`<div class="bd-modal-wrapper theme-dark">
|
|
||||||
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
|
||||||
<div class="bd-modal modal-1UGdnR">
|
|
||||||
<div class="bd-modal-inner inner-1JeGVc">
|
|
||||||
<div class="header header-1R_AjF">
|
|
||||||
<div class="title">${title}</div>
|
|
||||||
</div>
|
|
||||||
<div class="bd-modal-body">
|
|
||||||
<div class="scroller-wrap fade">
|
|
||||||
<div class="scroller">
|
|
||||||
${content}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footer footer-2yfCgX">
|
|
||||||
<button type="button">Okay</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`);
|
|
||||||
modal.find(".footer button").on("click", () => {
|
|
||||||
modal.addClass("closing");
|
|
||||||
setTimeout(() => { modal.remove(); }, 300);
|
|
||||||
});
|
|
||||||
modal.find(".bd-backdrop").on("click", () => {
|
|
||||||
modal.addClass("closing");
|
|
||||||
setTimeout(() => { modal.remove(); }, 300);
|
|
||||||
});
|
|
||||||
modal.appendTo("#app-mount");
|
|
||||||
};
|
|
||||||
|
|
||||||
Core.prototype.showContentErrors = function({plugins: pluginErrors = [], themes: themeErrors = []}) {
|
|
||||||
if (!pluginErrors || !themeErrors) return;
|
|
||||||
if (!pluginErrors.length && !themeErrors.length) return;
|
|
||||||
const modal = $(`<div class="bd-modal-wrapper theme-dark">
|
|
||||||
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
|
||||||
<div class="bd-modal bd-content-modal modal-1UGdnR">
|
|
||||||
<div class="bd-modal-inner inner-1JeGVc">
|
|
||||||
<div class="header header-1R_AjF"><div class="title">Content Errors</div></div>
|
|
||||||
<div class="bd-modal-body">
|
|
||||||
<div class="tab-bar-container">
|
|
||||||
<div class="tab-bar TOP">
|
|
||||||
<div class="tab-bar-item">Plugins</div>
|
|
||||||
<div class="tab-bar-item">Themes</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="table-header">
|
|
||||||
<div class="table-column column-name">Name</div>
|
|
||||||
<div class="table-column column-message">Message</div>
|
|
||||||
<div class="table-column column-error">Error</div>
|
|
||||||
</div>
|
|
||||||
<div class="scroller-wrap fade">
|
|
||||||
<div class="scroller">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footer footer-2yfCgX">
|
|
||||||
<button type="button">Okay</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`);
|
|
||||||
|
|
||||||
function generateTab(errors) {
|
|
||||||
const container = $(`<div class="errors">`);
|
|
||||||
for (const err of errors) {
|
|
||||||
const error = $(`<div class="error">
|
|
||||||
<div class="table-column column-name">${err.name ? err.name : err.file}</div>
|
|
||||||
<div class="table-column column-message">${err.message}</div>
|
|
||||||
<div class="table-column column-error"><a class="error-link" href="">${err.error ? err.error.message : ""}</a></div>
|
|
||||||
</div>`);
|
|
||||||
container.append(error);
|
|
||||||
if (err.error) {
|
|
||||||
error.find("a").on("click", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
Utilities.err("ContentManager", `Error details for ${err.name ? err.name : err.file}.`, err.error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tabs = [generateTab(pluginErrors), generateTab(themeErrors)];
|
|
||||||
|
|
||||||
modal.find(".tab-bar-item").on("click", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
modal.find(".tab-bar-item").removeClass("selected");
|
|
||||||
$(e.target).addClass("selected");
|
|
||||||
modal.find(".scroller").empty().append(tabs[$(e.target).index()]);
|
|
||||||
});
|
|
||||||
|
|
||||||
modal.find(".footer button").on("click", () => {
|
|
||||||
modal.addClass("closing");
|
|
||||||
setTimeout(() => { modal.remove(); }, 300);
|
|
||||||
});
|
|
||||||
modal.find(".bd-backdrop").on("click", () => {
|
|
||||||
modal.addClass("closing");
|
|
||||||
setTimeout(() => { modal.remove(); }, 300);
|
|
||||||
});
|
|
||||||
modal.appendTo("#app-mount");
|
|
||||||
if (pluginErrors.length) modal.find(".tab-bar-item")[0].click();
|
|
||||||
else modal.find(".tab-bar-item")[1].click();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 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 Adjusts the time (in ms) the toast should be shown for before disappearing automatically. Default: 3000
|
|
||||||
*/
|
|
||||||
Core.prototype.showToast = function(content, options = {}) {
|
|
||||||
if (!Config.deferLoaded) return;
|
|
||||||
if (!document.querySelector(".bd-toasts")) {
|
|
||||||
const toastWrapper = document.createElement("div");
|
|
||||||
toastWrapper.classList.add("bd-toasts");
|
|
||||||
const boundingElement = document.querySelector(".chat-3bRxxu form, #friends, .noChannel-Z1DQK7, .activityFeed-28jde9");
|
|
||||||
toastWrapper.style.setProperty("left", boundingElement ? boundingElement.getBoundingClientRect().left + "px" : "0px");
|
|
||||||
toastWrapper.style.setProperty("width", boundingElement ? boundingElement.offsetWidth + "px" : "100%");
|
|
||||||
toastWrapper.style.setProperty("bottom", (document.querySelector(".chat-3bRxxu form") ? document.querySelector(".chat-3bRxxu form").offsetHeight : 80) + "px");
|
|
||||||
document.querySelector(".app, .app-2rEoOp").appendChild(toastWrapper);
|
|
||||||
}
|
|
||||||
const {type = "", icon = true, timeout = 3000} = options;
|
|
||||||
const toastElem = document.createElement("div");
|
|
||||||
toastElem.classList.add("bd-toast");
|
|
||||||
if (type) toastElem.classList.add("toast-" + type);
|
|
||||||
if (type && icon) toastElem.classList.add("icon");
|
|
||||||
toastElem.innerText = content;
|
|
||||||
document.querySelector(".bd-toasts").appendChild(toastElem);
|
|
||||||
setTimeout(() => {
|
|
||||||
toastElem.classList.add("closing");
|
|
||||||
setTimeout(() => {
|
|
||||||
toastElem.remove();
|
|
||||||
if (!document.querySelectorAll(".bd-toasts .bd-toast").length) document.querySelector(".bd-toasts").remove();
|
|
||||||
}, 300);
|
|
||||||
}, timeout);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export default new Core();
|
export default new Core();
|
|
@ -1,5 +1,5 @@
|
||||||
import {Config} from "data";
|
import {Config} from "data";
|
||||||
import BdApi from "./pluginapi";
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const releaseChannel = DiscordNative.globals.releaseChannel;
|
const releaseChannel = DiscordNative.globals.releaseChannel;
|
||||||
|
@ -11,20 +11,15 @@ export default new class DataStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
try {
|
if (!fs.existsSync(this.BDFile)) fs.writeFileSync(this.BDFile, JSON.stringify(this.data, null, 4));
|
||||||
if (!fs.existsSync(this.BDFile)) fs.writeFileSync(this.BDFile, JSON.stringify(this.data, null, 4));
|
const data = __non_webpack_require__(this.BDFile);
|
||||||
const data = __non_webpack_require__(this.BDFile);
|
if (data.hasOwnProperty("settings")) this.data = data;
|
||||||
if (data.hasOwnProperty("settings")) this.data = data;
|
if (!fs.existsSync(this.settingsFile)) return;
|
||||||
if (!fs.existsSync(this.settingsFile)) return;
|
let settings = __non_webpack_require__(this.settingsFile);
|
||||||
let settings = __non_webpack_require__(this.settingsFile);
|
fs.unlinkSync(this.settingsFile);
|
||||||
fs.unlinkSync(this.settingsFile);
|
if (settings.hasOwnProperty("settings")) settings = Object.assign({stable: {}, canary: {}, ptb: {}}, {[releaseChannel]: settings});
|
||||||
if (settings.hasOwnProperty("settings")) settings = Object.assign({stable: {}, canary: {}, ptb: {}}, {[releaseChannel]: settings});
|
else settings = Object.assign({stable: {}, canary: {}, ptb: {}}, settings);
|
||||||
else settings = Object.assign({stable: {}, canary: {}, ptb: {}}, settings);
|
this.setBDData("settings", settings);
|
||||||
this.setBDData("settings", settings);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
BdApi.alert("Corrupt Storage", "The bd storage has somehow become corrupt. You may either try to salvage the file or delete it then reload.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get BDFile() {return this._BDFile || (this._BDFile = path.resolve(Config.dataPath, "bdstorage.json"));}
|
get BDFile() {return this._BDFile || (this._BDFile = path.resolve(Config.dataPath, "bdstorage.json"));}
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
/**
|
|
||||||
* A large list of known and useful webpack modules internal to Discord.
|
|
||||||
* Click the source link down below to view more info. Otherwise, if you
|
|
||||||
* have the library installed or have a plugin using this library,
|
|
||||||
* do `Object.keys(ZLibrary.DiscordModules)` in console for a list of modules.
|
|
||||||
* @module DiscordModules
|
|
||||||
* @version 0.0.3
|
|
||||||
*/
|
|
||||||
import Utilities from "./utilities";
|
|
||||||
import WebpackModules from "./webpackmodules";
|
|
||||||
|
|
||||||
export default Utilities.memoizeObject({
|
|
||||||
get React() {return WebpackModules.getByProps("createElement", "cloneElement");},
|
|
||||||
get ReactDOM() {return WebpackModules.getByProps("render", "findDOMNode");},
|
|
||||||
get Flux() {return WebpackModules.getByProps("connectStores");},
|
|
||||||
get Events() {return WebpackModules.getByPrototypes("setMaxListeners", "emit");},
|
|
||||||
|
|
||||||
/* Guild Info, Stores, and Utilities */
|
|
||||||
get GuildStore() {return WebpackModules.getByProps("getGuild");},
|
|
||||||
get SortedGuildStore() {return WebpackModules.getByProps("getSortedGuilds");},
|
|
||||||
get SelectedGuildStore() {return WebpackModules.getByProps("getLastSelectedGuildId");},
|
|
||||||
get GuildSync() {return WebpackModules.getByProps("getSyncedGuilds");},
|
|
||||||
get GuildInfo() {return WebpackModules.getByProps("getAcronym");},
|
|
||||||
get GuildChannelsStore() {return WebpackModules.getByProps("getChannels", "getDefaultChannel");},
|
|
||||||
get GuildMemberStore() {return WebpackModules.getByProps("getMember");},
|
|
||||||
get MemberCountStore() {return WebpackModules.getByProps("getMemberCounts");},
|
|
||||||
get GuildEmojiStore() {return WebpackModules.getByProps("getEmojis");},
|
|
||||||
get GuildActions() {return WebpackModules.getByProps("markGuildAsRead");},
|
|
||||||
get GuildPermissions() {return WebpackModules.getByProps("getGuildPermissions");},
|
|
||||||
|
|
||||||
/* Channel Store & Actions */
|
|
||||||
get ChannelStore() {return WebpackModules.getByProps("getChannels", "getDMFromUserId");},
|
|
||||||
get SelectedChannelStore() {return WebpackModules.getByProps("getLastSelectedChannelId");},
|
|
||||||
get ChannelActions() {return WebpackModules.getByProps("selectChannel");},
|
|
||||||
get PrivateChannelActions() {return WebpackModules.getByProps("openPrivateChannel");},
|
|
||||||
get ChannelSelector() {return WebpackModules.getByProps("selectGuild", "selectChannel");},
|
|
||||||
|
|
||||||
/* Current User Info, State and Settings */
|
|
||||||
get UserInfoStore() {return WebpackModules.getByProps("getToken");},
|
|
||||||
get UserSettingsStore() {return WebpackModules.getByProps("guildPositions");},
|
|
||||||
get AccountManager() {return WebpackModules.getByProps("register", "login");},
|
|
||||||
get UserSettingsUpdater() {return WebpackModules.getByProps("updateRemoteSettings");},
|
|
||||||
get OnlineWatcher() {return WebpackModules.getByProps("isOnline");},
|
|
||||||
get CurrentUserIdle() {return WebpackModules.getByProps("getIdleTime");},
|
|
||||||
get RelationshipStore() {return WebpackModules.getByProps("isBlocked", "getFriendIDs");},
|
|
||||||
get RelationshipManager() {return WebpackModules.getByProps("addRelationship");},
|
|
||||||
get MentionStore() {return WebpackModules.getByProps("getMentions");},
|
|
||||||
|
|
||||||
/* User Stores and Utils */
|
|
||||||
get UserStore() {return WebpackModules.getByProps("getCurrentUser");},
|
|
||||||
get UserStatusStore() {return WebpackModules.getByProps("getStatus", "getState");},
|
|
||||||
get UserTypingStore() {return WebpackModules.getByProps("isTyping");},
|
|
||||||
get UserActivityStore() {return WebpackModules.getByProps("getActivity");},
|
|
||||||
get UserNameResolver() {return WebpackModules.getByProps("getName");},
|
|
||||||
get UserNoteStore() {return WebpackModules.getByProps("getNote");},
|
|
||||||
get UserNoteActions() {return WebpackModules.getByProps("updateNote");},
|
|
||||||
|
|
||||||
/* Emoji Store and Utils */
|
|
||||||
get EmojiInfo() {return WebpackModules.getByProps("isEmojiDisabled");},
|
|
||||||
get EmojiUtils() {return WebpackModules.getByProps("getGuildEmoji");},
|
|
||||||
get EmojiStore() {return WebpackModules.getByProps("getByCategory", "EMOJI_NAME_RE");},
|
|
||||||
|
|
||||||
/* Invite Store and Utils */
|
|
||||||
get InviteStore() {return WebpackModules.getByProps("getInvites");},
|
|
||||||
get InviteResolver() {return WebpackModules.getByProps("findInvite");},
|
|
||||||
get InviteActions() {return WebpackModules.getByProps("acceptInvite");},
|
|
||||||
|
|
||||||
/* Discord Objects & Utils */
|
|
||||||
get DiscordConstants() {return WebpackModules.getByProps("Permissions", "ActivityTypes", "StatusTypes");},
|
|
||||||
get DiscordPermissions() {return WebpackModules.getByProps("Permissions", "ActivityTypes", "StatusTypes").Permissions;},
|
|
||||||
get PermissionUtils() {return WebpackModules.getByProps("getHighestRole");},
|
|
||||||
get ColorConverter() {return WebpackModules.getByProps("hex2int");},
|
|
||||||
get ColorShader() {return WebpackModules.getByProps("darken");},
|
|
||||||
get TinyColor() {return WebpackModules.getByPrototypes("toRgb");},
|
|
||||||
get ClassResolver() {return WebpackModules.getByProps("getClass");},
|
|
||||||
get ButtonData() {return WebpackModules.getByProps("ButtonSizes");},
|
|
||||||
get IconNames() {return WebpackModules.getByProps("IconNames");},
|
|
||||||
get NavigationUtils() {return WebpackModules.getByProps("transitionTo", "replaceWith", "getHistory");},
|
|
||||||
|
|
||||||
/* Discord Messages */
|
|
||||||
get MessageStore() {return WebpackModules.getByProps("getMessages");},
|
|
||||||
get MessageActions() {return WebpackModules.getByProps("jumpToMessage", "_sendMessage");},
|
|
||||||
get MessageQueue() {return WebpackModules.getByProps("enqueue");},
|
|
||||||
get MessageParser() {return WebpackModules.getByProps("createMessage", "parse", "unparse");},
|
|
||||||
|
|
||||||
/* Text Processing */
|
|
||||||
get hljs() {return WebpackModules.getByProps("highlight", "highlightBlock");},
|
|
||||||
get SimpleMarkdown() {return WebpackModules.getByProps("parseBlock", "parseInline", "defaultOutput");},
|
|
||||||
|
|
||||||
/* Experiments */
|
|
||||||
get ExperimentStore() {return WebpackModules.getByProps("getExperimentOverrides");},
|
|
||||||
get ExperimentsManager() {return WebpackModules.getByProps("isDeveloper");},
|
|
||||||
get CurrentExperiment() {return WebpackModules.getByProps("getExperimentId");},
|
|
||||||
|
|
||||||
/* Images, Avatars and Utils */
|
|
||||||
get ImageResolver() {return WebpackModules.getByProps("getUserAvatarURL", "getGuildIconURL");},
|
|
||||||
get ImageUtils() {return WebpackModules.getByProps("getSizedImageSrc");},
|
|
||||||
get AvatarDefaults() {return WebpackModules.getByProps("getUserAvatarURL", "DEFAULT_AVATARS");},
|
|
||||||
|
|
||||||
/* Window, DOM, HTML */
|
|
||||||
get WindowInfo() {return WebpackModules.getByProps("isFocused", "windowSize");},
|
|
||||||
get TagInfo() {return WebpackModules.getByProps("VALID_TAG_NAMES");},
|
|
||||||
get DOMInfo() {return WebpackModules.getByProps("canUseDOM");},
|
|
||||||
|
|
||||||
/* Locale/Location and Time */
|
|
||||||
get LocaleManager() {return WebpackModules.getByProps("setLocale");},
|
|
||||||
get Moment() {return WebpackModules.getByProps("parseZone");},
|
|
||||||
get LocationManager() {return WebpackModules.getByProps("createLocation");},
|
|
||||||
get Timestamps() {return WebpackModules.getByProps("fromTimestamp");},
|
|
||||||
|
|
||||||
/* Strings and Utils */
|
|
||||||
get Strings() {return WebpackModules.getByProps("Messages").Messages;},
|
|
||||||
get StringFormats() {return WebpackModules.getByProps("a", "z");},
|
|
||||||
get StringUtils() {return WebpackModules.getByProps("toASCII");},
|
|
||||||
|
|
||||||
/* URLs and Utils */
|
|
||||||
get URLParser() {return WebpackModules.getByProps("Url", "parse");},
|
|
||||||
get ExtraURLs() {return WebpackModules.getByProps("getArticleURL");},
|
|
||||||
|
|
||||||
/* Drag & Drop */
|
|
||||||
get DNDActions() {return WebpackModules.getByProps("beginDrag");},
|
|
||||||
get DNDSources() {return WebpackModules.getByProps("addTarget");},
|
|
||||||
get DNDObjects() {return WebpackModules.getByProps("DragSource");},
|
|
||||||
|
|
||||||
/* Media Stuff (Audio/Video) */
|
|
||||||
get MediaDeviceInfo() {return WebpackModules.getByProps("Codecs", "SUPPORTED_BROWSERS");},
|
|
||||||
get MediaInfo() {return WebpackModules.getByProps("getOutputVolume");},
|
|
||||||
get MediaEngineInfo() {return WebpackModules.getByProps("MediaEngineFeatures");},
|
|
||||||
get VoiceInfo() {return WebpackModules.getByProps("EchoCancellation");},
|
|
||||||
get VideoStream() {return WebpackModules.getByProps("getVideoStream");},
|
|
||||||
get SoundModule() {return WebpackModules.getByProps("playSound");},
|
|
||||||
|
|
||||||
/* Electron & Other Internals with Utils*/
|
|
||||||
get ElectronModule() {return WebpackModules.getByProps("setBadge");},
|
|
||||||
get Dispatcher() {return WebpackModules.getByProps("dirtyDispatch");},
|
|
||||||
get PathUtils() {return WebpackModules.getByProps("hasBasename");},
|
|
||||||
get NotificationModule() {return WebpackModules.getByProps("showNotification");},
|
|
||||||
get RouterModule() {return WebpackModules.getByProps("Router");},
|
|
||||||
get APIModule() {return WebpackModules.getByProps("getAPIBaseURL");},
|
|
||||||
get AnalyticEvents() {return WebpackModules.getByProps("AnalyticEventConfigs");},
|
|
||||||
get KeyGenerator() {return WebpackModules.getByRegex(/"binary"/);},
|
|
||||||
get Buffers() {return WebpackModules.getByProps("Buffer", "kMaxLength");},
|
|
||||||
get DeviceStore() {return WebpackModules.getByProps("getDevices");},
|
|
||||||
get SoftwareInfo() {return WebpackModules.getByProps("os");},
|
|
||||||
get CurrentContext() {return WebpackModules.getByProps("setTagsContext");}
|
|
||||||
});
|
|
|
@ -1,5 +1,9 @@
|
||||||
const EventEmitter = require("events");
|
const EventEmitter = require("events");
|
||||||
export default new class BDEvents extends EventEmitter {
|
export default new class BDEvents extends EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.setMaxListeners(20);
|
||||||
|
}
|
||||||
dispatch(eventName, ...args) {
|
dispatch(eventName, ...args) {
|
||||||
this.emit(eventName, ...args);
|
this.emit(eventName, ...args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
import {SettingsCookie, Emotes} from "data";
|
|
||||||
import DataStore from "./datastore";
|
|
||||||
import Utilities from "./utilities";
|
|
||||||
|
|
||||||
function QuickEmoteMenu() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.init = function() {
|
|
||||||
this.initialized = true;
|
|
||||||
$(document).on("mousedown", function(e) {
|
|
||||||
if (e.target.id != "rmenu") $("#rmenu").remove();
|
|
||||||
});
|
|
||||||
this.favoriteEmotes = {};
|
|
||||||
const fe = DataStore.getBDData("bdfavemotes");
|
|
||||||
if (fe !== "" && fe !== null) {
|
|
||||||
this.favoriteEmotes = JSON.parse(atob(fe));
|
|
||||||
}
|
|
||||||
|
|
||||||
let qmeHeader = "";
|
|
||||||
qmeHeader += "<div id=\"bda-qem\">";
|
|
||||||
qmeHeader += " <button class=\"active\" id=\"bda-qem-twitch\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Twitch</button>";
|
|
||||||
qmeHeader += " <button id=\"bda-qem-favourite\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Favourite</button>";
|
|
||||||
qmeHeader += " <button id=\"bda-qem-emojis\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Emojis</buttond>";
|
|
||||||
qmeHeader += "</div>";
|
|
||||||
this.qmeHeader = qmeHeader;
|
|
||||||
|
|
||||||
let teContainer = "";
|
|
||||||
teContainer += "<div id=\"bda-qem-twitch-container\">";
|
|
||||||
teContainer += " <div class=\"scroller-wrap scrollerWrap-2lJEkd fade\">";
|
|
||||||
teContainer += " <div class=\"scroller scroller-2FKFPG\">";
|
|
||||||
teContainer += " <div class=\"emote-menu-inner\">";
|
|
||||||
let url = "";
|
|
||||||
for (const emote in Emotes.TwitchGlobal) {
|
|
||||||
if (Emotes.TwitchGlobal.hasOwnProperty(emote)) {
|
|
||||||
url = Emotes.TwitchGlobal[emote];
|
|
||||||
teContainer += "<div class=\"emote-container\">";
|
|
||||||
teContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\">";
|
|
||||||
teContainer += " </img>";
|
|
||||||
teContainer += "</div>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
teContainer += " </div>";
|
|
||||||
teContainer += " </div>";
|
|
||||||
teContainer += " </div>";
|
|
||||||
teContainer += "</div>";
|
|
||||||
this.teContainer = teContainer;
|
|
||||||
|
|
||||||
let faContainer = "";
|
|
||||||
faContainer += "<div id=\"bda-qem-favourite-container\">";
|
|
||||||
faContainer += " <div class=\"scroller-wrap scrollerWrap-2lJEkd fade\">";
|
|
||||||
faContainer += " <div class=\"scroller scroller-2FKFPG\">";
|
|
||||||
faContainer += " <div class=\"emote-menu-inner\">";
|
|
||||||
for (const emote in this.favoriteEmotes) {
|
|
||||||
url = this.favoriteEmotes[emote];
|
|
||||||
faContainer += "<div class=\"emote-container\">";
|
|
||||||
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>";
|
|
||||||
faContainer += " </img>";
|
|
||||||
faContainer += "</div>";
|
|
||||||
}
|
|
||||||
faContainer += " </div>";
|
|
||||||
faContainer += " </div>";
|
|
||||||
faContainer += " </div>";
|
|
||||||
faContainer += "</div>";
|
|
||||||
this.faContainer = faContainer;
|
|
||||||
};
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.favContext = function(e, em) {
|
|
||||||
e.stopPropagation();
|
|
||||||
const menu = $("<div>", {"id": "removemenu", "data-emoteid": $(em).prop("title"), "text": "Remove", "class": "bd-context-menu context-menu theme-dark"});
|
|
||||||
menu.css({
|
|
||||||
top: e.pageY - $("#bda-qem-favourite-container").offset().top,
|
|
||||||
left: e.pageX - $("#bda-qem-favourite-container").offset().left
|
|
||||||
});
|
|
||||||
$(em).parent().append(menu);
|
|
||||||
menu.on("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
$(this).remove();
|
|
||||||
|
|
||||||
delete this.favoriteEmotes[$(this).data("emoteid")];
|
|
||||||
this.updateFavorites();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.switchHandler = function(e) {
|
|
||||||
this.switchQem($(e).attr("id"));
|
|
||||||
};
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.switchQem = function(id) {
|
|
||||||
const twitch = $("#bda-qem-twitch");
|
|
||||||
const fav = $("#bda-qem-favourite");
|
|
||||||
const emojis = $("#bda-qem-emojis");
|
|
||||||
twitch.removeClass("active");
|
|
||||||
fav.removeClass("active");
|
|
||||||
emojis.removeClass("active");
|
|
||||||
|
|
||||||
$(".emojiPicker-3m1S-j").hide();
|
|
||||||
$("#bda-qem-favourite-container").hide();
|
|
||||||
$("#bda-qem-twitch-container").hide();
|
|
||||||
|
|
||||||
switch (id) {
|
|
||||||
case "bda-qem-twitch":
|
|
||||||
twitch.addClass("active");
|
|
||||||
$("#bda-qem-twitch-container").show();
|
|
||||||
break;
|
|
||||||
case "bda-qem-favourite":
|
|
||||||
fav.addClass("active");
|
|
||||||
$("#bda-qem-favourite-container").show();
|
|
||||||
break;
|
|
||||||
case "bda-qem-emojis":
|
|
||||||
emojis.addClass("active");
|
|
||||||
$(".emojiPicker-3m1S-j").show();
|
|
||||||
$(".emojiPicker-3m1S-j .search-bar-inner input, .emojiPicker-3m1S-j .search-bar-inner input").focus();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.lastTab = id;
|
|
||||||
|
|
||||||
const emoteIcon = $(".emote-icon");
|
|
||||||
emoteIcon.off();
|
|
||||||
emoteIcon.on("click", function () {
|
|
||||||
const emote = $(this).attr("title");
|
|
||||||
const ta = Utilities.getTextArea();
|
|
||||||
Utilities.insertText(ta[0], ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.obsCallback = function (elem) {
|
|
||||||
if (!this.initialized) return;
|
|
||||||
const e = $(elem);
|
|
||||||
if (!SettingsCookie["bda-es-9"]) {
|
|
||||||
e.addClass("bda-qme-hidden");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
e.removeClass("bda-qme-hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SettingsCookie["bda-es-0"]) return;
|
|
||||||
|
|
||||||
e.prepend(this.qmeHeader);
|
|
||||||
e.append(this.teContainer);
|
|
||||||
e.append(this.faContainer);
|
|
||||||
|
|
||||||
if (this.lastTab == undefined) {
|
|
||||||
this.lastTab = "bda-qem-emojis";
|
|
||||||
}
|
|
||||||
this.switchQem(this.lastTab);
|
|
||||||
};
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.favorite = function (name, url) {
|
|
||||||
|
|
||||||
if (!this.favoriteEmotes.hasOwnProperty(name)) {
|
|
||||||
this.favoriteEmotes[name] = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateFavorites();
|
|
||||||
};
|
|
||||||
|
|
||||||
QuickEmoteMenu.prototype.updateFavorites = function () {
|
|
||||||
|
|
||||||
let faContainer = "";
|
|
||||||
faContainer += "<div id=\"bda-qem-favourite-container\">";
|
|
||||||
faContainer += " <div class=\"scroller-wrap scrollerWrap-2lJEkd fade\">";
|
|
||||||
faContainer += " <div class=\"scroller scroller-2FKFPG\">";
|
|
||||||
faContainer += " <div class=\"emote-menu-inner\">";
|
|
||||||
for (const emote in this.favoriteEmotes) {
|
|
||||||
const url = this.favoriteEmotes[emote];
|
|
||||||
faContainer += "<div class=\"emote-container\">";
|
|
||||||
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\" oncontextmenu=\"quickEmoteMenu.favContext(event, this);\">";
|
|
||||||
faContainer += " </img>";
|
|
||||||
faContainer += "</div>";
|
|
||||||
}
|
|
||||||
faContainer += " </div>";
|
|
||||||
faContainer += " </div>";
|
|
||||||
faContainer += " </div>";
|
|
||||||
faContainer += "</div>";
|
|
||||||
this.faContainer = faContainer;
|
|
||||||
|
|
||||||
$("#bda-qem-favourite-container").replaceWith(faContainer);
|
|
||||||
DataStore.setBDData("bdfavemotes", btoa(JSON.stringify(this.favoriteEmotes)));
|
|
||||||
};
|
|
||||||
|
|
||||||
export default new QuickEmoteMenu();
|
|
|
@ -5,6 +5,7 @@ import BDEmote from "../ui/emote";
|
||||||
import BdApi from "./pluginapi";
|
import BdApi from "./pluginapi";
|
||||||
import DataStore from "./datastore";
|
import DataStore from "./datastore";
|
||||||
import {DiscordModules} from "./webpackmodules";
|
import {DiscordModules} from "./webpackmodules";
|
||||||
|
import {Toasts} from "ui";
|
||||||
|
|
||||||
const bdEmoteSettingIDs = {
|
const bdEmoteSettingIDs = {
|
||||||
TwitchGlobal: "bda-es-7",
|
TwitchGlobal: "bda-es-7",
|
||||||
|
@ -192,7 +193,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) {
|
||||||
const exists = _fs.existsSync(file);
|
const exists = _fs.existsSync(file);
|
||||||
|
|
||||||
if (exists && this.isCacheValid()) {
|
if (exists && this.isCacheValid()) {
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast("Loading emotes from cache.", {type: "info"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show("Loading emotes from cache.", {type: "info"});
|
||||||
Utilities.log("Emotes", "Loading emotes from local cache.");
|
Utilities.log("Emotes", "Loading emotes from local cache.");
|
||||||
|
|
||||||
const data = await new Promise(resolve => {
|
const data = await new Promise(resolve => {
|
||||||
|
@ -211,7 +212,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast("Emotes successfully loaded.", {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show("Emotes successfully loaded.", {type: "success"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +221,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SettingsCookie["fork-es-3"]) return;
|
if (!SettingsCookie["fork-es-3"]) return;
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast("Downloading emotes in the background do not reload.", {type: "info"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show("Downloading emotes in the background do not reload.", {type: "info"});
|
||||||
|
|
||||||
for (const e in emoteInfo) {
|
for (const e in emoteInfo) {
|
||||||
await new Promise(r => setTimeout(r, 1000));
|
await new Promise(r => setTimeout(r, 1000));
|
||||||
|
@ -228,7 +229,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) {
|
||||||
Emotes[emoteInfo[e].variable] = data;
|
Emotes[emoteInfo[e].variable] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast("All emotes successfully downloaded.", {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show("All emotes successfully downloaded.", {type: "success"});
|
||||||
|
|
||||||
try { _fs.writeFileSync(file, JSON.stringify(Emotes), "utf8"); }
|
try { _fs.writeFileSync(file, JSON.stringify(Emotes), "utf8"); }
|
||||||
catch (err) { Utilities.err("Emotes", "Could not save emote data.", err); }
|
catch (err) { Utilities.err("Emotes", "Could not save emote data.", err); }
|
||||||
|
|
|
@ -11,7 +11,6 @@ import ContentManager from "./contentmanager";
|
||||||
import DataStore from "./datastore";
|
import DataStore from "./datastore";
|
||||||
// import DevMode from "./devmode";
|
// import DevMode from "./devmode";
|
||||||
import Events from "./emitter";
|
import Events from "./emitter";
|
||||||
import EmoteMenu from "./emotemenu";
|
|
||||||
import EmoteModule from "./emotes";
|
import EmoteModule from "./emotes";
|
||||||
import PluginManager from "./pluginmanager";
|
import PluginManager from "./pluginmanager";
|
||||||
// import PublicServers from "./publicservers";
|
// import PublicServers from "./publicservers";
|
||||||
|
@ -21,7 +20,7 @@ export const React = DiscordModules.React;
|
||||||
export const ReactDOM = DiscordModules.ReactDOM;
|
export const ReactDOM = DiscordModules.ReactDOM;
|
||||||
|
|
||||||
export {BDV2, BdApi, Core, ContentManager, DataStore,
|
export {BDV2, BdApi, Core, ContentManager, DataStore,
|
||||||
Events, EmoteMenu, EmoteModule, PluginManager, /*PublicServers,*/ ThemeManager,
|
Events, EmoteModule, PluginManager, /*PublicServers,*/ ThemeManager,
|
||||||
Utilities, WebpackModules, DiscordModules};
|
Utilities, WebpackModules, DiscordModules};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {Plugins, SettingsCookie, PluginCookie, ThemeCookie} from "data";
|
||||||
import Utilities from "./utilities";
|
import Utilities from "./utilities";
|
||||||
import WebpackModules, {DiscordModules} from "./webpackmodules";
|
import WebpackModules, {DiscordModules} from "./webpackmodules";
|
||||||
import DataStore from "./datastore";
|
import DataStore from "./datastore";
|
||||||
import Core from "./core";
|
import {Toasts, Modals} from "ui";
|
||||||
|
|
||||||
const BdApi = {
|
const BdApi = {
|
||||||
get React() { return DiscordModules.React; },
|
get React() { return DiscordModules.React; },
|
||||||
|
@ -76,28 +76,13 @@ BdApi.getPlugin = function (name) {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Get BetterDiscord Core
|
|
||||||
BdApi.getCore = function () {
|
|
||||||
return Core;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a generic but very customizable modal.
|
* Shows a generic but very customizable modal.
|
||||||
* @param {string} title - title of the modal
|
* @param {string} title - title of the modal
|
||||||
* @param {string} content - a string of text to display in the modal
|
* @param {string} content - a string of text to display in the modal
|
||||||
*/
|
*/
|
||||||
BdApi.alert = function (title, content) {
|
BdApi.alert = function (title, content) {
|
||||||
const ModalStack = BdApi.findModuleByProps("push", "update", "pop", "popWithKey");
|
Modals.alert(title, content);
|
||||||
const AlertModal = BdApi.findModuleByPrototypes("handleCancel", "handleSubmit", "handleMinorConfirm");
|
|
||||||
if (!ModalStack || !AlertModal) return Core.alert(title, content);
|
|
||||||
|
|
||||||
ModalStack.push(function(props) {
|
|
||||||
return BdApi.React.createElement(AlertModal, Object.assign({
|
|
||||||
title: title,
|
|
||||||
body: content,
|
|
||||||
}, props));
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,33 +97,12 @@ BdApi.alert = function (title, content) {
|
||||||
* @param {callable} [options.onCancel=NOOP] - callback to occur when clicking the cancel button
|
* @param {callable} [options.onCancel=NOOP] - callback to occur when clicking the cancel button
|
||||||
*/
|
*/
|
||||||
BdApi.showConfirmationModal = function (title, content, options = {}) {
|
BdApi.showConfirmationModal = function (title, content, options = {}) {
|
||||||
const ModalStack = BdApi.findModuleByProps("push", "update", "pop", "popWithKey");
|
return Modals.showConfirmationModal(title, content, options);
|
||||||
const TextElement = BdApi.findModuleByProps("Sizes", "Weights");
|
|
||||||
const ConfirmationModal = BdApi.findModule(m => m.defaultProps && m.key && m.key() == "confirm-modal");
|
|
||||||
if (!ModalStack || !ConfirmationModal || !TextElement) return Core.alert(title, content);
|
|
||||||
|
|
||||||
const {onConfirm, onCancel, confirmText, cancelText, danger = false} = options;
|
|
||||||
if (typeof(content) == "string") content = TextElement({color: TextElement.Colors.PRIMARY, children: [content]});
|
|
||||||
else if (Array.isArray(content)) content = TextElement({color: TextElement.Colors.PRIMARY, children: content});
|
|
||||||
content = [content];
|
|
||||||
|
|
||||||
const emptyFunction = () => {};
|
|
||||||
ModalStack.push(function(props) {
|
|
||||||
return BdApi.React.createElement(ConfirmationModal, Object.assign({
|
|
||||||
header: title,
|
|
||||||
children: content,
|
|
||||||
red: danger,
|
|
||||||
confirmText: confirmText ? confirmText : "Okay",
|
|
||||||
cancelText: cancelText ? cancelText : "Cancel",
|
|
||||||
onConfirm: onConfirm ? onConfirm : emptyFunction,
|
|
||||||
onCancel: onCancel ? onCancel : emptyFunction
|
|
||||||
}, props));
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Show toast alert
|
//Show toast alert
|
||||||
BdApi.showToast = function(content, options = {}) {
|
BdApi.showToast = function(content, options = {}) {
|
||||||
Core.showToast(content, options);
|
Toasts.show(content, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Finds module
|
// Finds module
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import {SettingsCookie, PluginCookie, Plugins} from "data";
|
import {SettingsCookie, PluginCookie, Plugins} from "data";
|
||||||
import ContentManager from "./contentmanager";
|
import ContentManager from "./contentmanager";
|
||||||
import Utilities from "./utilities";
|
import Utilities from "./utilities";
|
||||||
import Core from "./core";
|
|
||||||
import BdApi from "./pluginapi";
|
|
||||||
import Emitter from "./emitter";
|
import Emitter from "./emitter";
|
||||||
import DataStore from "./datastore";
|
import DataStore from "./datastore";
|
||||||
|
import {Toasts, Modals} from "ui";
|
||||||
|
|
||||||
function PluginModule() {
|
function PluginModule() {
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ PluginModule.prototype.loadPlugins = function () {
|
||||||
if (PluginCookie[name]) {
|
if (PluginCookie[name]) {
|
||||||
try {
|
try {
|
||||||
plugin.start();
|
plugin.start();
|
||||||
if (SettingsCookie["fork-ps-2"]) Core.showToast(`${plugin.getName()} v${plugin.getVersion()} has started.`);
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin.getName()} v${plugin.getVersion()} has started.`);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
PluginCookie[name] = false;
|
PluginCookie[name] = false;
|
||||||
|
@ -53,10 +52,10 @@ PluginModule.prototype.loadPlugins = function () {
|
||||||
PluginModule.prototype.startPlugin = function(plugin, reload = false) {
|
PluginModule.prototype.startPlugin = function(plugin, reload = false) {
|
||||||
try {
|
try {
|
||||||
Plugins[plugin].plugin.start();
|
Plugins[plugin].plugin.start();
|
||||||
if (SettingsCookie["fork-ps-2"] && !reload) Core.showToast(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has started.`);
|
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has started.`);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (SettingsCookie["fork-ps-2"] && !reload) Core.showToast(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be started.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be started.`, {type: "error"});
|
||||||
PluginCookie[plugin] = false;
|
PluginCookie[plugin] = false;
|
||||||
this.savePluginData();
|
this.savePluginData();
|
||||||
Utilities.err("Plugins", plugin + " could not be started.", err);
|
Utilities.err("Plugins", plugin + " could not be started.", err);
|
||||||
|
@ -66,10 +65,10 @@ PluginModule.prototype.startPlugin = function(plugin, reload = false) {
|
||||||
PluginModule.prototype.stopPlugin = function(plugin, reload = false) {
|
PluginModule.prototype.stopPlugin = function(plugin, reload = false) {
|
||||||
try {
|
try {
|
||||||
Plugins[plugin].plugin.stop();
|
Plugins[plugin].plugin.stop();
|
||||||
if (SettingsCookie["fork-ps-2"] && !reload) Core.showToast(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has stopped.`);
|
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has stopped.`);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (SettingsCookie["fork-ps-2"] && !reload) Core.showToast(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be stopped.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be stopped.`, {type: "error"});
|
||||||
Utilities.err("Plugins", Plugins[plugin].plugin.getName() + " could not be stopped.", err);
|
Utilities.err("Plugins", Plugins[plugin].plugin.getName() + " could not be stopped.", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -96,15 +95,15 @@ PluginModule.prototype.togglePlugin = function (plugin) {
|
||||||
PluginModule.prototype.loadPlugin = function(filename) {
|
PluginModule.prototype.loadPlugin = function(filename) {
|
||||||
const error = ContentManager.loadContent(filename, "plugin");
|
const error = ContentManager.loadContent(filename, "plugin");
|
||||||
if (error) {
|
if (error) {
|
||||||
if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({plugins: [error]});
|
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [error]});
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${filename} could not be loaded.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${filename} could not be loaded.`, {type: "error"});
|
||||||
return Utilities.err("ContentManager", `${filename} could not be loaded.`, error);
|
return Utilities.err("ContentManager", `${filename} could not be loaded.`, error);
|
||||||
}
|
}
|
||||||
const plugin = Object.values(Plugins).find(p => p.filename == filename).plugin;
|
const plugin = Object.values(Plugins).find(p => p.filename == filename).plugin;
|
||||||
try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();}
|
try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();}
|
||||||
catch (err) {if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({plugins: [err]});}
|
catch (err) {if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [err]});}
|
||||||
Utilities.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`);
|
Utilities.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`);
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${plugin.getName()} v${plugin.getVersion()} was loaded.`, {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin.getName()} v${plugin.getVersion()} was loaded.`, {type: "success"});
|
||||||
Emitter.dispatch("plugin-loaded", plugin.getName());
|
Emitter.dispatch("plugin-loaded", plugin.getName());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,12 +115,12 @@ PluginModule.prototype.unloadPlugin = function(filenameOrName) {
|
||||||
const error = ContentManager.unloadContent(Plugins[plugin].filename, "plugin");
|
const error = ContentManager.unloadContent(Plugins[plugin].filename, "plugin");
|
||||||
delete Plugins[plugin];
|
delete Plugins[plugin];
|
||||||
if (error) {
|
if (error) {
|
||||||
if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({plugins: [error]});
|
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [error]});
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${plugin} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
|
||||||
return Utilities.err("ContentManager", `${plugin} could not be unloaded. It may have not been loaded yet.`, error);
|
return Utilities.err("ContentManager", `${plugin} could not be unloaded. It may have not been loaded yet.`, error);
|
||||||
}
|
}
|
||||||
Utilities.log("ContentManager", `${plugin} was unloaded.`);
|
Utilities.log("ContentManager", `${plugin} was unloaded.`);
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${plugin} was unloaded.`, {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} was unloaded.`, {type: "success"});
|
||||||
Emitter.dispatch("plugin-unloaded", plugin);
|
Emitter.dispatch("plugin-unloaded", plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,14 +132,14 @@ PluginModule.prototype.reloadPlugin = function(filenameOrName) {
|
||||||
if (enabled) this.stopPlugin(plugin, true);
|
if (enabled) this.stopPlugin(plugin, true);
|
||||||
const error = ContentManager.reloadContent(Plugins[plugin].filename, "plugin");
|
const error = ContentManager.reloadContent(Plugins[plugin].filename, "plugin");
|
||||||
if (error) {
|
if (error) {
|
||||||
if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({plugins: [error]});
|
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [error]});
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${plugin} could not be reloaded.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} could not be reloaded.`, {type: "error"});
|
||||||
return Utilities.err("ContentManager", `${plugin} could not be reloaded.`, error);
|
return Utilities.err("ContentManager", `${plugin} could not be reloaded.`, error);
|
||||||
}
|
}
|
||||||
if (Plugins[plugin].plugin.load && typeof(Plugins[plugin].plugin.load) == "function") Plugins[plugin].plugin.load();
|
if (Plugins[plugin].plugin.load && typeof(Plugins[plugin].plugin.load) == "function") Plugins[plugin].plugin.load();
|
||||||
if (enabled) this.startPlugin(plugin, true);
|
if (enabled) this.startPlugin(plugin, true);
|
||||||
Utilities.log("ContentManager", `${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`);
|
Utilities.log("ContentManager", `${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`);
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`, {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`, {type: "success"});
|
||||||
Emitter.dispatch("plugin-reloaded", plugin);
|
Emitter.dispatch("plugin-reloaded", plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import {SettingsCookie} from "data";
|
import {SettingsCookie} from "data";
|
||||||
// import ClassNormalizer from "./classnormalizer";
|
import DataStore from "./datastore";
|
||||||
import ContentManager from "./contentmanager";
|
import ContentManager from "./contentmanager";
|
||||||
import BdApi from "./pluginapi";
|
import BdApi from "./pluginapi";
|
||||||
import Core from "./core";
|
|
||||||
import EmoteModule from "./emotes";
|
import EmoteModule from "./emotes";
|
||||||
// import DevMode from "./devmode";
|
|
||||||
import Events from "./emitter";
|
import Events from "./emitter";
|
||||||
|
import WebpackModules from "./webpackmodules";
|
||||||
|
|
||||||
import {SettingsPanel as SettingsRenderer} from "ui";
|
import {SettingsPanel as SettingsRenderer} from "ui";
|
||||||
|
import Utilities from "./utilities";
|
||||||
|
|
||||||
|
//WebpackModules.getModule(m => m.getSection && m.getProps && !m.getGuildId && !m.getChannel)
|
||||||
|
//WebpackModules.getByProps("getGuildId", "getSection")
|
||||||
|
|
||||||
export default new class SettingsPanel {
|
export default new class SettingsPanel {
|
||||||
|
|
||||||
|
@ -19,6 +22,62 @@ export default new class SettingsPanel {
|
||||||
this.renderer.renderSidebar();
|
this.renderer.renderSidebar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
DataStore.initialize();
|
||||||
|
if (!DataStore.getSettingGroup("settings")) return this.saveSettings();
|
||||||
|
const savedSettings = this.loadSettings();
|
||||||
|
$("<style id=\"customcss\">").text(atob(DataStore.getBDData("bdcustomcss"))).appendTo(document.head);
|
||||||
|
for (const setting in savedSettings) {
|
||||||
|
if (savedSettings[setting] !== undefined) SettingsCookie[setting] = savedSettings[setting];
|
||||||
|
}
|
||||||
|
this.saveSettings();
|
||||||
|
// console.log("PATCHING");
|
||||||
|
// Utilities.monkeyPatch(WebpackModules.getByProps("getUserSettingsSections").default.prototype, "render", {after: (data) => {
|
||||||
|
// data.returnValue.type;
|
||||||
|
// }});
|
||||||
|
|
||||||
|
// Patcher.after(temp2.prototype, "generateSections", (t,a,r) => {
|
||||||
|
// r.push({section: "DIVIDER"});
|
||||||
|
// r.push({section: "HEADER", label: "My Section"});
|
||||||
|
// r.push({color: "#ffffff", label: "My Tab", onClick: function() {console.log("CLICK");}, section: "My Section"});
|
||||||
|
// r.push({color: "#cccccc", label: "My Tab2", onClick: function() {console.log("CLICK2");}, section: "My Section"});
|
||||||
|
|
||||||
|
// })
|
||||||
|
this.patchSections();
|
||||||
|
}
|
||||||
|
|
||||||
|
async patchSections() {
|
||||||
|
const UserSettings = await this.getUserSettings(); // data.returnValue.type;
|
||||||
|
Utilities.monkeyPatch(UserSettings.prototype, "generateSections", {after: (data) => {
|
||||||
|
console.log(data);
|
||||||
|
data.returnValue.splice(23, 0, {section: "DIVIDER"});
|
||||||
|
data.returnValue.splice(24, 0, {section: "HEADER", label: "BandagedBD"});
|
||||||
|
data.returnValue.splice(25, 0, {section: "IJ1", label: "Injected Tab 1", element: () => this.renderer.core2});
|
||||||
|
data.returnValue.splice(26, 0, {section: "IJ2", label: "Injected Tab 2", onClick: function() {console.log("CLICK2");}});
|
||||||
|
}});
|
||||||
|
const viewClass = WebpackModules.getByProps("standardSidebarView").standardSidebarView.split(" ")[0];
|
||||||
|
const node = document.querySelector(`.${viewClass}`);
|
||||||
|
Utilities.getInternalInstance(node).return.return.return.return.return.return.stateNode.forceUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserSettings() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const cancel = Utilities.monkeyPatch(WebpackModules.getByProps("getUserSettingsSections").default.prototype, "render", {after: (data) => {
|
||||||
|
resolve(data.returnValue.type);
|
||||||
|
data.thisObject.forceUpdate();
|
||||||
|
cancel();
|
||||||
|
}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSettings() {
|
||||||
|
DataStore.setSettingGroup("settings", SettingsCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSettings() {
|
||||||
|
return DataStore.getSettingGroup("settings");
|
||||||
|
}
|
||||||
|
|
||||||
updateSettings(id, enabled) {
|
updateSettings(id, enabled) {
|
||||||
Events.dispatch("setting-updated", "Modules", id, enabled);
|
Events.dispatch("setting-updated", "Modules", id, enabled);
|
||||||
SettingsCookie[id] = enabled;
|
SettingsCookie[id] = enabled;
|
||||||
|
@ -46,7 +105,7 @@ export default new class SettingsPanel {
|
||||||
else BdApi.setWindowPreference("backgroundColor", "#2f3136");
|
else BdApi.setWindowPreference("backgroundColor", "#2f3136");
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.saveSettings();
|
this.saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeSettings() {
|
initializeSettings() {
|
||||||
|
@ -57,6 +116,6 @@ export default new class SettingsPanel {
|
||||||
ContentManager.watchContent("theme");
|
ContentManager.watchContent("theme");
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.saveSettings();
|
this.saveSettings();
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -1,10 +1,9 @@
|
||||||
import {SettingsCookie, ThemeCookie, Themes} from "data";
|
import {SettingsCookie, ThemeCookie, Themes} from "data";
|
||||||
import ContentManager from "./contentmanager";
|
import ContentManager from "./contentmanager";
|
||||||
import Utilities from "./utilities";
|
import Utilities from "./utilities";
|
||||||
import Core from "./core";
|
|
||||||
import BdApi from "./pluginapi";
|
|
||||||
import Emitter from "./emitter";
|
import Emitter from "./emitter";
|
||||||
import DataStore from "./datastore";
|
import DataStore from "./datastore";
|
||||||
|
import {Toasts, Modals} from "ui";
|
||||||
|
|
||||||
function ThemeModule() {
|
function ThemeModule() {
|
||||||
|
|
||||||
|
@ -32,14 +31,14 @@ ThemeModule.prototype.enableTheme = function(theme, reload = false) {
|
||||||
ThemeCookie[theme] = true;
|
ThemeCookie[theme] = true;
|
||||||
this.saveThemeData();
|
this.saveThemeData();
|
||||||
$("head").append($("<style>", {id: Utilities.escapeID(theme), text: unescape(Themes[theme].css)}));
|
$("head").append($("<style>", {id: Utilities.escapeID(theme), text: unescape(Themes[theme].css)}));
|
||||||
if (SettingsCookie["fork-ps-2"] && !reload) Core.showToast(`${Themes[theme].name} v${Themes[theme].version} has been applied.`);
|
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been applied.`);
|
||||||
};
|
};
|
||||||
|
|
||||||
ThemeModule.prototype.disableTheme = function(theme, reload = false) {
|
ThemeModule.prototype.disableTheme = function(theme, reload = false) {
|
||||||
ThemeCookie[theme] = false;
|
ThemeCookie[theme] = false;
|
||||||
this.saveThemeData();
|
this.saveThemeData();
|
||||||
$(`#${Utilities.escapeID(Themes[theme].name)}`).remove();
|
$(`#${Utilities.escapeID(Themes[theme].name)}`).remove();
|
||||||
if (SettingsCookie["fork-ps-2"] && !reload) Core.showToast(`${Themes[theme].name} v${Themes[theme].version} has been disabled.`);
|
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been disabled.`);
|
||||||
};
|
};
|
||||||
|
|
||||||
ThemeModule.prototype.toggleTheme = function(theme) {
|
ThemeModule.prototype.toggleTheme = function(theme) {
|
||||||
|
@ -50,13 +49,13 @@ ThemeModule.prototype.toggleTheme = function(theme) {
|
||||||
ThemeModule.prototype.loadTheme = function(filename) {
|
ThemeModule.prototype.loadTheme = function(filename) {
|
||||||
const error = ContentManager.loadContent(filename, "theme");
|
const error = ContentManager.loadContent(filename, "theme");
|
||||||
if (error) {
|
if (error) {
|
||||||
if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({themes: [error]});
|
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({themes: [error]});
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${filename} could not be loaded. It may not have been loaded.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${filename} could not be loaded. It may not have been loaded.`, {type: "error"});
|
||||||
return Utilities.err("ContentManager", `${filename} could not be loaded.`, error);
|
return Utilities.err("ContentManager", `${filename} could not be loaded.`, error);
|
||||||
}
|
}
|
||||||
const theme = Object.values(Themes).find(p => p.filename == filename);
|
const theme = Object.values(Themes).find(p => p.filename == filename);
|
||||||
Utilities.log("ContentManager", `${theme.name} v${theme.version} was loaded.`);
|
Utilities.log("ContentManager", `${theme.name} v${theme.version} was loaded.`);
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${theme.name} v${theme.version} was loaded.`, {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme.name} v${theme.version} was loaded.`, {type: "success"});
|
||||||
Emitter.dispatch("theme-loaded", theme.name);
|
Emitter.dispatch("theme-loaded", theme.name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,12 +67,12 @@ ThemeModule.prototype.unloadTheme = function(filenameOrName) {
|
||||||
const error = ContentManager.unloadContent(Themes[theme].filename, "theme");
|
const error = ContentManager.unloadContent(Themes[theme].filename, "theme");
|
||||||
delete Themes[theme];
|
delete Themes[theme];
|
||||||
if (error) {
|
if (error) {
|
||||||
if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({themes: [error]});
|
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({themes: [error]});
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${theme} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
|
||||||
return Utilities.err("ContentManager", `${theme} could not be unloaded. It may have not been loaded yet.`, error);
|
return Utilities.err("ContentManager", `${theme} could not be unloaded. It may have not been loaded yet.`, error);
|
||||||
}
|
}
|
||||||
Utilities.log("ContentManager", `${theme} was unloaded.`);
|
Utilities.log("ContentManager", `${theme} was unloaded.`);
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${theme} was unloaded.`, {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} was unloaded.`, {type: "success"});
|
||||||
Emitter.dispatch("theme-unloaded", theme);
|
Emitter.dispatch("theme-unloaded", theme);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,12 +83,12 @@ ThemeModule.prototype.reloadTheme = function(filenameOrName) {
|
||||||
const error = ContentManager.reloadContent(Themes[theme].filename, "theme");
|
const error = ContentManager.reloadContent(Themes[theme].filename, "theme");
|
||||||
if (ThemeCookie[theme]) this.disableTheme(theme, true), this.enableTheme(theme, true);
|
if (ThemeCookie[theme]) this.disableTheme(theme, true), this.enableTheme(theme, true);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (SettingsCookie["fork-ps-1"]) Core.showContentErrors({themes: [error]});
|
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({themes: [error]});
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${theme} could not be reloaded.`, {type: "error"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} could not be reloaded.`, {type: "error"});
|
||||||
return Utilities.err("ContentManager", `${theme} could not be reloaded.`, error);
|
return Utilities.err("ContentManager", `${theme} could not be reloaded.`, error);
|
||||||
}
|
}
|
||||||
Utilities.log("ContentManager", `${theme} v${Themes[theme].version} was reloaded.`);
|
Utilities.log("ContentManager", `${theme} v${Themes[theme].version} was reloaded.`);
|
||||||
if (SettingsCookie["fork-ps-2"]) BdApi.showToast(`${theme} v${Themes[theme].version} was reloaded.`, {type: "success"});
|
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} v${Themes[theme].version} was reloaded.`, {type: "success"});
|
||||||
Emitter.dispatch("theme-reloaded", theme);
|
Emitter.dispatch("theme-reloaded", theme);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {SettingsCookie} from "data";
|
import {SettingsCookie} from "data";
|
||||||
import {BDV2, EmoteMenu, DiscordModules} from "modules";
|
import {BDV2, DiscordModules} from "modules";
|
||||||
|
import EmoteMenu from "../builtins/emotemenu";
|
||||||
|
|
||||||
export default class BDEmote extends DiscordModules.React.Component {
|
export default class BDEmote extends DiscordModules.React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
import {Utilities, WebpackModules, React} from "modules";
|
||||||
|
|
||||||
|
export default class Modals {
|
||||||
|
|
||||||
|
static get ModalStack() {return WebpackModules.getByProps("push", "update", "pop", "popWithKey");}
|
||||||
|
static get AlertModal() {return WebpackModules.getByPrototypes("handleCancel", "handleSubmit", "handleMinorConfirm");}
|
||||||
|
static get TextElement() {return WebpackModules.getByProps("Sizes", "Weights");}
|
||||||
|
static get ConfirmationModal() {return WebpackModules.getModule(m => m.defaultProps && m.key && m.key() == "confirm-modal");}
|
||||||
|
|
||||||
|
static default(title, content) {
|
||||||
|
const modal = $(`<div class="bd-modal-wrapper theme-dark">
|
||||||
|
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
||||||
|
<div class="bd-modal modal-1UGdnR">
|
||||||
|
<div class="bd-modal-inner inner-1JeGVc">
|
||||||
|
<div class="header header-1R_AjF">
|
||||||
|
<div class="title">${title}</div>
|
||||||
|
</div>
|
||||||
|
<div class="bd-modal-body">
|
||||||
|
<div class="scroller-wrap fade">
|
||||||
|
<div class="scroller">
|
||||||
|
${content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer footer-2yfCgX">
|
||||||
|
<button type="button">Okay</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`);
|
||||||
|
modal.find(".footer button").on("click", () => {
|
||||||
|
modal.addClass("closing");
|
||||||
|
setTimeout(() => { modal.remove(); }, 300);
|
||||||
|
});
|
||||||
|
modal.find(".bd-backdrop").on("click", () => {
|
||||||
|
modal.addClass("closing");
|
||||||
|
setTimeout(() => { modal.remove(); }, 300);
|
||||||
|
});
|
||||||
|
modal.appendTo("#app-mount");
|
||||||
|
}
|
||||||
|
|
||||||
|
static alert(title, content) {
|
||||||
|
if (this.ModalStack && this.AlertModal) return this.default(title, content);
|
||||||
|
this.ModalStack.push(function(props) {
|
||||||
|
return React.createElement(this.AlertModal, Object.assign({
|
||||||
|
title: title,
|
||||||
|
body: content,
|
||||||
|
}, props));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
static showConfirmationModal(title, content, options = {}) {
|
||||||
|
const TextElement = this.TextElement;
|
||||||
|
const ConfirmationModal = this.ConfirmationModal;
|
||||||
|
const ModalStack = this.ModalStack;
|
||||||
|
if (!this.ModalStack || !this.ConfirmationModal || !this.TextElement) return this.alert(title, content);
|
||||||
|
|
||||||
|
const {onConfirm, onCancel, confirmText, cancelText, danger = false} = options;
|
||||||
|
if (typeof(content) == "string") content = TextElement({color: TextElement.Colors.PRIMARY, children: [content]});
|
||||||
|
else if (Array.isArray(content)) content = TextElement({color: TextElement.Colors.PRIMARY, children: content});
|
||||||
|
content = [content];
|
||||||
|
|
||||||
|
const emptyFunction = () => {};
|
||||||
|
ModalStack.push(function(props) {
|
||||||
|
return React.createElement(ConfirmationModal, Object.assign({
|
||||||
|
header: title,
|
||||||
|
children: content,
|
||||||
|
red: danger,
|
||||||
|
confirmText: confirmText ? confirmText : "Okay",
|
||||||
|
cancelText: cancelText ? cancelText : "Cancel",
|
||||||
|
onConfirm: onConfirm ? onConfirm : emptyFunction,
|
||||||
|
onCancel: onCancel ? onCancel : emptyFunction
|
||||||
|
}, props));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static showContentErrors({plugins: pluginErrors = [], themes: themeErrors = []}) {
|
||||||
|
if (!pluginErrors || !themeErrors) return;
|
||||||
|
if (!pluginErrors.length && !themeErrors.length) return;
|
||||||
|
const modal = $(`<div class="bd-modal-wrapper theme-dark">
|
||||||
|
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
||||||
|
<div class="bd-modal bd-content-modal modal-1UGdnR">
|
||||||
|
<div class="bd-modal-inner inner-1JeGVc">
|
||||||
|
<div class="header header-1R_AjF"><div class="title">Content Errors</div></div>
|
||||||
|
<div class="bd-modal-body">
|
||||||
|
<div class="tab-bar-container">
|
||||||
|
<div class="tab-bar TOP">
|
||||||
|
<div class="tab-bar-item">Plugins</div>
|
||||||
|
<div class="tab-bar-item">Themes</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-header">
|
||||||
|
<div class="table-column column-name">Name</div>
|
||||||
|
<div class="table-column column-message">Message</div>
|
||||||
|
<div class="table-column column-error">Error</div>
|
||||||
|
</div>
|
||||||
|
<div class="scroller-wrap fade">
|
||||||
|
<div class="scroller">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer footer-2yfCgX">
|
||||||
|
<button type="button">Okay</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`);
|
||||||
|
|
||||||
|
const generateTab = function(errors) {
|
||||||
|
const container = $(`<div class="errors">`);
|
||||||
|
for (const err of errors) {
|
||||||
|
const error = $(`<div class="error">
|
||||||
|
<div class="table-column column-name">${err.name ? err.name : err.file}</div>
|
||||||
|
<div class="table-column column-message">${err.message}</div>
|
||||||
|
<div class="table-column column-error"><a class="error-link" href="">${err.error ? err.error.message : ""}</a></div>
|
||||||
|
</div>`);
|
||||||
|
container.append(error);
|
||||||
|
if (err.error) {
|
||||||
|
error.find("a").on("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
Utilities.err("ContentManager", `Error details for ${err.name ? err.name : err.file}.`, err.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tabs = [generateTab(pluginErrors), generateTab(themeErrors)];
|
||||||
|
|
||||||
|
modal.find(".tab-bar-item").on("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
modal.find(".tab-bar-item").removeClass("selected");
|
||||||
|
$(e.target).addClass("selected");
|
||||||
|
modal.find(".scroller").empty().append(tabs[$(e.target).index()]);
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.find(".footer button").on("click", () => {
|
||||||
|
modal.addClass("closing");
|
||||||
|
setTimeout(() => { modal.remove(); }, 300);
|
||||||
|
});
|
||||||
|
modal.find(".bd-backdrop").on("click", () => {
|
||||||
|
modal.addClass("closing");
|
||||||
|
setTimeout(() => { modal.remove(); }, 300);
|
||||||
|
});
|
||||||
|
modal.appendTo("#app-mount");
|
||||||
|
if (pluginErrors.length) modal.find(".tab-bar-item")[0].click();
|
||||||
|
else modal.find(".tab-bar-item")[1].click();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import {SettingsInfo, SettingsCookie, Plugins, Themes} from "data";
|
import {SettingsInfo, SettingsCookie, Plugins, Themes} from "data";
|
||||||
import {React, ReactDOM, Utilities, ContentManager, Events, EmoteModule, EmoteMenu, PluginManager, ThemeManager} from "modules";
|
import {React, ReactDOM, Utilities, ContentManager, Events, EmoteModule, PluginManager, ThemeManager} from "modules";
|
||||||
import Sidebar from "./sidebar";
|
import Sidebar from "./sidebar";
|
||||||
import Scroller from "../scroller";
|
import Scroller from "../scroller";
|
||||||
import List from "../list";
|
import List from "../list";
|
||||||
|
@ -12,6 +12,7 @@ import ThemeCard from "./themecard";
|
||||||
import ReloadIcon from "../icons/reload";
|
import ReloadIcon from "../icons/reload";
|
||||||
|
|
||||||
import CssEditor from "../customcss/editor";
|
import CssEditor from "../customcss/editor";
|
||||||
|
import SettingsGroup from "../settings/settingsgroup";
|
||||||
|
|
||||||
export default class V2_SettingsPanel {
|
export default class V2_SettingsPanel {
|
||||||
|
|
||||||
|
@ -98,6 +99,12 @@ export default class V2_SettingsPanel {
|
||||||
self.sidebar.render();
|
self.sidebar.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get core2() {
|
||||||
|
return this.coreSettings.map(section => {
|
||||||
|
return React.createElement(SettingsGroup, Object.assign({}, section, {onChange: this.onChange}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
get coreComponent() {
|
get coreComponent() {
|
||||||
return React.createElement(Scroller, {contentColumn: true, fade: true, dark: true, children: [
|
return React.createElement(Scroller, {contentColumn: true, fade: true, dark: true, children: [
|
||||||
React.createElement(SectionedSettingsPanel, {key: "cspanel", onChange: this.onChange, sections: this.coreSettings}),
|
React.createElement(SectionedSettingsPanel, {key: "cspanel", onChange: this.onChange, sections: this.coreSettings}),
|
||||||
|
@ -110,7 +117,7 @@ export default class V2_SettingsPanel {
|
||||||
contentColumn: true, fade: true, dark: true, children: [
|
contentColumn: true, fade: true, dark: true, children: [
|
||||||
React.createElement(SettingsPanel, {key: "espanel", title: "Emote Settings", onChange: this.onChange, settings: this.emoteSettings, button: {
|
React.createElement(SettingsPanel, {key: "espanel", title: "Emote Settings", onChange: this.onChange, settings: this.emoteSettings, button: {
|
||||||
title: "Clear Emote Cache",
|
title: "Clear Emote Cache",
|
||||||
onClick: () => { EmoteModule.clearEmoteData(); EmoteModule.init(); EmoteMenu.init(); }
|
onClick: () => { EmoteModule.clearEmoteData(); EmoteModule.init(); }
|
||||||
}}),
|
}}),
|
||||||
React.createElement(Tools, {key: "tools"})
|
React.createElement(Tools, {key: "tools"})
|
||||||
]});
|
]});
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
import {React} from "modules";
|
import {React} from "modules";
|
||||||
|
|
||||||
|
const flexContainer = "flex-1xMQg5 flex-1O1GKY da-flex da-flex vertical-V37hAW flex-1O1GKY directionColumn-35P_nr justifyStart-2NDFzi alignStretch-DpGPf3 noWrap-3jynv6 switchItem-2hKKKK";
|
||||||
|
const flexWrap = "flex-1xMQg5 flex-1O1GKY da-flex da-flex horizontal-1ae9ci horizontal-2EEEnY flex-1O1GKY directionRow-3v3tfG justifyStart-2NDFzi alignStart-H-X2h- noWrap-3jynv6";
|
||||||
|
const flexChild = "flexChild-faoVW3 da-flexChild";
|
||||||
|
const title = "titleDefault-a8-ZSr title-31JmR4 da-titleDefault da-title";
|
||||||
|
const switchWrapper = "flexChild-faoVW3 da-flexChild switchEnabled-V2WDBB switch-3wwwcV da-switchEnabled da-switch valueUnchecked-2lU_20 value-2hFrkk sizeDefault-2YlOZr size-3rFEHg themeDefault-24hCdX";
|
||||||
|
const switchWrapperEnabled = "flexChild-faoVW3 da-flexChild switchEnabled-V2WDBB switch-3wwwcV da-switchEnabled da-switch valueChecked-m-4IJZ value-2hFrkk sizeDefault-2YlOZr size-3rFEHg themeDefault-24hCdX";
|
||||||
|
const switchClass = "checkboxEnabled-CtinEn checkbox-2tyjJg da-checkboxEnabled da-checkbox";
|
||||||
|
const description = "description-3_Ncsb formText-3fs7AJ da-description da-formText note-1V3kyJ da-note modeDefault-3a2Ph1 da-modeDefault primary-jw0I4K";
|
||||||
|
|
||||||
export default class V2C_Switch extends React.Component {
|
export default class V2C_Switch extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -19,25 +28,25 @@ export default class V2C_Switch extends React.Component {
|
||||||
const {checked} = this.state;
|
const {checked} = this.state;
|
||||||
return React.createElement(
|
return React.createElement(
|
||||||
"div",
|
"div",
|
||||||
{className: "ui-flex flex-vertical flex-justify-start flex-align-stretch flex-nowrap ui-switch-item"},
|
{className: `ui-flex flex-vertical flex-justify-start flex-align-stretch flex-nowrap ui-switch-item ${flexContainer}`},
|
||||||
React.createElement(
|
React.createElement(
|
||||||
"div",
|
"div",
|
||||||
{className: "ui-flex flex-horizontal flex-justify-start flex-align-stretch flex-nowrap"},
|
{className: `ui-flex flex-horizontal flex-justify-start flex-align-stretch flex-nowrap ${flexWrap}`},
|
||||||
React.createElement(
|
React.createElement(
|
||||||
"h3",
|
"h3",
|
||||||
{className: "ui-form-title h3 margin-reset margin-reset ui-flex-child"},
|
{className: `ui-form-title h3 margin-reset margin-reset ui-flex-child ${title} ${flexChild}`},
|
||||||
text
|
text
|
||||||
),
|
),
|
||||||
React.createElement(
|
React.createElement(
|
||||||
"label",
|
"div",
|
||||||
{className: "ui-switch-wrapper ui-flex-child", style: {flex: "0 0 auto"}},
|
{className: `ui-switch-wrapper ui-flex-child ${checked ? switchWrapperEnabled : switchWrapper}`, style: {flex: "0 0 auto"}},
|
||||||
React.createElement("input", {className: "ui-switch-checkbox", type: "checkbox", checked: checked, onChange: e => this.onChange(e)}),
|
React.createElement("input", {className: `ui-switch-checkbox ${switchClass}`, type: "checkbox", checked: checked, onChange: e => this.onChange(e)}),
|
||||||
React.createElement("div", {className: `ui-switch ${checked ? "checked" : ""}`})
|
React.createElement("div", {className: `ui-switch ${checked ? "checked" : ""}`})
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
React.createElement(
|
React.createElement(
|
||||||
"div",
|
"div",
|
||||||
{className: "ui-form-text style-description margin-top-4", style: {flex: "1 1 auto"}},
|
{className: `ui-form-text style-description margin-top-4 ${description}`, style: {flex: "1 1 auto"}},
|
||||||
info
|
info
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {SettingsCookie, ThemeCookie, Themes} from "data";
|
import {SettingsCookie, ThemeCookie, Themes} from "data";
|
||||||
import {React, Core, ThemeManager} from "modules";
|
import {React, ThemeManager} from "modules";
|
||||||
import ReloadIcon from "../icons/reload";
|
import ReloadIcon from "../icons/reload";
|
||||||
|
import Toasts from "../toasts";
|
||||||
|
|
||||||
export default class V2C_ThemeCard extends React.Component {
|
export default class V2C_ThemeCard extends React.Component {
|
||||||
|
|
||||||
|
@ -34,8 +35,8 @@ export default class V2C_ThemeCard extends React.Component {
|
||||||
reload() {
|
reload() {
|
||||||
const theme = this.props.theme.name;
|
const theme = this.props.theme.name;
|
||||||
const error = ThemeManager.reloadTheme(theme);
|
const error = ThemeManager.reloadTheme(theme);
|
||||||
if (error) Core.showToast(`Could not reload ${Themes[theme].name}. Check console for details.`, {type: "error"});
|
if (error) Toasts.show(`Could not reload ${Themes[theme].name}. Check console for details.`, {type: "error"});
|
||||||
else Core.showToast(`${Themes[theme].name} v${Themes[theme].version} has been reloaded.`, {type: "success"});
|
else Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been reloaded.`, {type: "success"});
|
||||||
// this.setState(this.state);
|
// this.setState(this.state);
|
||||||
this.props.theme = Themes[theme];
|
this.props.theme = Themes[theme];
|
||||||
this.onReload(this.props.theme.name);
|
this.onReload(this.props.theme.name);
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class V2C_SettingsTitle extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return React.createElement(
|
return React.createElement(
|
||||||
"h2",
|
"h2",
|
||||||
{className: "ui-form-title h2 margin-reset margin-bottom-20 marginTop60-3PGbtK da-marginTop6"},
|
{className: "ui-form-title h2 margin-reset margin-bottom-20 marginTop60-3PGbtK h2-2gWE-o title-3sZWYQ size16-14cGz5 height20-mO2eIN weightSemiBold-NJexzi defaultColor-1_ajX0 defaultMarginh2-2LTaUL marginBottom20-32qID7"},
|
||||||
this.props.text
|
this.props.text
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import {WebpackModules} from "modules";
|
||||||
|
|
||||||
|
const channelsClass = WebpackModules.getByProps("channels").channels.split(" ")[0];
|
||||||
|
const membersWrapClass = WebpackModules.getByProps("membersWrap").membersWrap.split(" ")[0];
|
||||||
|
|
||||||
|
export default class Toasts {
|
||||||
|
|
||||||
|
/** Shorthand for `type = "success"` for {@link module:Toasts.show} */
|
||||||
|
static async success(content, options = {}) {return this.show(content, Object.assign(options, {type: "success"}));}
|
||||||
|
|
||||||
|
/** Shorthand for `type = "info"` for {@link module:Toasts.show} */
|
||||||
|
static async info(content, options = {}) {return this.show(content, Object.assign(options, {type: "info"}));}
|
||||||
|
|
||||||
|
/** Shorthand for `type = "warning"` for {@link module:Toasts.show} */
|
||||||
|
static async warning(content, options = {}) {return this.show(content, Object.assign(options, {type: "warning"}));}
|
||||||
|
|
||||||
|
/** Shorthand for `type = "error"` for {@link module:Toasts.show} */
|
||||||
|
static async error(content, options = {}) {return this.show(content, Object.assign(options, {type: "error"}));}
|
||||||
|
|
||||||
|
/** Shorthand for `type = "default"` for {@link module:Toasts.show} */
|
||||||
|
static async default(content, options = {}) {return this.show(content, Object.assign(options, {type: ""}));}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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 Adjusts the time (in ms) the toast should be shown for before disappearing automatically. Default: 3000
|
||||||
|
*/
|
||||||
|
static show(content, options = {}) {
|
||||||
|
this.ensureContainer();
|
||||||
|
const {type = "", icon = true, timeout = 3000} = options;
|
||||||
|
const toastElem = document.createElement("div");
|
||||||
|
toastElem.classList.add("bd-toast");
|
||||||
|
if (type) toastElem.classList.add("toast-" + type);
|
||||||
|
if (type && icon) toastElem.classList.add("icon");
|
||||||
|
toastElem.innerText = content;
|
||||||
|
document.querySelector(".bd-toasts").appendChild(toastElem);
|
||||||
|
setTimeout(() => {
|
||||||
|
toastElem.classList.add("closing");
|
||||||
|
setTimeout(() => {
|
||||||
|
toastElem.remove();
|
||||||
|
if (!document.querySelectorAll(".bd-toasts .bd-toast").length) document.querySelector(".bd-toasts").remove();
|
||||||
|
}, 300);
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ensureContainer() {
|
||||||
|
if (document.querySelector(".bd-toasts")) return;
|
||||||
|
const container = document.querySelector(`.${channelsClass} + div`);
|
||||||
|
const memberlist = container.querySelector(`.${membersWrapClass}`);
|
||||||
|
const form = container ? container.querySelector("form") : null;
|
||||||
|
const left = container ? container.getBoundingClientRect().left : 310;
|
||||||
|
const right = memberlist ? memberlist.getBoundingClientRect().left : 0;
|
||||||
|
const width = right ? right - container.getBoundingClientRect().left : container.offsetWidth;
|
||||||
|
const bottom = form ? form.offsetHeight : 80;
|
||||||
|
const toastWrapper = document.createElement("div");
|
||||||
|
toastWrapper.classList.add("bd-toasts");
|
||||||
|
toastWrapper.style.setProperty("left", left + "px");
|
||||||
|
toastWrapper.style.setProperty("width", width + "px");
|
||||||
|
toastWrapper.style.setProperty("bottom", bottom + "px");
|
||||||
|
document.querySelector("#app-mount").appendChild(toastWrapper);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import SettingsPanel from "./settings/settings";
|
import SettingsPanel from "./settings/settings";
|
||||||
import * as PublicServers from "./publicservers/publicservers";
|
import * as PublicServers from "./publicservers/publicservers";
|
||||||
|
export {default as Toasts} from "./toasts";
|
||||||
|
export {default as Modals} from "./modals";
|
||||||
export {SettingsPanel, PublicServers};
|
export {SettingsPanel, PublicServers};
|
Loading…
Reference in New Issue