first refactor of emote module
This commit is contained in:
parent
b64f35fa88
commit
6bed40f21f
1194
js/main.js
1194
js/main.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -11,7 +11,9 @@ export default new class TwentyFourHour extends Builtin {
|
|||
}
|
||||
|
||||
disabled() {
|
||||
if (this.cancel24Hour) this.cancel24Hour();
|
||||
if (!this.cancel24Hour) return;
|
||||
this.cancel24Hour();
|
||||
delete this.cancel24Hour;
|
||||
}
|
||||
|
||||
inject24Hour() {
|
||||
|
|
|
@ -7,4 +7,6 @@ export {default as MinimalMode} from "./minimalmode";
|
|||
export {default as TwentyFourHour} from "./24hour";
|
||||
export {default as ColoredText} from "./coloredtext";
|
||||
export {default as VoiceDisconnect} from "./voicedisconnect";
|
||||
export {default as EmoteMenu} from "./emotemenu";
|
||||
export {default as EmoteMenu} from "./emotemenu";
|
||||
export {default as EmoteAutocaps} from "./emoteautocaps";
|
||||
export {default as EmoteModule} from "./emotes";
|
|
@ -9,13 +9,6 @@ export default new class ClassNormalizer extends Builtin {
|
|||
get category() {return "Modules";}
|
||||
get name() {return "ClassNormalizer";}
|
||||
|
||||
disabled() {
|
||||
if (!this.hasPatched) return;
|
||||
this.unpatchClassModules(WebpackModules.getModules(this.moduleFilter.bind(this)));
|
||||
this.revertElement(document.querySelector("#app-mount"));
|
||||
this.hasPatched = false;
|
||||
}
|
||||
|
||||
enabled() {
|
||||
if (this.hasPatched) return;
|
||||
this.patchClassModules(WebpackModules.getModules(this.moduleFilter.bind(this)));
|
||||
|
@ -23,6 +16,13 @@ export default new class ClassNormalizer extends Builtin {
|
|||
this.hasPatched = true;
|
||||
}
|
||||
|
||||
disabled() {
|
||||
if (!this.hasPatched) return;
|
||||
this.unpatchClassModules(WebpackModules.getModules(this.moduleFilter.bind(this)));
|
||||
this.revertElement(document.querySelector("#app-mount"));
|
||||
this.hasPatched = false;
|
||||
}
|
||||
|
||||
patchClassModules(modules) {
|
||||
for (const module of modules) {
|
||||
this.patchClassModule(normalizedPrefix, module);
|
||||
|
|
|
@ -13,7 +13,9 @@ export default new class ColoredText extends Builtin {
|
|||
}
|
||||
|
||||
disabled() {
|
||||
if (this.cancelColoredText) this.cancelColoredText();
|
||||
if (!this.cancelColoredText) return;
|
||||
this.cancelColoredText();
|
||||
delete this.cancelColoredText;
|
||||
}
|
||||
|
||||
injectColoredText() {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import Builtin from "../structs/builtin";
|
||||
|
||||
import {Emotes} from "data";
|
||||
import {Utilities} from "modules";
|
||||
|
||||
export default new class EmoteAutocaps extends Builtin {
|
||||
get name() {return "EmoteAutocapitalize";}
|
||||
get category() {return "Modules";}
|
||||
get id() {return "bda-es-4";}
|
||||
|
||||
enabled() {
|
||||
$("body").off(".bdac");
|
||||
$("body").on("keyup.bdac change.bdac paste.bdac", $(".channelTextArea-1LDbYG textarea:first"), () => {
|
||||
const text = $(".channelTextArea-1LDbYG textarea:first").val();
|
||||
if (text == undefined) return;
|
||||
|
||||
const lastWord = text.split(" ").pop();
|
||||
if (lastWord.length > 3) {
|
||||
if (lastWord == "danSgame") return;
|
||||
const ret = this.capitalize(lastWord.toLowerCase());
|
||||
if (ret !== null && ret !== undefined) {
|
||||
Utilities.insertText(Utilities.getTextArea()[0], text.replace(lastWord, ret));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
disabled() {
|
||||
$("body").off(".bdac");
|
||||
}
|
||||
|
||||
capitalize(value) {
|
||||
const res = Emotes.TwitchGlobal;
|
||||
for (const p in res) {
|
||||
if (res.hasOwnProperty(p) && value == (p + "").toLowerCase()) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
import Builtin, {onSettingChange} from "../structs/builtin";
|
||||
import {SettingsCookie, Emotes} from "data";
|
||||
import {SettingsCookie, Emotes, State} from "data";
|
||||
import {DataStore, Utilities, Events} from "modules";
|
||||
|
||||
const headerHTML = `<div id="bda-qem">
|
||||
|
@ -62,6 +62,7 @@ export default new class EmoteMenu extends Builtin {
|
|||
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);
|
||||
this.updateTwitchEmotes = this.updateTwitchEmotes.bind(this);
|
||||
}
|
||||
|
||||
initialize() {
|
||||
|
@ -72,10 +73,6 @@ export default new class EmoteMenu extends Builtin {
|
|||
}
|
||||
|
||||
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,
|
||||
|
@ -83,14 +80,26 @@ export default new class EmoteMenu extends Builtin {
|
|||
});
|
||||
this.hideEmojiCancel = onSettingChange(this.category, this.hideEmojisID, this.enableHideEmojis, this.disableHideEmojis);
|
||||
if (this.hideEmojis) this.enableHideEmojis();
|
||||
// await this.waitForEmotes();
|
||||
// this.updateTwitchEmotes();
|
||||
if (State.emotesLoaded) this.updateTwitchEmotes();
|
||||
Events.on("emotes-loaded", this.updateTwitchEmotes);
|
||||
}
|
||||
|
||||
disabled() {
|
||||
Events.off("emotes-loaded", this.updateTwitchEmotes);
|
||||
this.observer.disconnect();
|
||||
this.disableHideEmojis();
|
||||
if (this.hideEmojiCancel) this.hideEmojiCancel();
|
||||
}
|
||||
|
||||
async waitForEmotes() {
|
||||
if (State.emotesLoaded) return;
|
||||
return new Promise(resolve => {
|
||||
Events.on("emotes-loaded", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
enableHideEmojis() {
|
||||
$(".emojiPicker-3m1S-j").addClass("bda-qme-hidden");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
import Builtin, {onSettingChange} from "../structs/builtin";
|
||||
|
||||
import {Config, SettingsCookie, Emotes, EmoteBlacklist, EmoteInfo, EmoteModifiers, EmoteOverrides, State} from "data";
|
||||
import {Utilities, WebpackModules, DataStore, DiscordModules, Events} from "modules";
|
||||
import BDEmote from "../ui/emote";
|
||||
import {Toasts} from "ui";
|
||||
|
||||
const bdEmoteSettingIDs = {
|
||||
TwitchGlobal: "bda-es-7",
|
||||
TwitchSubscriber: "bda-es-7",
|
||||
BTTV: "bda-es-2",
|
||||
FrankerFaceZ: "bda-es-1",
|
||||
BTTV2: "bda-es-2"
|
||||
};
|
||||
|
||||
export default new class EmoteModule extends Builtin {
|
||||
get name() {return "Emotes";}
|
||||
get category() {return "Modules";}
|
||||
get id() {return "";}
|
||||
get categories() { return Object.keys(bdEmoteSettingIDs).filter(k => SettingsCookie[bdEmoteSettingIDs[k]]); }
|
||||
|
||||
get MessageContentComponent() {return WebpackModules.getModule(m => m.defaultProps && m.defaultProps.hasOwnProperty("disableButtons"));}
|
||||
|
||||
async initialize() {
|
||||
super.initialize();
|
||||
await this.getBlacklist();
|
||||
await this.loadEmoteData(EmoteInfo);
|
||||
|
||||
while (!this.MessageContentComponent) await new Promise(resolve => setTimeout(resolve, 100));
|
||||
this.patchMessageContent();
|
||||
}
|
||||
|
||||
disabled() {
|
||||
if (this.cancelEmoteRender) return;
|
||||
this.cancelEmoteRender();
|
||||
delete this.cancelEmoteRender;
|
||||
}
|
||||
|
||||
patchMessageContent() {
|
||||
if (this.cancelEmoteRender) return;
|
||||
this.cancelEmoteRender = Utilities.monkeyPatch(this.MessageContentComponent.prototype, "render", {after: ({returnValue}) => {
|
||||
Utilities.monkeyPatch(returnValue.props, "children", {silent: true, after: ({returnValue}) => {
|
||||
if (this.categories.length == 0) return;
|
||||
const markup = returnValue.props.children[1];
|
||||
if (!markup.props.children) return;
|
||||
const nodes = markup.props.children[1];
|
||||
if (!nodes || !nodes.length) return;
|
||||
for (let n = 0; n < nodes.length; n++) {
|
||||
const node = nodes[n];
|
||||
if (typeof(node) !== "string") continue;
|
||||
const words = node.split(/([^\s]+)([\s]|$)/g);
|
||||
for (let c = 0, clen = this.categories.length; c < clen; c++) {
|
||||
for (let w = 0, wlen = words.length; w < wlen; w++) {
|
||||
const emote = words[w];
|
||||
const emoteSplit = emote.split(":");
|
||||
const emoteName = emoteSplit[0];
|
||||
let emoteModifier = emoteSplit[1] ? emoteSplit[1] : "";
|
||||
let emoteOverride = emoteModifier.slice(0);
|
||||
|
||||
if (emoteName.length < 4 || EmoteBlacklist.includes(emoteName)) continue;
|
||||
if (!EmoteModifiers.includes(emoteModifier) || !SettingsCookie["bda-es-8"]) emoteModifier = "";
|
||||
if (!EmoteOverrides.includes(emoteOverride)) emoteOverride = "";
|
||||
else emoteModifier = emoteOverride;
|
||||
|
||||
let current = this.categories[c];
|
||||
if (emoteOverride === "twitch") {
|
||||
if (Emotes.TwitchGlobal[emoteName]) current = "TwitchGlobal";
|
||||
else if (Emotes.TwitchSubscriber[emoteName]) current = "TwitchSubscriber";
|
||||
}
|
||||
else if (emoteOverride === "bttv") {
|
||||
if (Emotes.BTTV[emoteName]) current = "BTTV";
|
||||
else if (Emotes.BTTV2[emoteName]) current = "BTTV2";
|
||||
}
|
||||
else if (emoteOverride === "ffz") {
|
||||
if (Emotes.FrankerFaceZ[emoteName]) current = "FrankerFaceZ";
|
||||
}
|
||||
|
||||
if (!Emotes[current][emoteName] || !SettingsCookie[bdEmoteSettingIDs[current]]) continue;
|
||||
const results = nodes[n].match(new RegExp(`([\\s]|^)${Utilities.escape(emoteModifier ? emoteName + ":" + emoteModifier : emoteName)}([\\s]|$)`));
|
||||
if (!results) continue;
|
||||
const pre = nodes[n].substring(0, results.index + results[1].length);
|
||||
const post = nodes[n].substring(results.index + results[0].length - results[2].length);
|
||||
nodes[n] = pre;
|
||||
const emoteComponent = DiscordModules.React.createElement(BDEmote, {name: emoteName, url: Emotes[current][emoteName], modifier: emoteModifier});
|
||||
nodes.splice(n + 1, 0, post);
|
||||
nodes.splice(n + 1, 0, emoteComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
const onlyEmotes = nodes.every(r => {
|
||||
if (typeof(r) == "string" && r.replace(/\s*/, "") == "") return true;
|
||||
else if (r.type && r.type.name == "BDEmote") return true;
|
||||
else if (r.props && r.props.children && r.props.children.props && r.props.children.props.emojiName) return true;
|
||||
return false;
|
||||
});
|
||||
if (!onlyEmotes) return;
|
||||
|
||||
for (const node of nodes) {
|
||||
if (typeof(node) != "object") continue;
|
||||
if (node.type.name == "BDEmote") node.props.jumboable = true;
|
||||
else if (node.props && node.props.children && node.props.children.props && node.props.children.props.emojiName) node.props.children.props.jumboable = true;
|
||||
}
|
||||
}});
|
||||
}});
|
||||
}
|
||||
|
||||
async loadEmoteData(emoteInfo) {
|
||||
const _fs = require("fs");
|
||||
const emoteFile = "emote_data.json";
|
||||
const file = Config.dataPath + emoteFile;
|
||||
const exists = _fs.existsSync(file);
|
||||
|
||||
if (exists && this.isCacheValid()) {
|
||||
Toasts.show("Loading emotes from cache.", {type: "info"});
|
||||
Utilities.log("Emotes", "Loading emotes from local cache.");
|
||||
|
||||
const data = await new Promise(resolve => {
|
||||
_fs.readFile(file, "utf8", (err, data) => {
|
||||
Utilities.log("Emotes", "Emotes loaded from cache.");
|
||||
if (err) data = {};
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
|
||||
let isValid = Utilities.testJSON(data);
|
||||
if (isValid) Object.assign(Emotes, JSON.parse(data));
|
||||
|
||||
for (const e in emoteInfo) {
|
||||
isValid = Object.keys(Emotes[emoteInfo[e].variable]).length > 0;
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
Toasts.show("Emotes successfully loaded.", {type: "success"});
|
||||
State.emotesLoaded = true;
|
||||
Events.dispatch("emotes-loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
Utilities.log("Emotes", "Cache was corrupt, downloading...");
|
||||
_fs.unlinkSync(file);
|
||||
}
|
||||
|
||||
if (!SettingsCookie["fork-es-3"]) return;
|
||||
Toasts.show("Downloading emotes in the background do not reload.", {type: "info"});
|
||||
|
||||
for (const e in emoteInfo) {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
const data = await this.downloadEmotes(emoteInfo[e]);
|
||||
Emotes[emoteInfo[e].variable] = data;
|
||||
}
|
||||
|
||||
Toasts.show("All emotes successfully downloaded.", {type: "success"});
|
||||
|
||||
try { _fs.writeFileSync(file, JSON.stringify(Emotes), "utf8"); }
|
||||
catch (err) { Utilities.err("Emotes", "Could not save emote data.", err); }
|
||||
|
||||
State.emotesLoaded = true;
|
||||
Events.dispatch("emotes-loaded");
|
||||
}
|
||||
|
||||
downloadEmotes(emoteMeta) {
|
||||
const request = require("request");
|
||||
const options = {
|
||||
url: emoteMeta.url,
|
||||
timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000
|
||||
};
|
||||
|
||||
Utilities.log("Emotes", `Downloading: ${emoteMeta.variable} (${emoteMeta.url})`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(options, (error, response, body) => {
|
||||
if (error) {
|
||||
Utilities.err("Emotes", "Could not download " + emoteMeta.variable, error);
|
||||
if (emoteMeta.backup) {
|
||||
emoteMeta.url = emoteMeta.backup;
|
||||
emoteMeta.backup = null;
|
||||
if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser;
|
||||
return resolve(this.downloadEmotes(emoteMeta));
|
||||
}
|
||||
return reject({});
|
||||
}
|
||||
|
||||
let parsedData = {};
|
||||
try {
|
||||
parsedData = JSON.parse(body);
|
||||
}
|
||||
catch (err) {
|
||||
Utilities.err("Emotes", "Could not download " + emoteMeta.variable, err);
|
||||
if (emoteMeta.backup) {
|
||||
emoteMeta.url = emoteMeta.backup;
|
||||
emoteMeta.backup = null;
|
||||
if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser;
|
||||
return resolve(this.downloadEmotes(emoteMeta));
|
||||
}
|
||||
return reject({});
|
||||
}
|
||||
if (typeof(emoteMeta.parser) === "function") parsedData = emoteMeta.parser(parsedData);
|
||||
|
||||
for (const emote in parsedData) {
|
||||
if (emote.length < 4 || EmoteBlacklist.includes(emote)) {
|
||||
delete parsedData[emote];
|
||||
continue;
|
||||
}
|
||||
parsedData[emote] = emoteMeta.getEmoteURL(parsedData[emote]);
|
||||
}
|
||||
resolve(parsedData);
|
||||
Utilities.log("Emotes", "Downloaded: " + emoteMeta.variable);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlacklist() {
|
||||
return new Promise(resolve => {
|
||||
$.getJSON(`https://rauenzi.github.io/BetterDiscordApp/data/emotefilter.json`, function (data) {
|
||||
resolve(EmoteBlacklist.push(...data.blacklist));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
isCacheValid() {
|
||||
const cacheLength = DataStore.getBDData("emoteCacheDays") || DataStore.setBDData("emoteCacheDays", 7) || 7;
|
||||
const cacheDate = new Date(DataStore.getBDData("emoteCacheDate") || null);
|
||||
const currentDate = new Date();
|
||||
const daysBetween = Math.round(Math.abs((currentDate.getTime() - cacheDate.getTime()) / (24 * 60 * 60 * 1000)));
|
||||
if (daysBetween > cacheLength) {
|
||||
DataStore.setBDData("emoteCacheDate", currentDate.toJSON());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
clearEmoteData() {
|
||||
const _fs = require("fs");
|
||||
const emoteFile = "emote_data.json";
|
||||
const file = Config.dataPath + emoteFile;
|
||||
const exists = _fs.existsSync(file);
|
||||
if (exists) _fs.unlinkSync(file);
|
||||
DataStore.setBDData("emoteCacheDate", (new Date()).toJSON());
|
||||
for (const category in Emotes) Object.assign(Emotes, {[category]: {}});
|
||||
}
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
import State from "./state";
|
||||
import SettingsInfo from "./settings";
|
||||
import SettingsCookie from "./cookies/settingscookie";
|
||||
import Config from "./config";
|
||||
|
@ -7,5 +8,8 @@ import Themes from "./themes";
|
|||
import Plugins from "./plugins";
|
||||
import Emotes from "./emotes/emotes";
|
||||
import EmoteBlacklist from "./emotes/blacklist";
|
||||
import EmoteInfo from "./emotes/info";
|
||||
import EmoteModifiers from "./emotes/modifiers";
|
||||
import EmoteOverrides from "./emotes/overrides"
|
||||
|
||||
export {SettingsInfo, SettingsCookie, Config, PluginCookie, ThemeCookie, Themes, Plugins, Emotes, EmoteBlacklist};
|
||||
export {State, SettingsInfo, SettingsCookie, Config, PluginCookie, ThemeCookie, Themes, Plugins, Emotes, EmoteBlacklist, EmoteInfo, EmoteModifiers, EmoteOverrides};
|
|
@ -0,0 +1,42 @@
|
|||
export default {
|
||||
TwitchGlobal: {
|
||||
url: "https://twitchemotes.com/api_cache/v3/global.json",
|
||||
backup: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_global.json`,
|
||||
variable: "TwitchGlobal",
|
||||
getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e.id}/1.0`,
|
||||
getOldData: (url, name) => { return {id: url.match(/\/([0-9]+)\//)[1], code: name, emoticon_set: 0, description: null}; }
|
||||
},
|
||||
TwitchSubscriber: {
|
||||
url: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_subscriber.json`,
|
||||
variable: "TwitchSubscriber",
|
||||
getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e}/1.0`,
|
||||
getOldData: (url) => url.match(/\/([0-9]+)\//)[1]
|
||||
},
|
||||
FrankerFaceZ: {
|
||||
url: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_ffz.json`,
|
||||
variable: "FrankerFaceZ",
|
||||
getEmoteURL: (e) => `https://cdn.frankerfacez.com/emoticon/${e}/1`,
|
||||
getOldData: (url) => url.match(/\/([0-9]+)\//)[1]
|
||||
},
|
||||
BTTV: {
|
||||
url: "https://api.betterttv.net/emotes",
|
||||
variable: "BTTV",
|
||||
parser: (data) => {
|
||||
const emotes = {};
|
||||
for (let e = 0, len = data.emotes.length; e < len; e++) {
|
||||
const emote = data.emotes[e];
|
||||
emotes[emote.regex] = emote.url;
|
||||
}
|
||||
return emotes;
|
||||
},
|
||||
getEmoteURL: (e) => `${e}`,
|
||||
getOldData: (url) => url
|
||||
},
|
||||
BTTV2: {
|
||||
url: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv.json`,
|
||||
variable: "BTTV2",
|
||||
oldVariable: "emotesBTTV2",
|
||||
getEmoteURL: (e) => `https://cdn.betterttv.net/emote/${e}/1x`,
|
||||
getOldData: (url) => url.match(/emote\/(.+)\//)[1]
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export default ["flip", "spin", "pulse", "spin2", "spin3", "1spin", "2spin", "3spin", "tr", "bl", "br", "shake", "shake2", "shake3", "flap"];
|
|
@ -0,0 +1 @@
|
|||
export default ["twitch", "bttv", "ffz"];
|
|
@ -0,0 +1,3 @@
|
|||
export default {
|
||||
emotesLoaded: false
|
||||
};
|
|
@ -1,14 +1,13 @@
|
|||
import BDV2 from "./bdv2";
|
||||
import Utilities from "./utilities";
|
||||
import {Config, SettingsCookie} from "data";
|
||||
import EmoteModule from "./emotes";
|
||||
// import EmoteModule from "./emotes";
|
||||
// import QuickEmoteMenu from "../builtins/emotemenu";
|
||||
import PluginManager from "./pluginmanager";
|
||||
import ThemeManager from "./thememanager";
|
||||
import SettingsPanel from "./settingspanel";
|
||||
import * as Builtins from "builtins";
|
||||
import {Modals} from "ui";
|
||||
import Events from "./emitter";
|
||||
|
||||
function Core() {
|
||||
}
|
||||
|
@ -34,12 +33,12 @@ Core.prototype.init = async function() {
|
|||
Utilities.log("Startup", "Initializing Settings");
|
||||
SettingsPanel.initialize();
|
||||
Utilities.log("Startup", "Initializing EmoteModule");
|
||||
window.emotePromise = EmoteModule.init().then(() => {
|
||||
EmoteModule.initialized = true;
|
||||
Utilities.log("Startup", "Initializing QuickEmoteMenu");
|
||||
Events.dispatch("emotes-loaded");
|
||||
// QuickEmoteMenu.init();
|
||||
});
|
||||
// window.emotePromise = EmoteModule.init().then(() => {
|
||||
// EmoteModule.initialized = true;
|
||||
// Utilities.log("Startup", "Initializing QuickEmoteMenu");
|
||||
// Events.dispatch("emotes-loaded");
|
||||
// // QuickEmoteMenu.init();
|
||||
// });
|
||||
|
||||
this.injectExternals();
|
||||
|
||||
|
@ -58,7 +57,7 @@ Core.prototype.init = async function() {
|
|||
$("#customcss").detach().appendTo(document.head);
|
||||
|
||||
// PublicServers.initialize();
|
||||
EmoteModule.autoCapitalize();
|
||||
// EmoteModule.autoCapitalize();
|
||||
|
||||
Utilities.log("Startup", "Removing Loading Icon");
|
||||
document.getElementsByClassName("bd-loaderv2")[0].remove();
|
||||
|
@ -66,10 +65,8 @@ Core.prototype.init = async function() {
|
|||
this.initObserver();
|
||||
|
||||
// Show loading errors
|
||||
if (SettingsCookie["fork-ps-1"]) {
|
||||
Utilities.log("Startup", "Collecting Startup Errors");
|
||||
Modals.showContentErrors({plugins: pluginErrors, themes: themeErrors});
|
||||
}
|
||||
Utilities.log("Startup", "Collecting Startup Errors");
|
||||
Modals.showContentErrors({plugins: pluginErrors, themes: themeErrors});
|
||||
};
|
||||
|
||||
Core.prototype.checkForGuilds = function() {
|
||||
|
|
|
@ -1,329 +0,0 @@
|
|||
import {Config, SettingsCookie, Emotes, EmoteBlacklist} from "data";
|
||||
import Utilities from "./utilities";
|
||||
import BDV2 from "./bdv2";
|
||||
import BDEmote from "../ui/emote";
|
||||
import BdApi from "./pluginapi";
|
||||
import DataStore from "./datastore";
|
||||
import {DiscordModules} from "./webpackmodules";
|
||||
import {Toasts} from "ui";
|
||||
|
||||
const bdEmoteSettingIDs = {
|
||||
TwitchGlobal: "bda-es-7",
|
||||
TwitchSubscriber: "bda-es-7",
|
||||
BTTV: "bda-es-2",
|
||||
FrankerFaceZ: "bda-es-1",
|
||||
BTTV2: "bda-es-2"
|
||||
};
|
||||
|
||||
function EmoteModule() {
|
||||
Object.defineProperty(this, "categories", {
|
||||
get: function() {
|
||||
const cats = [];
|
||||
for (const current in bdEmoteSettingIDs) {
|
||||
if (SettingsCookie[bdEmoteSettingIDs[current]]) cats.push(current);
|
||||
}
|
||||
return cats;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
EmoteModule.prototype.init = async function () {
|
||||
this.modifiers = ["flip", "spin", "pulse", "spin2", "spin3", "1spin", "2spin", "3spin", "tr", "bl", "br", "shake", "shake2", "shake3", "flap"];
|
||||
this.overrides = ["twitch", "bttv", "ffz"];
|
||||
|
||||
const emoteInfo = {
|
||||
TwitchGlobal: {
|
||||
url: "https://twitchemotes.com/api_cache/v3/global.json",
|
||||
backup: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_global.json`,
|
||||
variable: "TwitchGlobal",
|
||||
oldVariable: "emotesTwitch",
|
||||
getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e.id}/1.0`,
|
||||
getOldData: (url, name) => { return {id: url.match(/\/([0-9]+)\//)[1], code: name, emoticon_set: 0, description: null}; }
|
||||
},
|
||||
TwitchSubscriber: {
|
||||
url: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_subscriber.json`,
|
||||
variable: "TwitchSubscriber",
|
||||
oldVariable: "subEmotesTwitch",
|
||||
getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e}/1.0`,
|
||||
getOldData: (url) => url.match(/\/([0-9]+)\//)[1]
|
||||
},
|
||||
FrankerFaceZ: {
|
||||
url: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_ffz.json`,
|
||||
variable: "FrankerFaceZ",
|
||||
oldVariable: "emotesFfz",
|
||||
getEmoteURL: (e) => `https://cdn.frankerfacez.com/emoticon/${e}/1`,
|
||||
getOldData: (url) => url.match(/\/([0-9]+)\//)[1]
|
||||
},
|
||||
BTTV: {
|
||||
url: "https://api.betterttv.net/emotes",
|
||||
variable: "BTTV",
|
||||
oldVariable: "emotesBTTV",
|
||||
parser: (data) => {
|
||||
const emotes = {};
|
||||
for (let e = 0, len = data.emotes.length; e < len; e++) {
|
||||
const emote = data.emotes[e];
|
||||
emotes[emote.regex] = emote.url;
|
||||
}
|
||||
return emotes;
|
||||
},
|
||||
getEmoteURL: (e) => `${e}`,
|
||||
getOldData: (url) => url
|
||||
},
|
||||
BTTV2: {
|
||||
url: `https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv.json`,
|
||||
variable: "BTTV2",
|
||||
oldVariable: "emotesBTTV2",
|
||||
getEmoteURL: (e) => `https://cdn.betterttv.net/emote/${e}/1x`,
|
||||
getOldData: (url) => url.match(/emote\/(.+)\//)[1]
|
||||
}
|
||||
};
|
||||
|
||||
await this.getBlacklist();
|
||||
await this.loadEmoteData(emoteInfo);
|
||||
|
||||
while (!BDV2.MessageContentComponent) await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
if (this.cancelEmoteRender) return;
|
||||
this.cancelEmoteRender = Utilities.monkeyPatch(BDV2.MessageContentComponent.prototype, "render", {after: ({returnValue}) => {
|
||||
Utilities.monkeyPatch(returnValue.props, "children", {silent: true, after: ({returnValue}) => {
|
||||
if (this.categories.length == 0) return;
|
||||
const markup = returnValue.props.children[1];
|
||||
if (!markup.props.children) return;
|
||||
const nodes = markup.props.children[1];
|
||||
if (!nodes || !nodes.length) return;
|
||||
for (let n = 0; n < nodes.length; n++) {
|
||||
const node = nodes[n];
|
||||
if (typeof(node) !== "string") continue;
|
||||
const words = node.split(/([^\s]+)([\s]|$)/g);
|
||||
for (let c = 0, clen = this.categories.length; c < clen; c++) {
|
||||
for (let w = 0, wlen = words.length; w < wlen; w++) {
|
||||
const emote = words[w];
|
||||
const emoteSplit = emote.split(":");
|
||||
const emoteName = emoteSplit[0];
|
||||
let emoteModifier = emoteSplit[1] ? emoteSplit[1] : "";
|
||||
let emoteOverride = emoteModifier.slice(0);
|
||||
|
||||
if (emoteName.length < 4 || EmoteBlacklist.includes(emoteName)) continue;
|
||||
if (!this.modifiers.includes(emoteModifier) || !SettingsCookie["bda-es-8"]) emoteModifier = "";
|
||||
if (!this.overrides.includes(emoteOverride)) emoteOverride = "";
|
||||
else emoteModifier = emoteOverride;
|
||||
|
||||
let current = this.categories[c];
|
||||
if (emoteOverride === "twitch") {
|
||||
if (Emotes.TwitchGlobal[emoteName]) current = "TwitchGlobal";
|
||||
else if (Emotes.TwitchSubscriber[emoteName]) current = "TwitchSubscriber";
|
||||
}
|
||||
else if (emoteOverride === "bttv") {
|
||||
if (Emotes.BTTV[emoteName]) current = "BTTV";
|
||||
else if (Emotes.BTTV2[emoteName]) current = "BTTV2";
|
||||
}
|
||||
else if (emoteOverride === "ffz") {
|
||||
if (Emotes.FrankerFaceZ[emoteName]) current = "FrankerFaceZ";
|
||||
}
|
||||
|
||||
if (!Emotes[current][emoteName] || !SettingsCookie[bdEmoteSettingIDs[current]]) continue;
|
||||
const results = nodes[n].match(new RegExp(`([\\s]|^)${Utilities.escape(emoteModifier ? emoteName + ":" + emoteModifier : emoteName)}([\\s]|$)`));
|
||||
if (!results) continue;
|
||||
const pre = nodes[n].substring(0, results.index + results[1].length);
|
||||
const post = nodes[n].substring(results.index + results[0].length - results[2].length);
|
||||
nodes[n] = pre;
|
||||
const emoteComponent = DiscordModules.React.createElement(BDEmote, {name: emoteName, url: Emotes[current][emoteName], modifier: emoteModifier});
|
||||
nodes.splice(n + 1, 0, post);
|
||||
nodes.splice(n + 1, 0, emoteComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
const onlyEmotes = nodes.every(r => {
|
||||
if (typeof(r) == "string" && r.replace(/\s*/, "") == "") return true;
|
||||
else if (r.type && r.type.name == "BDEmote") return true;
|
||||
else if (r.props && r.props.children && r.props.children.props && r.props.children.props.emojiName) return true;
|
||||
return false;
|
||||
});
|
||||
if (!onlyEmotes) return;
|
||||
|
||||
for (const node of nodes) {
|
||||
if (typeof(node) != "object") continue;
|
||||
if (node.type.name == "BDEmote") node.props.jumboable = true;
|
||||
else if (node.props && node.props.children && node.props.children.props && node.props.children.props.emojiName) node.props.children.props.jumboable = true;
|
||||
}
|
||||
}});
|
||||
}});
|
||||
};
|
||||
|
||||
EmoteModule.prototype.disable = function() {
|
||||
this.disableAutoCapitalize();
|
||||
if (this.cancelEmoteRender) return;
|
||||
this.cancelEmoteRender();
|
||||
this.cancelEmoteRender = null;
|
||||
};
|
||||
|
||||
EmoteModule.prototype.clearEmoteData = async function() {
|
||||
const _fs = require("fs");
|
||||
const emoteFile = "emote_data.json";
|
||||
const file = Config.dataPath + emoteFile;
|
||||
const exists = _fs.existsSync(file);
|
||||
if (exists) _fs.unlinkSync(file);
|
||||
DataStore.setBDData("emoteCacheDate", (new Date()).toJSON());
|
||||
|
||||
Object.assign(Emotes, {
|
||||
TwitchGlobal: {},
|
||||
TwitchSubscriber: {},
|
||||
BTTV: {},
|
||||
FrankerFaceZ: {},
|
||||
BTTV2: {}
|
||||
});
|
||||
};
|
||||
|
||||
EmoteModule.prototype.isCacheValid = function() {
|
||||
const cacheLength = DataStore.getBDData("emoteCacheDays") || DataStore.setBDData("emoteCacheDays", 7) || 7;
|
||||
const cacheDate = new Date(DataStore.getBDData("emoteCacheDate") || null);
|
||||
const currentDate = new Date();
|
||||
const daysBetween = Math.round(Math.abs((currentDate.getTime() - cacheDate.getTime()) / (24 * 60 * 60 * 1000)));
|
||||
if (daysBetween > cacheLength) {
|
||||
DataStore.setBDData("emoteCacheDate", currentDate.toJSON());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
EmoteModule.prototype.loadEmoteData = async function(emoteInfo) {
|
||||
const _fs = require("fs");
|
||||
const emoteFile = "emote_data.json";
|
||||
const file = Config.dataPath + emoteFile;
|
||||
const exists = _fs.existsSync(file);
|
||||
|
||||
if (exists && this.isCacheValid()) {
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show("Loading emotes from cache.", {type: "info"});
|
||||
Utilities.log("Emotes", "Loading emotes from local cache.");
|
||||
|
||||
const data = await new Promise(resolve => {
|
||||
_fs.readFile(file, "utf8", (err, data) => {
|
||||
Utilities.log("Emotes", "Emotes loaded from cache.");
|
||||
if (err) data = {};
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
|
||||
let isValid = Utilities.testJSON(data);
|
||||
if (isValid) Object.assign(Emotes, JSON.parse(data));
|
||||
|
||||
for (const e in emoteInfo) {
|
||||
isValid = Object.keys(Emotes[emoteInfo[e].variable]).length > 0;
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show("Emotes successfully loaded.", {type: "success"});
|
||||
return;
|
||||
}
|
||||
|
||||
Utilities.log("Emotes", "Cache was corrupt, downloading...");
|
||||
_fs.unlinkSync(file);
|
||||
}
|
||||
|
||||
if (!SettingsCookie["fork-es-3"]) return;
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show("Downloading emotes in the background do not reload.", {type: "info"});
|
||||
|
||||
for (const e in emoteInfo) {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
const data = await this.downloadEmotes(emoteInfo[e]);
|
||||
Emotes[emoteInfo[e].variable] = data;
|
||||
}
|
||||
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show("All emotes successfully downloaded.", {type: "success"});
|
||||
|
||||
try { _fs.writeFileSync(file, JSON.stringify(Emotes), "utf8"); }
|
||||
catch (err) { Utilities.err("Emotes", "Could not save emote data.", err); }
|
||||
};
|
||||
|
||||
EmoteModule.prototype.downloadEmotes = function(emoteMeta) {
|
||||
const request = require("request");
|
||||
const options = {
|
||||
url: emoteMeta.url,
|
||||
timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000
|
||||
};
|
||||
|
||||
Utilities.log("Emotes", `Downloading: ${emoteMeta.variable} (${emoteMeta.url})`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(options, (error, response, body) => {
|
||||
if (error) {
|
||||
Utilities.err("Emotes", "Could not download " + emoteMeta.variable, error);
|
||||
if (emoteMeta.backup) {
|
||||
emoteMeta.url = emoteMeta.backup;
|
||||
emoteMeta.backup = null;
|
||||
if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser;
|
||||
return resolve(this.downloadEmotes(emoteMeta));
|
||||
}
|
||||
return reject({});
|
||||
}
|
||||
|
||||
let parsedData = {};
|
||||
try {
|
||||
parsedData = JSON.parse(body);
|
||||
}
|
||||
catch (err) {
|
||||
Utilities.err("Emotes", "Could not download " + emoteMeta.variable, err);
|
||||
if (emoteMeta.backup) {
|
||||
emoteMeta.url = emoteMeta.backup;
|
||||
emoteMeta.backup = null;
|
||||
if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser;
|
||||
return resolve(this.downloadEmotes(emoteMeta));
|
||||
}
|
||||
return reject({});
|
||||
}
|
||||
if (typeof(emoteMeta.parser) === "function") parsedData = emoteMeta.parser(parsedData);
|
||||
|
||||
for (const emote in parsedData) {
|
||||
if (emote.length < 4 || EmoteBlacklist.includes(emote)) {
|
||||
delete parsedData[emote];
|
||||
continue;
|
||||
}
|
||||
parsedData[emote] = emoteMeta.getEmoteURL(parsedData[emote]);
|
||||
}
|
||||
resolve(parsedData);
|
||||
Utilities.log("Emotes", "Downloaded: " + emoteMeta.variable);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
EmoteModule.prototype.getBlacklist = function () {
|
||||
return new Promise(resolve => {
|
||||
$.getJSON(`https://rauenzi.github.io/BetterDiscordApp/data/emotefilter.json`, function (data) {
|
||||
resolve(EmoteBlacklist.push(...data.blacklist));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
EmoteModule.prototype.autoCapitalize = function () {
|
||||
if (!SettingsCookie["bda-es-4"] || this.autoCapitalizeActive) return;
|
||||
$("body").on("keyup.bdac change.bdac paste.bdac", $(".channelTextArea-1LDbYG textarea:first"), () => {
|
||||
const text = $(".channelTextArea-1LDbYG textarea:first").val();
|
||||
if (text == undefined) return;
|
||||
|
||||
const lastWord = text.split(" ").pop();
|
||||
if (lastWord.length > 3) {
|
||||
if (lastWord == "danSgame") return;
|
||||
const ret = this.capitalize(lastWord.toLowerCase());
|
||||
if (ret !== null && ret !== undefined) {
|
||||
Utilities.insertText(Utilities.getTextArea()[0], text.replace(lastWord, ret));
|
||||
}
|
||||
}
|
||||
});
|
||||
this.autoCapitalizeActive = true;
|
||||
};
|
||||
|
||||
EmoteModule.prototype.capitalize = function (value) {
|
||||
const res = Emotes.TwitchGlobal;
|
||||
for (const p in res) {
|
||||
if (res.hasOwnProperty(p) && value == (p + "").toLowerCase()) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EmoteModule.prototype.disableAutoCapitalize = function() {
|
||||
this.autoCapitalizeActive = false;
|
||||
$("body").off(".bdac");
|
||||
};
|
||||
|
||||
export default new EmoteModule();
|
|
@ -11,7 +11,7 @@ import ContentManager from "./contentmanager";
|
|||
import DataStore from "./datastore";
|
||||
// import DevMode from "./devmode";
|
||||
import Events from "./emitter";
|
||||
import EmoteModule from "./emotes";
|
||||
// import EmoteModule from "./emotes";
|
||||
import PluginManager from "./pluginmanager";
|
||||
// import PublicServers from "./publicservers";
|
||||
import ThemeManager from "./thememanager";
|
||||
|
@ -20,7 +20,7 @@ export const React = DiscordModules.React;
|
|||
export const ReactDOM = DiscordModules.ReactDOM;
|
||||
|
||||
export {BDV2, BdApi, Core, ContentManager, DataStore,
|
||||
Events, EmoteModule, PluginManager, /*PublicServers,*/ ThemeManager,
|
||||
Events, PluginManager, /*PublicServers,*/ ThemeManager,
|
||||
Utilities, WebpackModules, DiscordModules};
|
||||
|
||||
|
||||
|
|
|
@ -100,7 +100,16 @@ BdApi.showConfirmationModal = function (title, content, options = {}) {
|
|||
return Modals.showConfirmationModal(title, content, options);
|
||||
};
|
||||
|
||||
//Show toast alert
|
||||
/**
|
||||
* This shows a toast similar to android towards the bottom of the screen.
|
||||
*
|
||||
* @param {string} content The string to show in the toast.
|
||||
* @param {object} options Options object. Optional parameter.
|
||||
* @param {string} [options.type=""] Changes the type of the toast stylistically and semantically. Choices: "", "info", "success", "danger"/"error", "warning"/"warn". Default: ""
|
||||
* @param {boolean} [options.icon=true] Determines whether the icon should show corresponding to the type. A toast without type will always have no icon. Default: true
|
||||
* @param {number} [options.timeout=3000] Adjusts the time (in ms) the toast should be shown for before disappearing automatically. Default: 3000
|
||||
* @param {boolean} [options.forceShow=false] Whether to force showing the toast and ignore the bd setting
|
||||
*/
|
||||
BdApi.showToast = function(content, options = {}) {
|
||||
Toasts.show(content, options);
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ PluginModule.prototype.loadPlugins = function () {
|
|||
if (PluginCookie[name]) {
|
||||
try {
|
||||
plugin.start();
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin.getName()} v${plugin.getVersion()} has started.`);
|
||||
Toasts.show(`${plugin.getName()} v${plugin.getVersion()} has started.`);
|
||||
}
|
||||
catch (err) {
|
||||
PluginCookie[name] = false;
|
||||
|
@ -52,10 +52,10 @@ PluginModule.prototype.loadPlugins = function () {
|
|||
PluginModule.prototype.startPlugin = function(plugin, reload = false) {
|
||||
try {
|
||||
Plugins[plugin].plugin.start();
|
||||
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has started.`);
|
||||
if (!reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has started.`);
|
||||
}
|
||||
catch (err) {
|
||||
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be started.`, {type: "error"});
|
||||
if (!reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be started.`, {type: "error"});
|
||||
PluginCookie[plugin] = false;
|
||||
this.savePluginData();
|
||||
Utilities.err("Plugins", plugin + " could not be started.", err);
|
||||
|
@ -65,10 +65,10 @@ PluginModule.prototype.startPlugin = function(plugin, reload = false) {
|
|||
PluginModule.prototype.stopPlugin = function(plugin, reload = false) {
|
||||
try {
|
||||
Plugins[plugin].plugin.stop();
|
||||
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has stopped.`);
|
||||
if (!reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} has stopped.`);
|
||||
}
|
||||
catch (err) {
|
||||
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Plugins[plugin].plugin.getName()} v${Plugins[plugin].plugin.getVersion()} could not be stopped.`, {type: "error"});
|
||||
if (!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);
|
||||
}
|
||||
};
|
||||
|
@ -95,15 +95,15 @@ PluginModule.prototype.togglePlugin = function (plugin) {
|
|||
PluginModule.prototype.loadPlugin = function(filename) {
|
||||
const error = ContentManager.loadContent(filename, "plugin");
|
||||
if (error) {
|
||||
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [error]});
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${filename} could not be loaded.`, {type: "error"});
|
||||
Modals.showContentErrors({plugins: [error]});
|
||||
Toasts.show(`${filename} could not be loaded.`, {type: "error"});
|
||||
return Utilities.err("ContentManager", `${filename} could not be loaded.`, error);
|
||||
}
|
||||
const plugin = Object.values(Plugins).find(p => p.filename == filename).plugin;
|
||||
try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();}
|
||||
catch (err) {if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [err]});}
|
||||
catch (err) {Modals.showContentErrors({plugins: [err]});}
|
||||
Utilities.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`);
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin.getName()} v${plugin.getVersion()} was loaded.`, {type: "success"});
|
||||
Toasts.show(`${plugin.getName()} v${plugin.getVersion()} was loaded.`, {type: "success"});
|
||||
Emitter.dispatch("plugin-loaded", plugin.getName());
|
||||
};
|
||||
|
||||
|
@ -115,12 +115,12 @@ PluginModule.prototype.unloadPlugin = function(filenameOrName) {
|
|||
const error = ContentManager.unloadContent(Plugins[plugin].filename, "plugin");
|
||||
delete Plugins[plugin];
|
||||
if (error) {
|
||||
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [error]});
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
|
||||
Modals.showContentErrors({plugins: [error]});
|
||||
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);
|
||||
}
|
||||
Utilities.log("ContentManager", `${plugin} was unloaded.`);
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} was unloaded.`, {type: "success"});
|
||||
Toasts.show(`${plugin} was unloaded.`, {type: "success"});
|
||||
Emitter.dispatch("plugin-unloaded", plugin);
|
||||
};
|
||||
|
||||
|
@ -132,14 +132,14 @@ PluginModule.prototype.reloadPlugin = function(filenameOrName) {
|
|||
if (enabled) this.stopPlugin(plugin, true);
|
||||
const error = ContentManager.reloadContent(Plugins[plugin].filename, "plugin");
|
||||
if (error) {
|
||||
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({plugins: [error]});
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} could not be reloaded.`, {type: "error"});
|
||||
Modals.showContentErrors({plugins: [error]});
|
||||
Toasts.show(`${plugin} could not be reloaded.`, {type: "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 (enabled) this.startPlugin(plugin, true);
|
||||
Utilities.log("ContentManager", `${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`);
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`, {type: "success"});
|
||||
Toasts.show(`${plugin} v${Plugins[plugin].plugin.getVersion()} was reloaded.`, {type: "success"});
|
||||
Emitter.dispatch("plugin-reloaded", plugin);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import {SettingsCookie} from "data";
|
|||
import DataStore from "./datastore";
|
||||
import ContentManager from "./contentmanager";
|
||||
import BdApi from "./pluginapi";
|
||||
import EmoteModule from "./emotes";
|
||||
// import EmoteModule from "./emotes";
|
||||
import Events from "./emitter";
|
||||
import WebpackModules from "./webpackmodules";
|
||||
|
||||
|
@ -83,10 +83,10 @@ export default new class SettingsPanel {
|
|||
SettingsCookie[id] = enabled;
|
||||
|
||||
|
||||
if (id == "bda-es-4") {
|
||||
if (enabled) EmoteModule.autoCapitalize();
|
||||
else EmoteModule.disableAutoCapitalize();
|
||||
}
|
||||
// if (id == "bda-es-4") {
|
||||
// if (enabled) EmoteModule.autoCapitalize();
|
||||
// else EmoteModule.disableAutoCapitalize();
|
||||
// }
|
||||
|
||||
if (id == "fork-ps-5") {
|
||||
if (enabled) {
|
||||
|
@ -109,7 +109,7 @@ export default new class SettingsPanel {
|
|||
}
|
||||
|
||||
initializeSettings() {
|
||||
if (SettingsCookie["bda-es-4"]) EmoteModule.autoCapitalize();
|
||||
// if (SettingsCookie["bda-es-4"]) EmoteModule.autoCapitalize();
|
||||
|
||||
if (SettingsCookie["fork-ps-5"]) {
|
||||
ContentManager.watchContent("plugin");
|
||||
|
|
|
@ -31,14 +31,14 @@ ThemeModule.prototype.enableTheme = function(theme, reload = false) {
|
|||
ThemeCookie[theme] = true;
|
||||
this.saveThemeData();
|
||||
$("head").append($("<style>", {id: Utilities.escapeID(theme), text: unescape(Themes[theme].css)}));
|
||||
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been applied.`);
|
||||
if (!reload) Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been applied.`);
|
||||
};
|
||||
|
||||
ThemeModule.prototype.disableTheme = function(theme, reload = false) {
|
||||
ThemeCookie[theme] = false;
|
||||
this.saveThemeData();
|
||||
$(`#${Utilities.escapeID(Themes[theme].name)}`).remove();
|
||||
if (SettingsCookie["fork-ps-2"] && !reload) Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been disabled.`);
|
||||
if (!reload) Toasts.show(`${Themes[theme].name} v${Themes[theme].version} has been disabled.`);
|
||||
};
|
||||
|
||||
ThemeModule.prototype.toggleTheme = function(theme) {
|
||||
|
@ -49,13 +49,13 @@ ThemeModule.prototype.toggleTheme = function(theme) {
|
|||
ThemeModule.prototype.loadTheme = function(filename) {
|
||||
const error = ContentManager.loadContent(filename, "theme");
|
||||
if (error) {
|
||||
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({themes: [error]});
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${filename} could not be loaded. It may not have been loaded.`, {type: "error"});
|
||||
Modals.showContentErrors({themes: [error]});
|
||||
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);
|
||||
}
|
||||
const theme = Object.values(Themes).find(p => p.filename == filename);
|
||||
Utilities.log("ContentManager", `${theme.name} v${theme.version} was loaded.`);
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme.name} v${theme.version} was loaded.`, {type: "success"});
|
||||
Toasts.show(`${theme.name} v${theme.version} was loaded.`, {type: "success"});
|
||||
Emitter.dispatch("theme-loaded", theme.name);
|
||||
};
|
||||
|
||||
|
@ -67,12 +67,12 @@ ThemeModule.prototype.unloadTheme = function(filenameOrName) {
|
|||
const error = ContentManager.unloadContent(Themes[theme].filename, "theme");
|
||||
delete Themes[theme];
|
||||
if (error) {
|
||||
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({themes: [error]});
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
|
||||
Modals.showContentErrors({themes: [error]});
|
||||
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);
|
||||
}
|
||||
Utilities.log("ContentManager", `${theme} was unloaded.`);
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} was unloaded.`, {type: "success"});
|
||||
Toasts.show(`${theme} was unloaded.`, {type: "success"});
|
||||
Emitter.dispatch("theme-unloaded", theme);
|
||||
};
|
||||
|
||||
|
@ -83,12 +83,12 @@ ThemeModule.prototype.reloadTheme = function(filenameOrName) {
|
|||
const error = ContentManager.reloadContent(Themes[theme].filename, "theme");
|
||||
if (ThemeCookie[theme]) this.disableTheme(theme, true), this.enableTheme(theme, true);
|
||||
if (error) {
|
||||
if (SettingsCookie["fork-ps-1"]) Modals.showContentErrors({themes: [error]});
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} could not be reloaded.`, {type: "error"});
|
||||
Modals.showContentErrors({themes: [error]});
|
||||
Toasts.show(`${theme} could not be reloaded.`, {type: "error"});
|
||||
return Utilities.err("ContentManager", `${theme} could not be reloaded.`, error);
|
||||
}
|
||||
Utilities.log("ContentManager", `${theme} v${Themes[theme].version} was reloaded.`);
|
||||
if (SettingsCookie["fork-ps-2"]) Toasts.show(`${theme} v${Themes[theme].version} was reloaded.`, {type: "success"});
|
||||
Toasts.show(`${theme} v${Themes[theme].version} was reloaded.`, {type: "success"});
|
||||
Emitter.dispatch("theme-reloaded", theme);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import {SettingsCookie} from "data";
|
||||
import {Utilities, WebpackModules, React} from "modules";
|
||||
|
||||
export default class Modals {
|
||||
|
||||
static get shouldShowContentErrors() {return SettingsCookie["fork-ps-1"];}
|
||||
|
||||
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");}
|
||||
|
@ -86,7 +89,7 @@ export default class Modals {
|
|||
}
|
||||
|
||||
static showContentErrors({plugins: pluginErrors = [], themes: themeErrors = []}) {
|
||||
if (!pluginErrors || !themeErrors) return;
|
||||
if (!pluginErrors || !themeErrors || !this.shouldShowContentErrors) return;
|
||||
if (!pluginErrors.length && !themeErrors.length) return;
|
||||
const modal = $(`<div class="bd-modal-wrapper theme-dark">
|
||||
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {SettingsInfo, SettingsCookie, Plugins, Themes} from "data";
|
||||
import {React, ReactDOM, Utilities, ContentManager, Events, EmoteModule, PluginManager, ThemeManager} from "modules";
|
||||
import {React, ReactDOM, Utilities, ContentManager, Events, PluginManager, ThemeManager} from "modules";
|
||||
import Sidebar from "./sidebar";
|
||||
import Scroller from "../scroller";
|
||||
import List from "../list";
|
||||
|
@ -117,7 +117,7 @@ export default class V2_SettingsPanel {
|
|||
contentColumn: true, fade: true, dark: true, children: [
|
||||
React.createElement(SettingsPanel, {key: "espanel", title: "Emote Settings", onChange: this.onChange, settings: this.emoteSettings, button: {
|
||||
title: "Clear Emote Cache",
|
||||
onClick: () => { EmoteModule.clearEmoteData(); EmoteModule.init(); }
|
||||
onClick: () => { Events.dispatch("emotes-clear"); /*EmoteModule.clearEmoteData(); EmoteModule.init();*/ }
|
||||
}}),
|
||||
React.createElement(Tools, {key: "tools"})
|
||||
]});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import {SettingsCookie} from "data";
|
||||
import {WebpackModules} from "modules";
|
||||
|
||||
const channelsClass = WebpackModules.getByProps("channels").channels.split(" ")[0];
|
||||
|
@ -5,6 +6,8 @@ const membersWrapClass = WebpackModules.getByProps("membersWrap").membersWrap.sp
|
|||
|
||||
export default class Toasts {
|
||||
|
||||
static get shouldShowToasts() {return SettingsCookie["fork-ps-2"];}
|
||||
|
||||
/** Shorthand for `type = "success"` for {@link module:Toasts.show} */
|
||||
static async success(content, options = {}) {return this.show(content, Object.assign(options, {type: "success"}));}
|
||||
|
||||
|
@ -25,13 +28,15 @@ export default class Toasts {
|
|||
*
|
||||
* @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
|
||||
* @param {string} [options.type=""] Changes the type of the toast stylistically and semantically. Choices: "", "info", "success", "danger"/"error", "warning"/"warn". Default: ""
|
||||
* @param {boolean} [options.icon=true] Determines whether the icon should show corresponding to the type. A toast without type will always have no icon. Default: true
|
||||
* @param {number} [options.timeout=3000] Adjusts the time (in ms) the toast should be shown for before disappearing automatically. Default: 3000
|
||||
* @param {boolean} [options.forceShow=false] Whether to force showing the toast and ignore the bd setting
|
||||
*/
|
||||
static show(content, options = {}) {
|
||||
const {type = "", icon = true, timeout = 3000, forceShow = false} = options;
|
||||
if (!this.shouldShowToasts && !forceShow) return;
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue