BetterDiscordApp-rauenzi/js/main.js

4099 lines
140 KiB
JavaScript
Raw Normal View History

2015-08-27 15:46:53 +02:00
/* BetterDiscordApp Core JavaScript
2017-04-30 03:11:22 +02:00
* Version: 1.78
2015-08-27 15:46:53 +02:00
* Author: Jiiks | http://jiiks.net
* Date: 27/08/2015 - 16:36
* Last Update: 01/05/2016
2015-08-27 15:46:53 +02:00
* https://github.com/Jiiks/BetterDiscordApp
*/
2017-01-09 06:41:36 +01:00
2018-01-09 04:24:00 +01:00
/* global Proxy, bdplugins, bdthemes, betterDiscordIPC, bdVersion, version, BDV2, webpackJsonp */
2017-11-03 04:05:33 +01:00
/* eslint-disable no-console */
/*Localstorage fix*/
(function() {
let __fs = window.require("fs");
2017-01-22 19:00:24 +01:00
let __process = window.require("process");
let __platform = __process.platform;
let __dataPath = (__platform === 'win32' ? __process.env.APPDATA : __platform === 'darwin' ? __process.env.HOME + '/Library/Preferences' : process.env.HOME + '/.config') + '/BetterDiscord/';
2018-01-09 04:24:00 +01:00
let localStorageFile = "localStorage.json";
2017-01-22 19:00:24 +01:00
let __data = {};
2018-01-09 04:24:00 +01:00
if(__fs.existsSync(`${__dataPath}${localStorageFile}`)) {
2017-01-22 19:00:24 +01:00
try {
2018-01-09 04:24:00 +01:00
__data = JSON.parse(__fs.readFileSync(`${__dataPath}${localStorageFile}`));
2017-01-22 19:00:24 +01:00
}catch(err) {
console.log(err);
}
2018-01-09 04:24:00 +01:00
} else if(__fs.existsSync(localStorageFile)) {
try {
2018-01-09 04:24:00 +01:00
__data = JSON.parse(__fs.readFileSync(localStorageFile));
2017-01-11 10:23:15 +01:00
}catch(err) {
console.log(err);
}
}
var __ls = __data;
__ls.setItem = function(i, v) {
__ls[i] = v;
this.save();
};
__ls.getItem = function(i) {
return __ls[i] || null;
};
__ls.save = function() {
2018-01-09 04:24:00 +01:00
__fs.writeFileSync(`${__dataPath}${localStorageFile}`, JSON.stringify(this), null, 4);
};
var __proxy = new Proxy(__ls, {
2017-11-03 04:05:33 +01:00
set: function(target, name, val) {
__ls[name] = val;
__ls.save();
},
2017-11-03 04:05:33 +01:00
get: function(target, name) {
return __ls[name] || null;
}
});
window.localStorage = __proxy;
})();
2017-04-30 03:11:22 +02:00
(() => {
let v2Loader = document.createElement('div');
v2Loader.className = "bd-loaderv2";
v2Loader.title = "BetterDiscord is loading...";
document.body.appendChild(v2Loader);
})();
2018-03-15 15:30:14 +01:00
2017-01-09 06:41:36 +01:00
window.bdStorage = {};
window.bdStorage.get = function(i) {
return betterDiscordIPC.sendSync('synchronous-message', { 'arg': 'storage', 'cmd': 'get', 'var': i });
};
window.bdStorage.set = function(i, v) {
betterDiscordIPC.sendSync('synchronous-message', { 'arg': 'storage', 'cmd': 'set', 'var': i, 'data': v });
};
window.bdPluginStorage = {};
window.bdPluginStorage.get = function(pn, i) {
return betterDiscordIPC.sendSync('synchronous-message', { 'arg': 'pluginstorage', 'cmd': 'get', 'pn': pn, 'var': i });
};
window.bdPluginStorage.set = function(pn, i, v) {
betterDiscordIPC.sendSync('synchronous-message', { 'arg': 'pluginstorage', 'cmd': 'set', 'pn': pn, 'var': i, 'data': v });
};
betterDiscordIPC.on('asynchronous-reply', (event, arg) => {
console.log(event);
console.log(arg);
});
2018-01-09 04:24:00 +01:00
var settingsPanel, emoteModule, utils, quickEmoteMenu, voiceMode, pluginModule, themeModule, dMode, publicServersModule;
2017-06-17 19:08:43 +02:00
var jsVersion = 1.792;
2017-01-09 09:38:52 +01:00
var supportedVersion = "0.2.81";
2018-03-15 15:30:14 +01:00
var bbdVersion = "0.0.6";
2015-08-29 11:36:47 +02:00
var mainObserver;
2015-08-27 15:46:53 +02:00
var twitchEmoteUrlStart = "https://static-cdn.jtvnw.net/emoticons/v1/";
var twitchEmoteUrlEnd = "/1.0";
var ffzEmoteUrlStart = "https://cdn.frankerfacez.com/emoticon/";
var ffzEmoteUrlEnd = "/1";
2015-12-10 04:01:24 +01:00
var bttvEmoteUrlStart = "https://cdn.betterttv.net/emote/";
var bttvEmoteUrlEnd = "/1x";
2015-08-27 15:46:53 +02:00
var mainCore;
2015-08-27 15:46:53 +02:00
2015-08-29 11:36:47 +02:00
var settings = {
"Save logs locally": { "id": "bda-gs-0", "info": "Saves chat logs locally", "implemented": false, "hidden": false, "cat": "core"},
2018-02-28 08:25:06 +01:00
"Public Servers": { "id": "bda-gs-1", "info": "Display public servers button", "implemented": true, "hidden": false, "cat": "core"},
2017-10-30 22:24:54 +01:00
"Minimal Mode": { "id": "bda-gs-2", "info": "Hide elements and reduce the size of elements.", "implemented": true, "hidden": false, "cat": "core"},
"Voice Mode": { "id": "bda-gs-4", "info": "Only show voice chat", "implemented": true, "hidden": false, "cat": "core"},
2017-10-30 22:24:54 +01:00
"Hide Channels": { "id": "bda-gs-3", "info": "Hide channels in minimal mode", "implemented": true, "hidden": false, "cat": "core"},
"Dark Mode": { "id": "bda-gs-5", "info": "Make certain elements dark by default(wip)", "implemented": true, "hidden": false, "cat": "core"},
"Override Default Emotes": { "id": "bda-es-5", "info": "Override default emotes", "implemented": false, "hidden": false, "cat": "core"},
"Voice Disconnect": { "id": "bda-dc-0", "info": "Disconnect from voice server when closing Discord", "implemented": true, "hidden": false, "cat": "core"},
"Custom css live update": { "id": "bda-css-0", "info": "", "implemented": true, "hidden": true, "cat": "core"},
"Custom css auto udpate": { "id": "bda-css-1", "info": "", "implemented": true, "hidden": true, "cat": "core"},
"24 Hour Timestamps": { "id": "bda-gs-6", "info": "Replace 12hr timestamps with proper ones", "implemented": true, "hidden": false, "cat": "core"},
"Coloured Text": { "id": "bda-gs-7", "info": "Make text colour the same as role colour", "implemented": true, "hidden": false, "cat": "core"},
2017-04-30 03:11:22 +02:00
"BetterDiscord Blue": { "id": "bda-gs-b", "info": "Replace Discord blue with BD Blue", "implemented": true, "hidden": false, "cat": "core"},
"Developer Mode": { "id": "bda-gs-8", "info": "Developer Mode", "implemented": true, "hidden": false, "cat": "core"},
2017-12-24 07:51:24 +01:00
"Startup Error Modal": { "id": "fork-ps-1", "info": "Show a modal with plugin/theme errors on startup", "implemented": true, "hidden": false, "cat": "fork"},
"Show Toasts": { "id": "fork-ps-2", "info": "Shows a small notification for starting and stopping plugins & themes", "implemented": true, "hidden": false, "cat": "fork"},
"Scroll To Settings": { "id": "fork-ps-3", "info": "Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)", "implemented": true, "hidden": false, "cat": "fork"},
2017-12-24 07:51:24 +01:00
"Emote Modifier Tooltip": { "id": "fork-es-1", "info": "Shows the emote modifier in the tooltip.", "implemented": true, "hidden": false, "cat": "fork"},
"Animate On Hover": { "id": "fork-es-2", "info": "Only animate the emote modifiers on hover", "implemented": true, "hidden": false, "cat": "fork"},
"Copy Selector": { "id": "fork-dm-1", "info": "Adds a \"Copy Selector\" option to context menus when developer mode is active", "implemented": true, "hidden": false, "cat": "fork"},
"Twitch Emotes": { "id": "bda-es-7", "info": "Show Twitch emotes", "implemented": true, "hidden": false, "cat": "emote"},
"FrankerFaceZ Emotes": { "id": "bda-es-1", "info": "Show FrankerFaceZ Emotes", "implemented": true, "hidden": false, "cat": "emote"},
"BetterTTV Emotes": { "id": "bda-es-2", "info": "Show BetterTTV Emotes", "implemented": true, "hidden": false, "cat": "emote"},
"Emote Menu": { "id": "bda-es-0", "info": "Show Twitch/Favourite emotes in emote menu", "implemented": true, "hidden": false, "cat": "emote"},
"Emoji Menu": { "id": "bda-es-9", "info": "Show Discord emoji menu", "implemented": true, "hidden": false, "cat": "emote"},
"Emote Autocomplete": { "id": "bda-es-3", "info": "Autocomplete emote commands", "implemented": false, "hidden": false, "cat": "emote"},
"Emote Auto Capitalization": { "id": "bda-es-4", "info": "Autocapitalize emote commands", "implemented": true, "hidden": false, "cat": "emote"},
"Show Names": { "id": "bda-es-6", "info": "Show emote names on hover", "implemented": true, "hidden": false, "cat": "emote"},
"Show emote modifiers": { "id": "bda-es-8", "info": "Enable emote mods (flip, spin, pulse, spin2, spin3, 1spin, 2spin, 3spin, tr, bl, br, shake, shake2, shake3, flap)", "implemented": true, "hidden": false, "cat": "emote"},
2016-01-08 16:33:43 +01:00
};
2015-08-29 11:36:47 +02:00
var defaultCookie = {
2016-01-08 16:33:43 +01:00
"version": jsVersion,
"bda-gs-0": false,
2018-03-29 09:56:07 +02:00
"bda-gs-1": true,
2015-12-23 22:48:59 +01:00
"bda-gs-2": false,
"bda-gs-3": false,
"bda-gs-4": false,
2016-04-09 14:51:59 +02:00
"bda-gs-5": true,
"bda-gs-6": false,
"bda-gs-7": false,
"bda-gs-8": false,
"bda-es-0": true,
2015-12-23 09:56:16 +01:00
"bda-es-1": true,
2015-12-23 22:48:59 +01:00
"bda-es-2": true,
"bda-es-3": false,
"bda-es-4": false,
"bda-es-5": true,
"bda-es-6": true,
"bda-es-7": true,
2017-04-30 03:11:22 +02:00
"bda-gs-b": true,
2016-04-02 09:56:19 +02:00
"bda-es-8": true,
"bda-jd": true,
"bda-dc-0": false,
"bda-css-0": false,
2016-04-09 08:04:34 +02:00
"bda-css-1": false,
2017-12-24 07:51:24 +01:00
"bda-es-9": true,
"fork-dm-1": false,
"fork-ps-1": true,
"fork-ps-2": true,
"fork-ps-3": true,
"fork-es-1": true,
"fork-es-2": false,
2018-03-29 09:56:07 +02:00
"fork-pub-notice": false
};
2015-08-29 11:36:47 +02:00
var settingsCookie = {};
2015-08-27 15:46:53 +02:00
2017-11-03 21:01:49 +01:00
var bdpluginErrors, bdthemeErrors; // define for backwards compatibility
2018-01-09 04:24:00 +01:00
var bdConfig = null;
function Core(config) {
if (!config) {
config = {
branch: "master",
repo: "rauenzi",
updater: {
CDN: "cdn.rawgit.com"
}
}
}
else config.newLoader = true;
window.bdConfig = config;
}
2015-08-27 15:46:53 +02:00
2018-03-15 15:30:14 +01:00
Core.prototype.init = async function() {
var self = this;
var lVersion = (typeof(version) === "undefined") ? bdVersion : version;
if (lVersion < supportedVersion) {
this.alert("Not Supported", "BetterDiscord v" + lVersion + "(your version)" + " is not supported by the latest js(" + jsVersion + ").<br><br> Please download the latest version from <a href='https://betterdiscord.net' target='_blank'>BetterDiscord.net</a>");
return;
}
2015-08-29 11:36:47 +02:00
2015-08-27 15:46:53 +02:00
utils = new Utils();
2015-11-01 12:37:04 +01:00
utils.getHash();
2018-01-09 04:24:00 +01:00
publicServersModule = new V2_PublicServers();
2015-08-27 15:46:53 +02:00
quickEmoteMenu = new QuickEmoteMenu();
voiceMode = new VoiceMode();
dMode = new devMode();
2015-08-27 15:46:53 +02:00
utils.log("Initializing Settings");
2015-08-29 11:36:47 +02:00
this.initSettings();
//Incase were too fast
function gwDefer() {
2018-03-15 15:30:14 +01:00
//console.log(new Date().getTime() + " Defer");
2017-10-29 08:00:33 +01:00
if (document.querySelectorAll('.guilds .guild').length > 0) {
2018-03-15 15:30:14 +01:00
//console.log(new Date().getTime() + " Defer Loaded");
emoteModule = new EmoteModule();
utils.log("Initializing EmoteModule");
emoteModule.init();
2017-11-01 06:43:07 +01:00
self.injectExternals();
2018-01-09 22:32:02 +01:00
2018-01-20 02:17:52 +01:00
utils.log("Updating Settings");
settingsPanel = new V2_SettingsPanel();
settingsPanel.updateSettings();
// Add check for backwards compatibility
2017-11-03 21:02:50 +01:00
if (!bdpluginErrors) bdpluginErrors = [];
if (!bdthemeErrors) bdthemeErrors = [];
utils.log("Loading Plugins");
2015-12-12 07:07:56 +01:00
pluginModule = new PluginModule();
pluginModule.loadPlugins();
2018-02-28 08:25:06 +01:00
utils.log("Loading Themes");
2018-02-28 08:25:06 +01:00
themeModule = new ThemeModule();
themeModule.loadThemes();
2015-12-12 07:07:56 +01:00
2018-02-28 08:25:06 +01:00
$("#customcss").detach().appendTo(document.head);
utils.log("Initializing QuickEmoteMenu");
2018-01-09 22:32:02 +01:00
quickEmoteMenu.init();
window.addEventListener("beforeunload", function(){
if(settingsCookie["bda-dc-0"]){
2017-10-29 21:33:48 +01:00
document.querySelector('.btn.btn-disconnect').click();
}
});
2018-01-09 04:24:00 +01:00
publicServersModule.initialize();
emoteModule.autoCapitalize();
/*Display new features in BetterDiscord*/
2016-01-08 16:33:43 +01:00
if (settingsCookie["version"] < jsVersion) {
2017-10-30 01:00:34 +01:00
//var cl = self.constructChangelog();
settingsCookie["version"] = jsVersion;
self.saveSettings();
}
2015-12-27 16:39:10 +01:00
utils.log("Removing Loading Icon");
2017-04-30 03:11:22 +02:00
document.getElementsByClassName("bd-loaderv2")[0].remove();
2018-02-28 08:25:06 +01:00
utils.log("Initializing Main Observer");
self.initObserver();
// Show loading errors
2017-12-24 07:51:24 +01:00
if (settingsCookie["fork-ps-1"]) {
utils.log("Collecting Startup Errors");
2017-11-03 18:54:47 +01:00
self.showStartupErrors();
}
2018-03-29 09:56:07 +02:00
if (!bdStorage.get("publicServerNotice")) {
settingsCookie["bda-gs-1"] = true;
settingsPanel.updateSettings();
self.alert("Public Servers Fixed!", "Hey there!<br><br>I just overhauled and fixed the public servers module. Since it was broken for a long time, I've enabled it for you and I suggest you go ahead and check it out!");
bdStorage.set("publicServerNotice", true);
}
2015-08-31 15:20:33 +02:00
} else {
setTimeout(gwDefer, 100);
2015-08-31 15:20:33 +02:00
}
}
2015-08-31 15:59:34 +02:00
2016-01-08 16:33:43 +01:00
$(document).ready(function () {
setTimeout(gwDefer, 1000);
});
};
2015-08-27 15:46:53 +02:00
2017-11-01 06:28:53 +01:00
Core.prototype.injectExternals = function() {
utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js")
2017-11-01 06:28:53 +01:00
};
2016-01-08 16:33:43 +01:00
Core.prototype.initSettings = function () {
if ($.cookie("better-discord") == undefined) {
2015-08-29 11:36:47 +02:00
settingsCookie = defaultCookie;
this.saveSettings();
} else {
this.loadSettings();
2017-11-09 14:23:20 +01:00
$('<style id="customcss">').html(atob(window.bdStorage.get("bdcustomcss"))).appendTo(document.head);
2016-01-08 16:33:43 +01:00
for (var setting in defaultCookie) {
if (settingsCookie[setting] == undefined) {
settingsCookie[setting] = defaultCookie[setting];
2015-08-29 11:36:47 +02:00
this.saveSettings();
}
2015-08-27 15:46:53 +02:00
}
}
};
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
Core.prototype.saveSettings = function () {
$.cookie("better-discord", JSON.stringify(settingsCookie), {
expires: 365,
path: '/'
});
};
2015-08-29 11:36:47 +02:00
2016-01-08 16:33:43 +01:00
Core.prototype.loadSettings = function () {
2015-08-29 11:36:47 +02:00
settingsCookie = JSON.parse($.cookie("better-discord"));
};
2016-04-09 08:04:34 +02:00
2016-01-08 16:33:43 +01:00
Core.prototype.initObserver = function () {
mainObserver = new MutationObserver((mutations) => {
for (let i = 0; i < mutations.length; i++) {
let mutation = mutations[i];
if (typeof pluginModule !== "undefined") pluginModule.rawObserver(mutation);
2017-10-30 22:04:48 +01:00
// onSwitch()
// leaving Activity Feed/Friends menu
2017-10-30 21:53:27 +01:00
if (mutation.removedNodes.length && mutation.removedNodes[0] instanceof Element) {
let node = mutation.removedNodes[0];
if (node.classList.contains("activityFeed-HeiGwL") || node.id === "friends") {
pluginModule.channelSwitch();
}
2017-10-30 21:53:27 +01:00
}
2017-10-30 22:04:48 +01:00
// if there was nothing added, skip
2017-10-30 21:53:27 +01:00
if (!mutation.addedNodes.length || !(mutation.addedNodes[0] instanceof Element)) return;
2017-10-30 21:53:27 +01:00
let node = mutation.addedNodes[0];
if (node.classList.contains("layer") || node.classList.contains("layer-kosS71")) {
if (node.getElementsByClassName("guild-settings-base-section").length) node.setAttribute('layer-id', 'server-settings');
2017-12-24 07:51:24 +01:00
if (node.getElementsByClassName("socialLinks-1oZoF3").length) {
2017-11-01 06:28:53 +01:00
node.setAttribute('layer-id', 'user-settings');
if (!document.getElementById("bd-settings-sidebar")) settingsPanel.renderSidebar();
2017-11-01 06:28:53 +01:00
}
}
2017-10-30 22:04:48 +01:00
// Emoji Picker
if (node.classList.contains('popout') && !node.classList.contains('popout-left')) {
2018-01-09 22:32:02 +01:00
if (node.getElementsByClassName('emoji-picker').length || node.getElementsByClassName('emojiPicker-3g68GS').length) quickEmoteMenu.obsCallback(node);
2017-10-30 22:04:48 +01:00
}
2017-10-30 22:04:48 +01:00
// onSwitch()
// Not a channel, but still a switch (Activity Feed/Friends menu/NSFW check)
2017-11-03 18:34:26 +01:00
if (node.classList.contains("activityFeed-HeiGwL") || node.id === "friends") {
2017-10-30 21:53:27 +01:00
pluginModule.channelSwitch();
}
2017-10-30 22:04:48 +01:00
// onSwitch()
2017-10-30 21:53:27 +01:00
// New Channel
if (node.classList.contains("messages-wrapper") || node.getElementsByClassName("messages-wrapper").length) {
this.inject24Hour(node);
this.injectColoredText(node);
2017-10-30 21:53:27 +01:00
pluginModule.channelSwitch();
}
2017-10-30 22:04:48 +01:00
// onMessage
2017-10-30 21:53:27 +01:00
// New Message Group
if (node.classList.contains("message-group")) {
this.inject24Hour(node);
this.injectColoredText(node);
// if (!node.getElementsByClassName("message-sending").length && node.parentElement && node.parentElement.children && node == node.parentElement.children[node.parentElement.children.length - 1]) {
// pluginModule.newMessage();
// }
2015-08-29 11:36:47 +02:00
}
if (node.classList.contains("message-text")) {
this.injectColoredText(node.parentElement.parentElement.parentElement.parentElement);
}
2017-10-30 22:04:48 +01:00
// onMessage
2017-10-30 21:53:27 +01:00
// Single Message
if (node.classList.contains("message")) {
this.injectColoredText(node.parentElement.parentElement);
//if (!node.classList.contains("message-sending")) pluginModule.newMessage();
2017-10-30 21:53:27 +01:00
}
2018-03-15 15:30:14 +01:00
emoteModule.obsCallback(mutation);
}
2015-08-29 11:36:47 +02:00
});
2016-01-08 16:33:43 +01:00
mainObserver.observe(document, {
childList: true,
subtree: true
});
};
2015-08-29 11:36:47 +02:00
2017-10-30 21:53:27 +01:00
Core.prototype.inject24Hour = function(node) {
if (!settingsCookie["bda-gs-6"]) return;
node.querySelectorAll('.timestamp').forEach(elem => {
if (elem.getAttribute("data-24")) return;
let text = elem.innerText || elem.textContent;
let matches = /([^0-9]*)([0-9]?[0-9]:[0-9][0-9])([^0-9]*)/.exec(text);
if(matches == null) return;
if(matches.length < 4) return;
2017-11-04 06:59:30 +01:00
let time = matches[2].split(':');
let hours = parseInt(time[0]);
let minutes = time[1];
let timeOfDay = matches[3].toLowerCase();
if (timeOfDay.includes("am") && hours == 12) hours -= 12;
else if (timeOfDay.includes("pm") && hours < 12) hours += 12;
2017-11-04 06:59:30 +01:00
hours = ("0" + hours).slice(-2);
elem.innerText = matches[1] + hours + ":" + minutes + matches[3];
2017-11-04 06:59:30 +01:00
elem.setAttribute("data-24", matches[2]);
});
};
2017-11-04 06:59:30 +01:00
Core.prototype.remove24Hour = function(node) {
2017-10-30 21:53:27 +01:00
node.querySelectorAll('.timestamp').forEach(elem => {
2017-11-04 06:59:30 +01:00
if (!elem.getAttribute("data-24")) return;
let time = elem.getAttribute("data-24");
elem.removeAttribute("data-24");
2017-10-30 21:53:27 +01:00
let text = elem.innerText || elem.textContent;
2017-11-04 06:59:30 +01:00
let matches = /([^0-9]*)([0-9]?[0-9]:[0-9][0-9])([^0-9]*)/.exec(text);
2017-10-30 21:53:27 +01:00
if(matches == null) return;
2017-11-04 06:59:30 +01:00
if(matches.length < 4) return;
elem.innerText = matches[1] + time + matches[3];
2017-10-30 21:53:27 +01:00
});
};
Core.prototype.injectColoredText = function(node) {
if (!settingsCookie["bda-gs-7"]) return;
node.querySelectorAll('.user-name').forEach(elem => {
let color = elem.style.color;
if (color === "rgb(255, 255, 255)") return;
elem.closest(".message-group").querySelectorAll('.markup').forEach(elem => {
2018-01-09 22:32:02 +01:00
if (elem.getAttribute("data-colour")) return;
elem.setAttribute("data-colour", true);
2017-10-30 21:53:27 +01:00
elem.style.setProperty("color", color);
});
});
};
2017-11-04 06:59:30 +01:00
Core.prototype.removeColoredText = function(node) {
node.querySelectorAll('.user-name').forEach(elem => {
elem.closest(".message-group").querySelectorAll('.markup').forEach(elem => {
2018-01-09 22:32:02 +01:00
if (!elem.getAttribute("data-colour")) return;
elem.removeAttribute("data-colour");
2017-11-04 06:59:30 +01:00
elem.style.setProperty("color", "");
});
});
};
2017-11-03 18:34:26 +01:00
Core.prototype.alert = function(title, content) {
let modal = $(`<div class="bd-modal-wrapper theme-dark">
<div class="bd-backdrop backdrop-2ohBEd"></div>
<div class="bd-modal modal-2LIEKY">
<div class="bd-modal-inner inner-1_1f7b">
<div class="header header-3sp3cE">
<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-1PYmcw">
<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.showStartupErrors = function() {
2017-11-03 20:52:35 +01:00
if (!bdpluginErrors || !bdthemeErrors) return;
if (!bdpluginErrors.length && !bdthemeErrors.length) return;
2017-11-03 18:34:26 +01:00
let modal = $(`<div class="bd-modal-wrapper theme-dark">
<div class="bd-backdrop backdrop-2ohBEd"></div>
<div class="bd-modal bd-startup-modal modal-2LIEKY">
<div class="bd-modal-inner inner-1_1f7b">
<div class="header header-3sp3cE"><div class="title">Startup 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-reason">Reason</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-1PYmcw">
<button type="button">Okay</button>
</div>
</div>
</div>
</div>`);
function generateTab(errors) {
let container = $(`<div class="errors">`);
for (let err of errors) {
let error = $(`<div class="error">
<div class="table-column column-name">${err.name ? err.name : err.file}</div>
<div class="table-column column-reason">${err.reason}</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();
utils.err(`Error details for ${err.name ? err.name : err.file}.`, err.error);
});
}
}
return container;
}
let tabs = [generateTab(bdpluginErrors), generateTab(bdthemeErrors)];
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");
modal.find('.tab-bar-item')[0].click();
};
2017-11-03 20:52:35 +01:00
/**
* This shows a toast similar to android towards the bottom of the screen.
*
* @param {string} content The string to show in the toast.
* @param {object} options Options object. Optional parameter.
* @param {string} options.type Changes the type of the toast stylistically and semantically. Choices: "", "info", "success", "danger"/"error", "warning"/"warn". Default: ""
* @param {boolean} options.icon 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 (!document.querySelector('.bd-toasts')) {
let toastWrapper = document.createElement("div");
toastWrapper.classList.add("bd-toasts");
let boundingElement = document.querySelector('.chat form, #friends, .noChannel-2EQ0a9, .activityFeed-HeiGwL');
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 form') ? document.querySelector('.chat form').offsetHeight : 80) + "px");
document.querySelector('.app').appendChild(toastWrapper);
}
const {type = "", icon = true, timeout = 3000} = options;
let 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);
};
2017-10-30 23:14:26 +01:00
2015-08-27 15:46:53 +02:00
/* BetterDiscordApp EmoteModule JavaScript
* Version: 1.5
2015-08-27 15:46:53 +02:00
* Author: Jiiks | http://jiiks.net
* Date: 26/08/2015 - 15:29
2015-10-14 08:50:34 +02:00
* Last Update: 14/10/2015 - 09:48
2015-08-27 15:46:53 +02:00
* https://github.com/Jiiks/BetterDiscordApp
* Note: Due to conflicts autocapitalize only supports global emotes
*/
/*
* =Changelog=
* -v1.5
* --Twitchemotes.com api
*/
2015-08-27 15:46:53 +02:00
var emotesFfz = {};
var emotesBTTV = {};
2017-11-03 04:05:33 +01:00
var emotesBTTV2 = {};
2018-01-09 04:24:00 +01:00
var emotesTwitch = {};
var subEmotesTwitch = {};
2015-08-27 15:46:53 +02:00
2018-01-09 04:24:00 +01:00
window.bdEmotes = {
TwitchGlobal: {},
TwitchSubscriber: {},
BTTV: {},
2018-01-24 00:08:20 +01:00
FrankerFaceZ: {},
2018-01-09 04:24:00 +01:00
BTTV2: {}
}
window.bdEmoteSettingIDs = {
TwitchGlobal: "bda-es-7",
TwitchSubscriber: "bda-es-7",
BTTV: "bda-es-2",
2018-01-24 00:08:20 +01:00
FrankerFaceZ: "bda-es-1",
BTTV2: "bda-es-2"
2018-01-09 04:24:00 +01:00
}
2016-01-08 16:33:43 +01:00
function EmoteModule() {}
2015-08-29 11:36:47 +02:00
2018-02-28 08:25:06 +01:00
EmoteModule.prototype.init = async function () {
2018-01-09 04:24:00 +01:00
this.modifiers = ["flip", "spin", "pulse", "spin2", "spin3", "1spin", "2spin", "3spin", "tr", "bl", "br", "shake", "shake2", "shake3", "flap"];
2018-01-20 02:17:52 +01:00
this.overrides = ['twitch', 'bttv', 'ffz'];
2018-03-16 22:01:31 +01:00
this.categories = ["TwitchGlobal", "TwitchSubscriber", "BTTV", "BTTV2", "FrankerFaceZ"];
2018-01-09 04:24:00 +01:00
let emoteInfo = {
'TwitchGlobal': {
url: 'https://twitchemotes.com/api_cache/v3/global.json',
backup: "https://" + bdConfig.updater.CDN + '/' + bdConfig.repo + '/BetterDiscordApp/' + bdConfig.hash + '/data/emotedata_twitch_global.json',
variable: 'TwitchGlobal',
2018-02-13 08:49:11 +01:00
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} }
2018-01-09 04:24:00 +01:00
},
'TwitchSubscriber': {
url: 'https://twitchemotes.com/api_cache/v3/subscriber.json',
backup: "https://" + bdConfig.updater.CDN + '/' + bdConfig.repo + '/BetterDiscordApp/' + bdConfig.hash + '/data/emotedata_twitch_subscriber.json',
variable: 'TwitchSubscriber',
2018-02-13 08:49:11 +01:00
oldVariable: 'subEmotesTwitch',
2018-01-09 04:24:00 +01:00
parser: (data) => {
let emotes = {};
for (let c in data) {
let channel = data[c];
for (let e = 0, elen = channel.emotes.length; e < elen; e++) {
let emote = channel.emotes[e];
emotes[emote.code] = emote.id;
}
}
return emotes;
},
2018-02-13 08:49:11 +01:00
getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e}/1.0`,
getOldData: (url) => url.match(/\/([0-9]+)\//)[1]
2018-01-09 04:24:00 +01:00
},
'FrankerFaceZ': {
url: "https://" + bdConfig.updater.CDN + '/' + bdConfig.repo + '/BetterDiscordApp/' + bdConfig.hash + '/data/emotedata_ffz.json',
variable: 'FrankerFaceZ',
2018-02-13 08:49:11 +01:00
oldVariable: "emotesFfz",
getEmoteURL: (e) => `https://cdn.frankerfacez.com/emoticon/${e}/1`,
getOldData: (url) => url.match(/\/([0-9]+)\//)[1]
2018-01-09 04:24:00 +01:00
},
'BTTV': {
url: 'https://api.betterttv.net/emotes',
variable: 'BTTV',
2018-02-13 08:49:11 +01:00
oldVariable: "emotesBTTV",
2018-01-09 04:24:00 +01:00
parser: (data) => {
let emotes = {};
for (let e = 0, len = data.emotes.length; e < len; e++) {
let emote = data.emotes[e];
emotes[emote.regex] = emote.url;
}
return emotes;
},
2018-02-13 08:49:11 +01:00
getEmoteURL: (e) => `${e}`,
getOldData: (url) => url
2018-01-09 04:24:00 +01:00
},
'BTTV2': {
url: "https://" + bdConfig.updater.CDN + '/' + bdConfig.repo + '/BetterDiscordApp/' + bdConfig.hash + '/data/emotedata_bttv.json',
variable: 'BTTV2',
2018-02-13 08:49:11 +01:00
oldVariable: "emotesBTTV2",
getEmoteURL: (e) => `https://cdn.betterttv.net/emote/${e}/1x`,
getOldData: (url) => url.match(/emote\/(.+)\//)[1]
2018-01-09 04:24:00 +01:00
}
};
if (!bdConfig.newLoader) {
window.bdEmotes = {
TwitchGlobal: emotesTwitch,
TwitchSubscriber: subEmotesTwitch,
BTTV: emotesBTTV,
2018-01-24 00:08:20 +01:00
FrankerFaceZ: emotesFfz,
BTTV2: emotesBTTV2
2018-01-09 04:24:00 +01:00
}
for (let type in window.bdEmotes) {
for (let emote in window.bdEmotes[type]) {
window.bdEmotes[type][emote] = emoteInfo[type].getEmoteURL(window.bdEmotes[type][emote]);
}
}
return;
}
2018-03-12 19:36:13 +01:00
2018-03-15 15:30:14 +01:00
new Promise((resolve) => {
let observer = new MutationObserver((changes) => {
for (let change of changes) {
if (!change.addedNodes.length || !(change.addedNodes[0] instanceof Element) || !change.addedNodes[0].classList) continue;
let elem = change.addedNodes[0];
if (!elem.querySelector(".message")) continue;
observer.disconnect();
2018-03-15 15:30:14 +01:00
resolve(BDV2.getInternalInstance(elem.querySelector(".message")).return.type);
}
});
observer.observe(document.querySelector('.app') || document.querySelector('#app-mount'), {childList: true, subtree: true})
}).then(MessageComponent => {
2018-03-16 19:18:50 +01:00
if (this.cancel1) this.cancel1();
if (this.cancel2) this.cancel2();
2018-03-12 19:36:13 +01:00
this.cancel1 = Utils.monkeyPatch(MessageComponent.prototype, "componentDidMount", {after: (data) => {
if (!settingsCookie["bda-es-7"] && !settingsCookie["bda-es-2"] && !settingsCookie["bda-es-1"]) return;
2018-03-12 19:36:13 +01:00
let message = BDV2.reactDom.findDOMNode(data.thisObject);
message = message.querySelector('.markup');
2018-03-15 15:30:14 +01:00
if (!message) return;
this.injectEmote(message);
2018-03-12 19:36:13 +01:00
}});
2018-03-15 15:30:14 +01:00
2018-03-12 19:36:13 +01:00
this.cancel2 = Utils.monkeyPatch(MessageComponent.prototype, "componentDidUpdate", {after: (data) => {
if (!settingsCookie["bda-es-7"] && !settingsCookie["bda-es-2"] && !settingsCookie["bda-es-1"]) return;
2018-03-12 19:36:13 +01:00
let message = BDV2.reactDom.findDOMNode(data.thisObject);
message = message.querySelector('.markup');
if (!message) return;
$(message).children('.emotewrapper').remove();
2018-03-15 15:30:14 +01:00
this.injectEmote(message);
2018-03-12 19:36:13 +01:00
}});
});
2018-03-15 15:30:14 +01:00
this.loadEmoteData(emoteInfo);
this.getBlacklist();
2018-01-09 04:24:00 +01:00
};
EmoteModule.prototype.clearEmoteData = async function() {
let _fs = require("fs");
let emoteFile = "emote_data.json";
let file = bdConfig.dataPath + emoteFile;
let exists = _fs.existsSync(file);
if (exists) _fs.unlinkSync(file);
window.bdEmotes = {
TwitchGlobal: {},
TwitchSubscriber: {},
BTTV: {},
2018-01-24 00:08:20 +01:00
FrankerFaceZ: {},
2018-01-09 04:24:00 +01:00
BTTV2: {}
}
};
2018-02-13 08:49:11 +01:00
EmoteModule.prototype.goBack = async function(emoteInfo) {
for (let e in emoteInfo) {
for (let emote in bdEmotes[emoteInfo[e].variable]) {
window[emoteInfo[e].oldVariable][emote] = emoteInfo[e].getOldData(bdEmotes[emoteInfo[e].variable][emote], emote)
}
}
}
2018-01-09 04:24:00 +01:00
EmoteModule.prototype.loadEmoteData = async function(emoteInfo) {
let _fs = require("fs");
let emoteFile = "emote_data.json";
let file = bdConfig.dataPath + emoteFile;
let exists = _fs.existsSync(file);
if (exists && !bdConfig.cache.expired) {
2018-02-13 17:06:19 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast("Loading emotes from cache.", {type: "info"});
2018-01-09 04:24:00 +01:00
utils.log("[Emotes] Loading emotes from local cache.")
let data = _fs.readFileSync(file, "utf8");
let isValid = this.testJSON(data);
2018-01-09 04:24:00 +01:00
if (isValid) bdEmotes = JSON.parse(data);
for (let e in emoteInfo) {
isValid = Object.keys(bdEmotes[emoteInfo[e].variable]).length > 0;
2018-01-09 04:24:00 +01:00
}
if (isValid) {
2018-02-13 08:49:11 +01:00
await this.goBack(emoteInfo)
2018-02-13 17:06:19 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast("Emotes successfully loaded.", {type: "success"})
return;
2018-01-09 04:24:00 +01:00
}
utils.log("[Emotes] Cache was corrupt, downloading...")
_fs.unlinkSync(file);
2018-01-09 04:24:00 +01:00
}
2018-02-13 17:06:19 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast("Downloading emotes in the background do not reload.", {type: "info"});
2018-01-09 04:24:00 +01:00
for (let e in emoteInfo) {
let data = await this.downloadEmotes(emoteInfo[e]);
bdEmotes[emoteInfo[e].variable] = data;
}
2018-02-13 08:49:11 +01:00
await this.goBack(emoteInfo)
2018-02-13 17:06:19 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast("All emotes successfully downloaded.", {type: "success"});
2018-01-09 04:24:00 +01:00
try { _fs.writeFileSync(file, JSON.stringify(bdEmotes), "utf8"); }
catch(err) { utils.err("[Emotes] Could not save emote data.", err); }
2018-01-09 22:32:02 +01:00
quickEmoteMenu.init();
2018-01-09 04:24:00 +01:00
}
EmoteModule.prototype.downloadEmotes = function(emoteMeta) {
let request = require("request");
let options = {
url: emoteMeta.url,
timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000
};
utils.log("[Emotes] Downloading: " + emoteMeta.variable);
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) {
utils.err("[Emotes] Could not download " + emoteMeta.variable, error)
if (emoteMeta.backup) {
emoteMeta.url = emoteMeta.backup;
emoteMeta.backup = null;
return this.downloadEmotes(emoteMeta);
}
reject({});
}
else {
let parsedData = JSON.parse(body);
if (typeof(emoteMeta.parser) === "function") parsedData = emoteMeta.parser(parsedData);
for (let emote in parsedData) {
parsedData[emote] = emoteMeta.getEmoteURL(parsedData[emote]);
}
resolve(parsedData);
2018-01-24 00:08:20 +01:00
utils.log("[Emotes] Downloaded: " + emoteMeta.variable);
2018-01-09 04:24:00 +01:00
}
});
});
}
EmoteModule.prototype.testJSON = function(data) {
try {
let json = JSON.parse(data);
return true;
}
catch(err) {
return false;
}
return false;
}
2015-11-01 12:57:10 +01:00
2016-01-08 16:33:43 +01:00
EmoteModule.prototype.getBlacklist = function () {
2018-03-15 15:30:14 +01:00
$.getJSON("https://cdn.rawgit.com/rauenzi/betterDiscordApp/" + _hash + "/data/emotefilter.json", function (data) {
2016-01-08 16:33:43 +01:00
bemotes = data.blacklist;
});
2015-11-01 12:44:25 +01:00
};
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
EmoteModule.prototype.obsCallback = function (mutation) {
2018-03-12 19:36:13 +01:00
return;
2015-08-29 11:36:47 +02:00
var self = this;
2016-01-08 16:33:43 +01:00
for (var i = 0; i < mutation.addedNodes.length; ++i) {
2015-08-29 11:36:47 +02:00
var next = mutation.addedNodes.item(i);
2016-01-08 16:33:43 +01:00
if (next) {
2015-08-29 11:36:47 +02:00
var nodes = self.getNodes(next);
2016-01-08 16:33:43 +01:00
for (var node in nodes) {
if (nodes.hasOwnProperty(node)) {
var elem = nodes[node].parentElement;
if (elem && elem.classList.contains('edited')) {
2018-03-12 19:36:13 +01:00
$(elem.parentElement).children('.emotewrapper').remove();
setTimeout(() => {
2018-03-15 15:30:14 +01:00
//$(elem.parentElement).children()
2018-03-12 19:36:13 +01:00
self.injectEmote(elem, true);
}, 200);
} else {
self.injectEmote(nodes[node]);
}
}
2015-08-29 11:36:47 +02:00
}
}
}
};
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
EmoteModule.prototype.getNodes = function (node) {
2015-08-27 15:46:53 +02:00
var next;
var nodes = [];
2015-10-31 22:49:42 +01:00
var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
2015-08-27 15:46:53 +02:00
2017-11-03 04:05:33 +01:00
// eslint-disable-next-line no-cond-assign
2016-01-08 16:33:43 +01:00
while (next = treeWalker.nextNode()) {
2015-08-27 15:46:53 +02:00
nodes.push(next);
}
return nodes;
};
2015-08-27 15:46:53 +02:00
2015-11-01 12:44:25 +01:00
var bemotes = [];
2015-08-27 15:46:53 +02:00
2018-01-20 02:17:52 +01:00
EmoteModule.prototype.injectEmote = async function(node, edited) {
2018-03-12 19:36:13 +01:00
//if (!node.parentElement || (!node.parentElement.classList.contains("markup") && !node.parentElement.classList.contains("message-content"))) return;
2018-01-09 04:24:00 +01:00
let messageScroller = document.querySelector('.messages.scroller');
2018-03-15 15:30:14 +01:00
let message = node//.parentElement;
2018-01-20 02:17:52 +01:00
let editNode = null;
2018-02-28 08:25:06 +01:00
/*if (edited) message.querySelectorAll(".emotewrapper").forEach(node => {
let name = node.querySelector(".emote").getAttribute("alt");
let last = message.children.length - 2;
if (node == message.children[0] && node != message.children[last]) name = name + " ";
else if (node == message.children[last] && node != message.children[0]) name = " " + name;
else if (node != message.children[0] && node != message.children[last]) name = " " + name + " ";
node.outerHTML = name;
});*/
let textNodes = utils.getTextNodes(message);
let words = textNodes.map(n => n.data).join(" ").split(/([^\s]+)([\s]|$)/g).filter(function(e) { return e; });//message.innerHTML.split(/([^\s]+)([\s]|$)/g).filter(function(e) { return e; });
2015-08-27 15:46:53 +02:00
2018-01-20 02:17:52 +01:00
let inject = function(message, messageScroller, category, emoteName, emoteModifier) {
2018-03-16 19:18:50 +01:00
let inCategory = Object.hasOwnProperty.call(bdEmotes[category], emoteName);
2018-01-20 02:17:52 +01:00
if (!inCategory || !settingsCookie[bdEmoteSettingIDs[category]]) return false;
let url = bdEmotes[category][emoteName];
let element = this.createEmoteElement(emoteName, url, emoteModifier);
let oldHeight = message.offsetHeight;
2018-02-28 08:25:06 +01:00
//message.innerHTML = message.innerHTML.replace(new RegExp(`([\\s]|^)${utils.escape(emoteModifier ? emoteName + ":" + emoteModifier : emoteName)}([\\s]|$)`, "g"), `$1${element}$2`);
2018-03-12 19:36:13 +01:00
utils.insertElement(message, new RegExp(`([\\s]|^)${utils.escape(emoteModifier ? emoteName + ":" + emoteModifier : emoteName)}([\\s]|$)`), $(element)[0]);
2018-01-20 02:17:52 +01:00
messageScroller.scrollTop = messageScroller.scrollTop + (message.offsetHeight - oldHeight);
return true;
}
inject = inject.bind(this, message, messageScroller);
2018-01-09 04:24:00 +01:00
for (let w = 0, len = words.length; w < len; w++) {
let emote = words[w];
let emoteSplit = emote.split(':');
let emoteName = emoteSplit[0];
let emoteModifier = emoteSplit[1] ? emoteSplit[1] : "";
2018-01-20 02:17:52 +01:00
let emoteOverride = emoteModifier.slice(0);
2016-01-08 16:33:43 +01:00
2018-01-09 04:55:12 +01:00
if (bemotes.includes(emoteName) || emoteName.length < 4) continue;
2018-01-09 04:24:00 +01:00
if (!this.modifiers.includes(emoteModifier) || !settingsCookie["bda-es-8"]) emoteModifier = "";
2018-01-20 02:17:52 +01:00
if (!this.overrides.includes(emoteOverride)) emoteOverride = "";
if (emoteOverride === "twitch") {
let tglobal = false;
let tsubscriber = false;
tglobal = inject("TwitchGlobal", emoteName, emoteOverride);
if (!tglobal) tsubscriber = inject("TwitchSubscriber", emoteName, emoteOverride);
if (tglobal || tsubscriber) continue;
}
else if (emoteOverride === "bttv") {
let bttv = false;
let bttv2 = false;
bttv = inject("BTTV", emoteName, emoteOverride);
if (!bttv) bttv2 = inject("BTTV2", emoteName, emoteOverride);
if (bttv || bttv2) continue;
}
else if (emoteOverride === "ffz") {
let ffz = inject("FrankerFaceZ", emoteName, emoteOverride);
if (ffz) continue;
}
2018-01-09 04:24:00 +01:00
for (let c = 0, clen = this.categories.length; c < clen; c++) {
2018-01-20 02:17:52 +01:00
inject(this.categories[c], emoteName, emoteModifier);
2018-01-09 04:24:00 +01:00
}
2018-01-09 04:24:00 +01:00
if (emote == "[!s]") message.classList.add("spoiler");
}
2018-01-20 02:17:52 +01:00
// if (edited) $(message).append(editNode);
};
2016-01-08 16:33:43 +01:00
EmoteModule.prototype.createEmoteElement = function(word, url, mod) {
var len = Math.round(word.length / 4);
var name = word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3);
2018-01-09 04:24:00 +01:00
var stopAnim = settingsCookie['fork-es-2'] ? " stop-animation" : "";
var modClass = mod ? "emote" + mod : "";
var html = '<span class="emotewrapper"><img draggable="false" style="max-height:32px;" data-modifier="' + mod + '" class="emote ' + modClass + stopAnim + '" alt="' + name + '" src="' + url + '"/><input onclick=\'quickEmoteMenu.favorite("' + name + '", "' + url + '");\' class="fav" title="Favorite!" type="button"></span>';
return html.replace(new RegExp("\uFDD9", "g"), "");
};
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
EmoteModule.prototype.autoCapitalize = function () {
2015-08-27 15:46:53 +02:00
var self = this;
2015-08-31 15:36:28 +02:00
2017-10-29 21:33:48 +01:00
$('body').delegate($(".channelTextArea-1HTP3C textarea:first"), 'keyup change paste', function () {
2016-01-08 16:33:43 +01:00
if (!settingsCookie["bda-es-4"]) return;
2015-08-27 15:46:53 +02:00
2017-10-29 21:33:48 +01:00
var text = $(".channelTextArea-1HTP3C textarea:first").val();
2016-01-08 16:33:43 +01:00
if (text == undefined) return;
2015-08-29 11:36:47 +02:00
2015-08-27 15:46:53 +02:00
var lastWord = text.split(" ").pop();
2016-01-08 16:33:43 +01:00
if (lastWord.length > 3) {
if (lastWord == "danSgame") return;
2015-08-27 15:46:53 +02:00
var ret = self.capitalize(lastWord.toLowerCase());
2016-01-08 16:33:43 +01:00
if (ret !== null && ret !== undefined) {
2017-10-29 21:33:48 +01:00
utils.insertText(utils.getTextArea()[0], text.replace(lastWord, ret));
2015-08-27 15:46:53 +02:00
}
}
});
};
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
EmoteModule.prototype.capitalize = function (value) {
2018-01-09 04:24:00 +01:00
var res = bdEmotes.TwitchGlobal;
2016-01-08 16:33:43 +01:00
for (var p in res) {
if (res.hasOwnProperty(p) && value == (p + '').toLowerCase()) {
return p;
}
2015-08-27 15:46:53 +02:00
}
};
2016-12-05 21:05:48 +01:00
2017-04-30 03:11:22 +02:00
/* BetterDiscordApp QuickEmoteMenu JavaScript
* Version: 1.3
* Author: Jiiks | http://jiiks.net
* Date: 26/08/2015 - 11:49
* Last Update: 29/08/2015 - 11:46
* https://github.com/Jiiks/BetterDiscordApp
*/
2015-12-31 18:27:43 +01:00
2017-04-30 03:11:22 +02:00
function QuickEmoteMenu() {
2015-12-31 18:27:43 +01:00
}
2017-04-30 03:11:22 +02:00
QuickEmoteMenu.prototype.init = function() {
2015-12-31 18:27:43 +01:00
2017-04-30 03:11:22 +02:00
$(document).on("mousedown", function(e) {
if(e.target.id != "rmenu") $("#rmenu").remove();
});
this.favoriteEmotes = {};
2017-11-03 04:05:33 +01:00
var fe = window.bdStorage.get("bdfavemotes");
2017-04-30 03:11:22 +02:00
if (fe !== "" && fe !== null) {
this.favoriteEmotes = JSON.parse(atob(fe));
2016-01-08 16:33:43 +01:00
}
2015-12-31 18:27:43 +01:00
2017-11-01 06:03:48 +01:00
var qmeHeader = "";
2017-04-30 03:11:22 +02:00
qmeHeader += "<div id=\"bda-qem\">";
2017-11-03 04:05:33 +01:00
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>";
2017-11-01 06:03:48 +01:00
qmeHeader += "</div>";
2017-04-30 03:11:22 +02:00
this.qmeHeader = qmeHeader;
2015-12-31 18:27:43 +01:00
2017-11-01 06:03:48 +01:00
var teContainer = "";
2017-04-30 03:11:22 +02:00
teContainer += "<div id=\"bda-qem-twitch-container\">";
teContainer += " <div class=\"scroller-wrap fade\">";
teContainer += " <div class=\"scroller\">";
teContainer += " <div class=\"emote-menu-inner\">";
2018-01-09 04:24:00 +01:00
for (let emote in bdEmotes.TwitchGlobal) {
if (bdEmotes.TwitchGlobal.hasOwnProperty(emote)) {
var url = bdEmotes.TwitchGlobal[emote];
2017-04-30 03:11:22 +02:00
teContainer += "<div class=\"emote-container\">";
2018-01-09 04:24:00 +01:00
teContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\">";
2017-04-30 03:11:22 +02:00
teContainer += " </img>";
teContainer += "</div>";
}
2015-12-31 18:27:43 +01:00
}
2017-11-03 04:05:33 +01:00
teContainer += " </div>";
teContainer += " </div>";
teContainer += " </div>";
teContainer += "</div>";
2017-04-30 03:11:22 +02:00
this.teContainer = teContainer;
2015-12-31 18:27:43 +01:00
2017-11-01 06:03:48 +01:00
var faContainer = "";
2017-04-30 03:11:22 +02:00
faContainer += "<div id=\"bda-qem-favourite-container\">";
faContainer += " <div class=\"scroller-wrap fade\">";
faContainer += " <div class=\"scroller\">";
faContainer += " <div class=\"emote-menu-inner\">";
2017-11-03 04:05:33 +01:00
for (let emote in this.favoriteEmotes) {
2017-04-30 03:11:22 +02:00
var url = this.favoriteEmotes[emote];
faContainer += "<div class=\"emote-container\">";
2017-11-01 06:03:48 +01:00
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>";
2017-04-30 03:11:22 +02:00
faContainer += " </img>";
faContainer += "</div>";
2015-12-31 18:27:43 +01:00
}
2017-11-01 06:03:48 +01:00
faContainer += " </div>";
faContainer += " </div>";
faContainer += " </div>";
faContainer += "</div>";
2017-04-30 03:11:22 +02:00
this.faContainer = faContainer;
2015-12-31 18:27:43 +01:00
};
2017-04-30 03:11:22 +02:00
QuickEmoteMenu.prototype.favContext = function(e, em) {
e.stopPropagation();
2017-11-03 20:52:35 +01:00
var menu = $('<div>', { id: "rmenu", "data-emoteid": $(em).prop("title"), text: "Remove", class: "context-menu theme-dark" });
2017-04-30 03:11:22 +02:00
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();
2015-12-31 18:27:43 +01:00
2017-04-30 03:11:22 +02:00
delete quickEmoteMenu.favoriteEmotes[$(this).data("emoteid")];
quickEmoteMenu.updateFavorites();
return false;
});
return false;
2015-12-31 18:27:43 +01:00
};
2017-04-30 03:11:22 +02:00
QuickEmoteMenu.prototype.switchHandler = function(e) {
this.switchQem($(e).attr("id"));
};
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
QuickEmoteMenu.prototype.switchQem = function(id) {
var twitch = $("#bda-qem-twitch");
var fav = $("#bda-qem-favourite");
var emojis = $("#bda-qem-emojis");
twitch.removeClass("active");
fav.removeClass("active");
emojis.removeClass("active");
2015-12-12 09:50:25 +01:00
2018-01-09 22:32:02 +01:00
$(".emoji-picker, .emojiPicker-3g68GS").hide();
2017-04-30 03:11:22 +02:00
$("#bda-qem-favourite-container").hide();
$("#bda-qem-twitch-container").hide();
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
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");
2018-01-09 22:32:02 +01:00
$(".emoji-picker, .emojiPicker-3g68GS").show();
$(".emoji-picker .search-bar-inner input, .emojiPicker-3g68GS .search-bar-inner input").focus();
2017-04-30 03:11:22 +02:00
break;
}
this.lastTab = id;
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
var emoteIcon = $(".emote-icon");
emoteIcon.off();
emoteIcon.on("click", function () {
var emote = $(this).attr("title");
2017-10-29 21:33:48 +01:00
var ta = utils.getTextArea();
utils.insertText(ta[0], ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote);
2017-04-30 03:11:22 +02:00
});
2015-12-12 09:50:25 +01:00
};
2017-10-29 21:33:48 +01:00
QuickEmoteMenu.prototype.obsCallback = function (elem) {
var e = $(elem);
2017-04-30 03:11:22 +02:00
if(!settingsCookie["bda-es-9"]) {
e.addClass("bda-qme-hidden");
} else {
e.removeClass("bda-qme-hidden");
2015-12-12 09:50:25 +01:00
}
2017-04-30 03:11:22 +02:00
if(!settingsCookie["bda-es-0"]) return;
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
e.prepend(this.qmeHeader);
e.append(this.teContainer);
e.append(this.faContainer);
if(this.lastTab == undefined) {
this.lastTab = "bda-qem-favourite";
}
this.switchQem(this.lastTab);
2015-12-12 13:53:07 +01:00
};
2017-04-30 03:11:22 +02:00
QuickEmoteMenu.prototype.favorite = function (name, url) {
2016-01-08 16:33:43 +01:00
2017-04-30 03:11:22 +02:00
if (!this.favoriteEmotes.hasOwnProperty(name)) {
this.favoriteEmotes[name] = url;
}
2017-04-30 03:11:22 +02:00
this.updateFavorites();
2015-12-12 13:53:07 +01:00
};
2017-04-30 03:11:22 +02:00
QuickEmoteMenu.prototype.updateFavorites = function () {
2016-01-08 16:33:43 +01:00
2017-11-01 06:03:48 +01:00
var faContainer = "";
2017-04-30 03:11:22 +02:00
faContainer += "<div id=\"bda-qem-favourite-container\">";
faContainer += " <div class=\"scroller-wrap fade\">";
faContainer += " <div class=\"scroller\">";
faContainer += " <div class=\"emote-menu-inner\">";
for (var emote in this.favoriteEmotes) {
var url = this.favoriteEmotes[emote];
faContainer += "<div class=\"emote-container\">";
2017-11-03 20:52:35 +01:00
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\" oncontextmenu=\"quickEmoteMenu.favContext(event, this);\">";
2017-04-30 03:11:22 +02:00
faContainer += " </img>";
faContainer += "</div>";
}
2017-11-01 06:03:48 +01:00
faContainer += " </div>";
faContainer += " </div>";
faContainer += " </div>";
faContainer += "</div>";
2017-04-30 03:11:22 +02:00
this.faContainer = faContainer;
$("#bda-qem-favourite-container").replaceWith(faContainer);
window.bdStorage.set("bdfavemotes", btoa(JSON.stringify(this.favoriteEmotes)));
};
2017-04-30 03:11:22 +02:00
2017-05-04 17:47:16 +02:00
2017-04-30 03:11:22 +02:00
/* BetterDiscordApp Utilities JavaScript
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 26/08/2015 - 15:54
* https://github.com/Jiiks/BetterDiscordApp
*/
var _hash;
function Utils() {
}
Utils.prototype.getTextArea = function () {
2017-10-29 21:33:48 +01:00
return $(".channelTextArea-1HTP3C textarea");
};
Utils.prototype.insertText = function (textarea, text) {
2017-10-29 21:55:59 +01:00
textarea.focus();
2017-10-29 21:33:48 +01:00
textarea.selectionStart = 0;
textarea.selectionEnd = textarea.value.length;
document.execCommand("insertText", false, text);
2017-04-30 03:11:22 +02:00
};
Utils.prototype.jqDefer = function (fnc) {
if (window.jQuery) {
fnc();
} else {
setTimeout(function () {
this.jqDefer(fnc);
}, 100);
}
};
Utils.prototype.getHash = function () {
2018-03-15 15:30:14 +01:00
$.getJSON("https://api.github.com/repos/rauenzi/BetterDiscordApp/commits/master", function (data) {
2017-04-30 03:11:22 +02:00
_hash = data.sha;
2018-03-16 22:01:31 +01:00
bdConfig.hash = _hash;
2017-04-30 03:11:22 +02:00
});
};
Utils.prototype.loadHtml = function (html, callback) {
var container = $("<div/>", {
class: "bd-container"
}).appendTo("body");
//TODO Inject these in next core update
2017-11-04 16:04:50 +01:00
html = '//cdn.rawgit.com/Jiiks/BetterDiscordApp/' + _hash + '/html/' + html + '.html';
2017-04-30 03:11:22 +02:00
container.load(html, callback());
};
Utils.prototype.injectJs = function (uri) {
$("<script/>", {
type: "text/javascript",
src: uri
}).appendTo($("body"));
};
Utils.prototype.injectCss = function (uri) {
$("<link/>", {
type: "text/css",
rel: "stylesheet",
href: uri
}).appendTo($("head"));
};
2017-10-29 23:23:39 +01:00
Utils.prototype.escapeID = function(id) {
return id.replace(/^[^a-z]+|[^\w-]+/gi, "");
};
2017-04-30 03:11:22 +02:00
Utils.prototype.log = function (message) {
2017-10-31 07:35:38 +01:00
console.log('%c[BetterDiscord] %c' + message + '', 'color: #3a71c1; font-weight: 700;', '');
2017-04-30 03:11:22 +02:00
};
2017-10-31 07:35:38 +01:00
Utils.prototype.err = function (message, error) {
console.log('%c[BetterDiscord] %c' + message + '', 'color: red; font-weight: 700;', '');
if (error) {
console.groupCollapsed('%cError: ' + error.message, 'color: red;');
2017-10-31 10:12:58 +01:00
console.error(error.stack);
2017-10-31 07:35:38 +01:00
console.groupEnd();
}
2017-04-30 03:11:22 +02:00
};
2018-02-28 08:25:06 +01:00
Utils.prototype.escape = function(s) {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
};
Utils.prototype.insertElement = function(node, regex, element) {
var child = node.firstChild;
while (child) {
if (child.nodeType != Node.TEXT_NODE) {child = child.nextSibling; continue};
var bk = 0;
child.data.replace(regex, function(all) {
2018-03-16 22:01:31 +01:00
var args = [].slice.call(arguments);
var offset = args[args.length - 2];
var newTextNode = args[1] ? child.splitText(offset + args[1].length + bk) : child.splitText(offset + bk);
2018-02-28 08:25:06 +01:00
bk -= child.data.length + all.length;
2018-03-16 22:01:31 +01:00
newTextNode.data = newTextNode.data.substr(all.trim().length);
child.parentNode.insertBefore(element, newTextNode);
2018-02-28 08:25:06 +01:00
child = newTextNode;
});
regex.lastIndex = 0;
child = child.nextSibling;
}
return node;
};
Utils.prototype.getTextNodes = function(node) {
2018-03-15 15:30:14 +01:00
var textNodes = [];
if (!node) return textNodes;
2018-02-28 08:25:06 +01:00
for (var i = 0; i < node.childNodes.length; i++) {
var curNode = node.childNodes[i];
if (curNode.nodeType === Node.TEXT_NODE) {
textNodes.push(curNode)
}
}
return textNodes;
}
2018-03-12 19:36:13 +01:00
Utils.suppressErrors = (method, desiption) => (...params) => {
try { return method(...params); }
catch (e) { console.error('Error occurred in ' + desiption, e); }
};
Utils.monkeyPatch = (what, methodName, options) => {
const {before, after, instead, once = false, silent = false} = options;
const displayName = options.displayName || what.displayName || what.name || what.constructor.displayName || what.constructor.name;
if (!silent) console.log('patch', methodName, 'of', displayName); // eslint-disable-line no-console
const origMethod = what[methodName];
const cancel = () => {
if (!silent) console.log('unpatch', methodName, 'of', displayName); // eslint-disable-line no-console
what[methodName] = origMethod;
};
what[methodName] = function() {
const data = {
thisObject: this,
methodArguments: arguments,
cancelPatch: cancel,
originalMethod: origMethod,
callOriginalMethod: () => data.returnValue = data.originalMethod.apply(data.thisObject, data.methodArguments)
};
if (instead) {
const tempRet = Utils.suppressErrors(instead, '`instead` callback of ' + what[methodName].displayName)(data);
if (tempRet !== undefined)
data.returnValue = tempRet;
}
else {
if (before) Utils.suppressErrors(before, '`before` callback of ' + what[methodName].displayName)(data);
data.callOriginalMethod();
if (after) Utils.suppressErrors(after, '`after` callback of ' + what[methodName].displayName)(data);
}
if (once) cancel();
return data.returnValue;
};
what[methodName].__monkeyPatched = true;
what[methodName].displayName = 'patched ' + (what[methodName].displayName || methodName);
return cancel;
};
2017-04-30 03:11:22 +02:00
/* BetterDiscordApp VoiceMode JavaScript
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 25/10/2015 - 19:10
* https://github.com/Jiiks/BetterDiscordApp
*/
function VoiceMode() {
}
VoiceMode.prototype.obsCallback = function () {
var self = this;
if (settingsCookie["bda-gs-4"]) {
self.disable();
setTimeout(function () {
self.enable();
}, 300);
}
};
VoiceMode.prototype.enable = function () {
$(".scroller.guild-channels ul").first().css("display", "none");
$(".scroller.guild-channels header").first().css("display", "none");
$(".app.flex-vertical").first().css("overflow", "hidden");
$(".chat.flex-vertical.flex-spacer").first().css("visibility", "hidden").css("min-width", "0px");
$(".flex-vertical.channels-wrap").first().css("flex-grow", "100000");
$(".guild-header .btn.btn-hamburger").first().css("visibility", "hidden");
};
VoiceMode.prototype.disable = function () {
$(".scroller.guild-channels ul").first().css("display", "");
$(".scroller.guild-channels header").first().css("display", "");
$(".app.flex-vertical").first().css("overflow", "");
$(".chat.flex-vertical.flex-spacer").first().css("visibility", "").css("min-width", "");
$(".flex-vertical.channels-wrap").first().css("flex-grow", "");
$(".guild-header .btn.btn-hamburger").first().css("visibility", "");
};
/* BetterDiscordApp PluginModule JavaScript
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 16/12/2015
* https://github.com/Jiiks/BetterDiscordApp
*/
var pluginCookie = {};
function PluginModule() {
}
PluginModule.prototype.loadPlugins = function () {
this.loadPluginData();
2017-10-31 07:39:42 +01:00
var plugins = Object.keys(bdplugins);
2017-10-31 07:35:38 +01:00
for (var i = 0; i < plugins.length; i++) {
2017-10-31 07:58:39 +01:00
var plugin, name;
2017-10-31 07:35:38 +01:00
2017-10-31 07:58:39 +01:00
try {
plugin = bdplugins[plugins[i]].plugin;
2017-10-29 22:58:35 +01:00
name = plugin.getName();
plugin.load();
}
2017-10-31 09:26:30 +01:00
catch (err) {
pluginCookie[name] = false;
2017-10-31 22:28:49 +01:00
utils.err("Plugin " + name + " could not be loaded.", err);
2017-11-03 06:34:04 +01:00
bdpluginErrors.push({name: name, file: bdplugins[plugins[i]].filename, reason: "load() could not be fired.", error: {message: err.message, stack: err.stack}});
2017-10-31 22:28:49 +01:00
continue;
2017-10-31 09:26:30 +01:00
}
2017-04-30 03:11:22 +02:00
2017-10-31 07:58:39 +01:00
if (!pluginCookie[name]) pluginCookie[name] = false;
2017-04-30 03:11:22 +02:00
2017-10-31 07:58:39 +01:00
if (pluginCookie[name]) {
2017-11-03 21:08:53 +01:00
try {
plugin.start();
2017-12-24 07:51:24 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${plugin.getName()} v${plugin.getVersion()} has started.`);
2017-11-03 21:08:53 +01:00
}
2017-10-31 09:26:30 +01:00
catch (err) {
pluginCookie[name] = false;
utils.err("Plugin " + name + " could not be started.", err);
2017-11-03 06:34:04 +01:00
bdpluginErrors.push({name: name, file: bdplugins[plugins[i]].filename, reason: "start() could not be fired.", error: {message: err.message, stack: err.stack}});
2017-10-31 09:26:30 +01:00
}
2017-04-30 03:11:22 +02:00
}
2017-10-31 07:35:38 +01:00
}
2017-10-31 09:26:30 +01:00
this.savePluginData();
};
PluginModule.prototype.startPlugin = function (plugin) {
2017-11-03 20:52:35 +01:00
try {
bdplugins[plugin].plugin.start();
2017-12-24 07:51:24 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} has started.`);
2017-11-03 20:52:35 +01:00
}
2017-10-31 09:26:30 +01:00
catch (err) {
pluginCookie[plugin] = false;
this.savePluginData();
utils.err("Plugin " + name + " could not be started.", err);
}
};
PluginModule.prototype.stopPlugin = function (plugin) {
2017-11-03 20:52:35 +01:00
try {
bdplugins[plugin].plugin.stop();
2017-12-24 07:51:24 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} has stopped.`);
2017-11-03 20:52:35 +01:00
}
catch (err) {
utils.err("Plugin " + name + " could not be stopped.", err);
}
2017-10-31 09:26:30 +01:00
};
PluginModule.prototype.enablePlugin = function (plugin) {
pluginCookie[plugin] = true;
this.savePluginData();
this.startPlugin(plugin);
};
PluginModule.prototype.disablePlugin = function (plugin) {
pluginCookie[plugin] = false;
this.savePluginData();
this.stopPlugin(plugin);
};
PluginModule.prototype.togglePlugin = function (plugin) {
2017-11-01 18:46:13 +01:00
if (pluginCookie[plugin]) this.disablePlugin(plugin);
else this.enablePlugin(plugin);
2017-04-30 03:11:22 +02:00
};
PluginModule.prototype.loadPluginData = function () {
var cookie = $.cookie("bd-plugins");
if (cookie != undefined) {
pluginCookie = JSON.parse($.cookie("bd-plugins"));
}
};
PluginModule.prototype.savePluginData = function () {
$.cookie("bd-plugins", JSON.stringify(pluginCookie), {
expires: 365,
path: '/'
});
};
PluginModule.prototype.newMessage = function () {
var plugins = Object.keys(bdplugins);
for (var i = 0; i < plugins.length; i++) {
var plugin = bdplugins[plugins[i]].plugin;
2017-10-31 22:28:49 +01:00
if (!pluginCookie[plugin.getName()]) continue;
if (typeof plugin.onMessage === "function") {
try { plugin.onMessage(); }
catch (err) { utils.err("Unable to fire onMessage for " + plugin.getName() + ".", err); }
2017-04-30 03:11:22 +02:00
}
}
2017-04-30 03:11:22 +02:00
};
PluginModule.prototype.channelSwitch = function () {
var plugins = Object.keys(bdplugins);
for (var i = 0; i < plugins.length; i++) {
var plugin = bdplugins[plugins[i]].plugin;
2017-10-31 22:28:49 +01:00
if (!pluginCookie[plugin.getName()]) continue;
if (typeof plugin.onSwitch === "function") {
try { plugin.onSwitch(); }
catch (err) { utils.err("Unable to fire onSwitch for " + plugin.getName() + ".", err); }
2017-04-30 03:11:22 +02:00
}
}
2017-04-30 03:11:22 +02:00
};
PluginModule.prototype.rawObserver = function(e) {
var plugins = Object.keys(bdplugins);
for (var i = 0; i < plugins.length; i++) {
var plugin = bdplugins[plugins[i]].plugin;
2017-10-31 22:28:49 +01:00
if (!pluginCookie[plugin.getName()]) continue;
if (typeof plugin.observer === "function") {
try { plugin.observer(e); }
catch (err) { utils.err("Unable to fire observer for " + plugin.getName() + ".", err); }
2017-04-30 03:11:22 +02:00
}
}
2017-04-30 03:11:22 +02:00
};
2017-10-30 04:45:07 +01:00
2017-04-30 03:11:22 +02:00
/* BetterDiscordApp ThemeModule JavaScript
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 16/12/2015
* https://github.com/Jiiks/BetterDiscordApp
*/
var themeCookie = {};
function ThemeModule() {
}
ThemeModule.prototype.loadThemes = function () {
this.loadThemeData();
2017-10-31 07:58:39 +01:00
var themes = Object.keys(bdthemes);
for (var i = 0; i < themes.length; i++) {
var name = bdthemes[themes[i]].name;
if (!themeCookie[name]) themeCookie[name] = false;
2017-11-01 18:34:00 +01:00
if (themeCookie[name]) $("head").append($('<style>', {id: utils.escapeID(name), html: unescape(bdthemes[name].css)}));
}
2017-04-30 03:11:22 +02:00
};
2017-11-01 18:34:00 +01:00
ThemeModule.prototype.enableTheme = function (theme) {
themeCookie[theme] = true;
this.saveThemeData();
$("head").append(`<style id="${utils.escapeID(bdthemes[theme].name)}">${unescape(bdthemes[theme].css)}</style>`);
2017-12-24 07:51:24 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${bdthemes[theme].name} v${bdthemes[theme].version} has been applied.`);
2017-11-01 18:34:00 +01:00
};
ThemeModule.prototype.disableTheme = function (theme) {
themeCookie[theme] = false;
this.saveThemeData();
$(`#${utils.escapeID(bdthemes[theme].name)}`).remove();
2017-12-24 07:51:24 +01:00
if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${bdthemes[theme].name} v${bdthemes[theme].version} has been removed.`);
2017-11-01 18:34:00 +01:00
};
2017-11-01 18:37:44 +01:00
ThemeModule.prototype.toggleTheme = function (theme) {
2017-11-01 18:46:13 +01:00
if (themeCookie[theme]) this.disableTheme(theme);
else this.enableTheme(theme);
2017-11-01 18:34:00 +01:00
};
2017-04-30 03:11:22 +02:00
ThemeModule.prototype.loadThemeData = function () {
var cookie = $.cookie("bd-themes");
if (cookie != undefined) {
themeCookie = JSON.parse($.cookie("bd-themes"));
}
};
ThemeModule.prototype.saveThemeData = function () {
$.cookie("bd-themes", JSON.stringify(themeCookie), {
expires: 365,
path: '/'
});
};
/* BetterDiscordApp API for Plugins
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 11/12/2015
* Last Update: 11/12/2015
* https://github.com/Jiiks/BetterDiscordApp
*
* Plugin Template: https://gist.github.com/Jiiks/71edd5af0beafcd08956
*/
function BdApi() {}
//Inject CSS to document head
//id = id of element
//css = custom css
BdApi.injectCSS = function (id, css) {
2017-10-29 23:23:39 +01:00
$("head").append($('<style>', {id: utils.escapeID(id), html: css}));
2017-04-30 03:11:22 +02:00
};
//Clear css/remove any element
//id = id of element
BdApi.clearCSS = function (id) {
2017-10-29 23:23:39 +01:00
$("#" + utils.escapeID(id)).remove();
2017-04-30 03:11:22 +02:00
};
2017-11-03 18:34:26 +01:00
//Inject CSS to document head
//id = id of element
//css = custom css
BdApi.linkJS = function (id, url) {
$("head").append($('<script>', {id: utils.escapeID(id), src: url, type: "text/javascript"}));
};
//Clear css/remove any element
//id = id of element
BdApi.unlinkJS = function (id) {
$("#" + utils.escapeID(id)).remove();
};
2017-04-30 03:11:22 +02:00
//Get another plugin
//name = name of plugin
BdApi.getPlugin = function (name) {
if (bdplugins.hasOwnProperty(name)) {
return bdplugins[name]["plugin"];
}
return null;
};
//Get ipc for reason
BdApi.getIpc = function () {
return betterDiscordIPC;
};
//Get BetterDiscord Core
BdApi.getCore = function () {
return mainCore;
};
2017-11-03 18:34:26 +01:00
//Show modal alert
BdApi.alert = function (title, content) {
mainCore.alert(title, content);
};
2017-11-03 20:52:35 +01:00
//Show toast alert
2017-11-03 18:54:47 +01:00
BdApi.showToast = function(content, options = {}) {
2017-11-03 20:52:35 +01:00
mainCore.showToast(content, options);
2017-11-03 18:54:47 +01:00
};
2017-04-30 03:11:22 +02:00
/* BetterDiscordApp DevMode JavaScript
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 22/05/2016
* Last Update: 22/05/2016
* https://github.com/Jiiks/BetterDiscordApp
*/
function devMode() {}
devMode.prototype.enable = function(selectorMode) {
var self = this;
2017-10-30 08:39:41 +01:00
this.disable();
$(window).on("keydown.bdDevmode", function(e) {
if(e.which === 119) {//F8
2017-11-03 18:34:26 +01:00
console.log('%c[%cDevMode%c] %cBreak/Resume', 'color: red;', 'color: #303030; font-weight:700;', 'color:red;', '');
2017-11-03 04:05:33 +01:00
debugger; // eslint-disable-line no-debugger
}
});
2017-10-30 04:45:07 +01:00
2018-01-09 04:24:00 +01:00
if (!selectorMode) return;
2017-10-30 05:56:20 +01:00
$(document).on("contextmenu.bdDevmode", function(e) {
var parents = [];
$(e.toElement).parents().addBack().not('html').each(function() {
var entry = "";
2017-10-30 05:56:20 +01:00
if (this.classList && this.classList.length) {
entry += "." + Array.prototype.join.call(this.classList, '.');
parents.push(entry);
}
});
self.lastSelector = parents.join(" ").trim();
2017-04-30 03:11:22 +02:00
function attach() {
2018-03-15 15:30:14 +01:00
var cm = $(".contextMenu-uoJTbz");
2017-04-30 03:11:22 +02:00
if(cm.length <= 0) {
2018-03-15 15:30:14 +01:00
cm = $('<div class="contextMenu-uoJTbz bd-context-menu"></div>');
2017-10-30 05:56:20 +01:00
cm.addClass($('.app').hasClass("theme-dark") ? "theme-dark" : "theme-light");
cm.appendTo('.app');
cm.css("top", e.clientY);
cm.css("left", e.clientX);
2017-10-30 06:20:19 +01:00
$(document).on('click.bdDevModeCtx', () => {
cm.remove();
$(document).off('.bdDevModeCtx');
});
$(document).on('contextmenu.bdDevModeCtx', () => {
cm.remove();
$(document).off('.bdDevModeCtx');
});
$(document).on("keyup.bdDevModeCtx", (e) => {
if (e.keyCode === 27) {
cm.remove();
$(document).off('.bdDevModeCtx');
}
});
2017-04-30 03:11:22 +02:00
}
var cmo = $("<div/>", {
2018-03-15 15:30:14 +01:00
class: "itemGroup-oViAgA"
2017-04-30 03:11:22 +02:00
});
var cmi = $("<div/>", {
2018-03-15 15:30:14 +01:00
class: "item-1XYaYf",
2017-04-30 03:11:22 +02:00
click: function() {
var t = $("<textarea/>", { text: self.lastSelector }).appendTo("body");
t.select();
document.execCommand("copy");
t.remove();
2017-10-30 05:56:20 +01:00
//if (cm.hasClass("bd-context-menu")) cm.remove();
cm.hide();
2017-04-30 03:11:22 +02:00
}
}).append($("<span/>", { text: "Copy Selector" }));
cmo.append(cmi);
cm.append(cmo);
2018-03-15 15:30:14 +01:00
if (cm.hasClass("undefined")) cm.css("top", "-=" + cmo.outerHeight());
2017-04-30 03:11:22 +02:00
}
2017-10-30 08:39:41 +01:00
setImmediate(attach);
2017-04-30 03:11:22 +02:00
e.stopPropagation();
});
};
devMode.prototype.disable = function() {
$(window).off("keydown.bdDevmode");
2017-10-30 05:56:20 +01:00
$(document).off("contextmenu.bdDevmode");
2017-10-30 08:35:08 +01:00
$(document).off("contextmenu.bdDevModeCtx");
2017-04-30 03:11:22 +02:00
};
2017-11-03 18:34:26 +01:00
2017-04-30 03:11:22 +02:00
/*V2 Premature*/
window.bdtemp = {
'editorDetached': false
};
class V2 {
constructor() {
2017-12-22 02:02:35 +01:00
this.WebpackModules = (() => {
const req = webpackJsonp([], {
'__extra_id__': (module, exports, req) => exports.default = req
}, ['__extra_id__']).default;
delete req.m['__extra_id__'];
delete req.c['__extra_id__'];
const find = (filter, options = {}) => {
const {cacheOnly = true} = options;
for (let i in req.c) {
if (req.c.hasOwnProperty(i)) {
let m = req.c[i].exports;
if (m && m.__esModule && m.default && filter(m.default)) return m.default;
if (m && filter(m)) return m;
}
}
if (cacheOnly) {
console.warn('Cannot find loaded module in cache');
return null;
}
console.warn('Cannot find loaded module in cache. Loading all modules may have unexpected side effects');
for (let i = 0; i < req.m.length; ++i) {
try {
let m = req(i);
if (m && m.__esModule && m.default && filter(m.default)) return m.default;
if (m && filter(m)) return m;
}
catch (e) {
console.error(e);
}
}
console.warn('Cannot find module');
return null;
};
const findByUniqueProperties = (propNames, options) => find(module => propNames.every(prop => module[prop] !== undefined), options);
const findByDisplayName = (displayName, options) => find(module => module.displayName === displayName, options);
return {find, findByUniqueProperties, findByDisplayName};
})();
2017-04-30 03:11:22 +02:00
this.internal = {
2017-12-22 02:02:35 +01:00
'react': this.WebpackModules.findByUniqueProperties(['Component', 'PureComponent', 'Children', 'createElement', 'cloneElement']),
'react-dom': this.WebpackModules.findByUniqueProperties(['findDOMNode'])
2017-04-30 03:11:22 +02:00
};
2018-03-12 19:36:13 +01:00
this.getInternalInstance = e => e[Object.keys(e).find(k => k.startsWith("__reactInternalInstance"))];
2017-04-30 03:11:22 +02:00
}
get reactComponent() {
return this.internal['react'].Component;
}
get react() {
return this.internal['react'];
}
get reactDom() {
return this.internal['react-dom'];
}
parseSettings(cat) {
return Object.keys(settings).reduce((arr, key) => {
let setting = settings[key];
if(setting.cat === cat && setting.implemented && !setting.hidden) {
setting.text = key;
2017-11-03 04:05:33 +01:00
arr.push(setting);
2017-04-30 03:11:22 +02:00
} return arr;
}, []);
}
}
2017-11-01 18:12:29 +01:00
2017-04-30 03:11:22 +02:00
window.BDV2 = new V2();
class V2C_SettingsPanel extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
let { settings } = this.props;
return BDV2.react.createElement(
"div",
{ className: "content-column default" },
2017-12-24 07:51:24 +01:00
BDV2.react.createElement(V2Components.SettingsTitle, { text: this.props.title}),
this.props.button && BDV2.react.createElement("button", {key: "title-button", className: 'bd-pfbtn', onClick: this.props.button.onClick}, this.props.button.title),
2017-04-30 03:11:22 +02:00
settings.map(setting => {
return BDV2.react.createElement(V2Components.Switch, { id: setting.id, key: setting.id, data: setting, checked: settingsCookie[setting.id], onChange: (id, checked) => {
this.props.onChange(id, checked);
} });
})
);
}
}
class V2C_Switch extends BDV2.reactComponent {
constructor(props) {
super(props);
this.setInitialState();
this.onChange = this.onChange.bind(this);
}
setInitialState() {
this.state = {
'checked': this.props.checked
};
}
render() {
let { text, info } = this.props.data;
let { checked } = this.state;
return BDV2.react.createElement(
"div",
{ className: "ui-flex flex-vertical flex-justify-start flex-align-stretch flex-nowrap ui-switch-item" },
BDV2.react.createElement(
"div",
{ className: "ui-flex flex-horizontal flex-justify-start flex-align-stretch flex-nowrap" },
BDV2.react.createElement(
"h3",
{ className: "ui-form-title h3 margin-reset margin-reset ui-flex-child" },
text
),
BDV2.react.createElement(
"label",
{ className: "ui-switch-wrapper ui-flex-child", style: { flex: '0 0 auto' } },
BDV2.react.createElement("input", { className: "ui-switch-checkbox", type: "checkbox", checked: checked, onChange: e => this.onChange(e) }),
2017-06-17 19:08:43 +02:00
BDV2.react.createElement("div", { className: `ui-switch ${checked ? 'checked' : ''}` })
2017-04-30 03:11:22 +02:00
)
),
BDV2.react.createElement(
"div",
{ className: "ui-form-text style-description margin-top-4", style: { flex: '1 1 auto' } },
info
)
);
}
2017-11-03 04:05:33 +01:00
onChange() {
2017-04-30 03:11:22 +02:00
this.props.onChange(this.props.id, !this.state.checked);
this.setState({
'checked': !this.state.checked
});
}
}
class V2C_Scroller extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
2018-03-29 09:56:07 +02:00
//scrollerWrap-2uBjct scrollerThemed-19vinI themeGhostHairline-2H8SiW scrollerFade-28dRsO
let wrapperClass = `scrollerWrap-2uBjct scrollerThemed-19vinI themeGhostHairline-2H8SiW${this.props.fade ? ' scrollerFade-28dRsO' : ''}`;
2018-03-30 05:08:50 +02:00
let scrollerClass = "scroller-fzNley scroller";
if (this.props.sidebar) scrollerClass = "scroller-fzNley sidebar-region-scroller scroller";
if (this.props.contentColumn) {
scrollerClass = "scroller-fzNley content-region-scroller scroller";
2018-03-30 05:08:50 +02:00
wrapperClass = "scrollerWrap-2uBjct content-region-scroller-wrap scrollerThemed-19vinI themeGhost-10fio9 scrollerTrack-3hhmU0";
}
2017-04-30 03:11:22 +02:00
let { children } = this.props;
return BDV2.react.createElement(
"div",
{ key: "scrollerwrap", className: wrapperClass },
BDV2.react.createElement(
"div",
2018-03-30 05:08:50 +02:00
{ key: "scroller", ref: "scroller", className: scrollerClass },
2017-04-30 03:11:22 +02:00
children
)
);
}
}
class V2C_TabBarItem extends BDV2.reactComponent {
constructor(props) {
super(props);
this.setInitialState();
this.onClick = this.onClick.bind(this);
}
setInitialState() {
this.state = {
'selected': this.props.selected || false
};
}
render() {
return BDV2.react.createElement(
"div",
{ className: `ui-tab-bar-item${this.props.selected ? ' selected' : ''}`, onClick: this.onClick },
this.props.text
);
}
onClick() {
if (this.props.onClick) {
this.props.onClick(this.props.id);
}
}
}
class V2C_TabBarSeparator extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
return BDV2.react.createElement("div", { className: "ui-tab-bar-separator margin-top-8 margin-bottom-8" });
}
}
class V2C_TabBarHeader extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
return BDV2.react.createElement(
"div",
{ className: "ui-tab-bar-header" },
this.props.text
);
}
}
class V2C_SideBar extends BDV2.reactComponent {
constructor(props) {
super(props);
let self = this;
2017-06-17 19:08:43 +02:00
const si = $("[class*=side] > [class*=selected]");
if(si.length) {
self.scn = si.attr("class");
}
const ns = $("[class*=side] > [class*=notSelected]");
if(ns.length) {
self.nscn = ns.attr("class");
}
2018-02-05 23:48:19 +01:00
$("[class*='side-'] > [class*='item-']").on("click", () => {
2017-04-30 03:11:22 +02:00
self.setState({
'selected': null
});
});
self.setInitialState();
self.onClick = self.onClick.bind(self);
}
setInitialState() {
let self = this;
self.state = {
'selected': null,
'items': self.props.items
};
let initialSelection = self.props.items.find(item => {
return item.selected;
});
if (initialSelection) {
self.state.selected = initialSelection.id;
}
}
render() {
let self = this;
let { headerText } = self.props;
let { items, selected } = self.state;
return BDV2.react.createElement(
"div",
null,
BDV2.react.createElement(V2Components.TabBar.Separator, null),
BDV2.react.createElement(V2Components.TabBar.Header, { text: headerText }),
items.map(item => {
let { id, text } = item;
return BDV2.react.createElement(V2Components.TabBar.Item, { key: id, selected: selected === id, text: text, id: id, onClick: self.onClick });
})
);
}
onClick(id) {
let self = this;
2017-06-17 19:08:43 +02:00
const si = $("[class*=side] > [class*=selected]");
if(si.length) {
si.off("click.bdsb").on("click.bsb", e => {
$(e.target).attr("class", self.scn);
});
si.attr("class", self.nscn);
}
2017-11-03 04:05:33 +01:00
self.setState({'selected': null});
self.setState({'selected': id});
2017-04-30 03:11:22 +02:00
if (self.props.onClick) self.props.onClick(id);
}
}
class V2C_XSvg extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
return BDV2.react.createElement(
"svg",
{ xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 12 12", style: { width: "18px", height: "18px" } },
BDV2.react.createElement(
"g",
2017-10-29 22:20:45 +01:00
{ className: "background", fill: "none", "fillRule": "evenodd" },
2017-04-30 03:11:22 +02:00
BDV2.react.createElement("path", { d: "M0 0h12v12H0" }),
BDV2.react.createElement("path", { className: "fill", fill: "#dcddde", d: "M9.5 3.205L8.795 2.5 6 5.295 3.205 2.5l-.705.705L5.295 6 2.5 8.795l.705.705L6 6.705 8.795 9.5l.705-.705L6.705 6" })
)
);
}
}
class V2C_Tools extends BDV2.reactComponent {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
render() {
return BDV2.react.createElement(
"div",
{ className: "tools" },
BDV2.react.createElement(
"div",
{ className: "btn-close", onClick: this.onClick },
BDV2.react.createElement(V2Components.XSvg, null)
),
BDV2.react.createElement(
"div",
{ className: "esc-text" },
"ESC"
)
);
}
onClick() {
if (this.props.onClick) {
this.props.onClick();
}
$(".btn-close").first().click();
}
}
class V2C_SettingsTitle extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
return BDV2.react.createElement(
"h2",
{ className: "ui-form-title h2 margin-reset margin-bottom-20" },
this.props.text
);
}
}
class V2C_Checkbox extends BDV2.reactComponent {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
this.setInitialState();
}
setInitialState() {
this.state = {
'checked': this.props.checked || false
};
}
render() {
return BDV2.react.createElement(
"li",
null,
BDV2.react.createElement(
"div",
{ className: "checkbox", onClick: this.onClick },
BDV2.react.createElement(
"div",
{ className: "checkbox-inner" },
BDV2.react.createElement("input", { checked: this.state.checked, onChange: () => {}, type: "checkbox" }),
BDV2.react.createElement("span", null)
),
BDV2.react.createElement(
"span",
null,
this.props.text
)
)
);
}
onClick() {
this.props.onChange(this.props.id, !this.state.checked);
this.setState({
'checked': !this.state.checked
});
}
}
class V2C_CssEditorDetached extends BDV2.reactComponent {
constructor(props) {
super(props);
let self = this;
self.onClick = self.onClick.bind(self);
self.updateCss = self.updateCss.bind(self);
self.saveCss = self.saveCss.bind(self);
self.onChange = self.onChange.bind(self);
}
componentDidMount() {
$("#app-mount").addClass('bd-detached-editor');
window.bdtemp.editorDetached = true;
// this.updateLineCount();
this.editor = ace.edit("bd-customcss-editor-detached");
this.editor.setTheme("ace/theme/monokai");
this.editor.session.setMode("ace/mode/css");
this.editor.setShowPrintMargin(false);
this.editor.setFontSize(14);
this.editor.on('change', () => {
if (!settingsCookie["bda-css-0"]) return;
this.saveCss();
this.updateCss();
});
2017-04-30 03:11:22 +02:00
}
componentWillUnmount() {
$("#app-mount").removeClass('bd-detached-editor');
window.bdtemp.editorDetached = false;
this.editor.destroy();
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
updateLineCount() {
let lineCount = this.refs.editor.value.split('\n').length;
if (lineCount == this.props.lines) return;
this.refs.lines.textContent = Array.from(new Array(lineCount), (_, i) => i + 1).join(".\n") + ".";
this.props.lines = lineCount;
}
2017-04-30 03:11:22 +02:00
get options() {
return {
lineNumbers: true,
mode: 'css',
indentUnit: 4,
theme: 'material',
scrollbarStyle: 'simple'
};
}
get css() {
let _ccss = window.bdStorage.get("bdcustomcss");
let ccss = "";
if (_ccss && _ccss !== "") {
ccss = atob(_ccss);
}
return ccss;
}
get root() {
let _root = $("#bd-customcss-detach-container");
if (!_root.length) {
if (!this.injectRoot()) return null;
return this.detachedRoot;
}
return _root[0];
}
injectRoot() {
if (!$(".app").length) return false;
$("<div/>", {
id: 'bd-customcss-detach-container'
}).insertAfter($(".app"));
return true;
}
render() {
let self = this;
return BDV2.react.createElement(
"div",
{ className: "bd-detached-css-editor", id: "bd-customcss-detach-editor" },
BDV2.react.createElement(
"div",
{ id: "bd-customcss-innerpane" },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement("div", {className: "editor-wrapper"},
BDV2.react.createElement("div", {id: "bd-customcss-editor-detached", className: "editor", ref: "editor"}, self.css)
2018-01-09 04:24:00 +01:00
),
2017-04-30 03:11:22 +02:00
BDV2.react.createElement(
"div",
{ id: "bd-customcss-attach-controls" },
BDV2.react.createElement(
"ul",
{ className: "checkbox-group" },
BDV2.react.createElement(V2Components.Checkbox, { id: "live-update", text: "Live Update", onChange: self.onChange, checked: settingsCookie["bda-css-0"] })
),
BDV2.react.createElement(
"div",
{ id: "bd-customcss-detach-controls-button" },
BDV2.react.createElement(
"button",
{ style: { borderRadius: "3px 0 0 3px", borderRight: "1px solid #3f4146" }, className: "btn btn-primary", onClick: () => {
self.onClick("update");
} },
"Update"
),
BDV2.react.createElement(
"button",
{ style: { borderRadius: "0", borderLeft: "1px solid #2d2d2d", borderRight: "1px solid #2d2d2d" }, className: "btn btn-primary", onClick: () => {
self.onClick("save");
} },
"Save"
),
BDV2.react.createElement(
"button",
{ style: { borderRadius: "0 3px 3px 0", borderLeft: "1px solid #3f4146" }, className: "btn btn-primary", onClick: () => {
self.onClick("attach");
} },
"Attach"
),
BDV2.react.createElement(
"span",
{ style: { fontSize: "10px", marginLeft: "5px" } },
"Unsaved changes are lost on attach"
)
)
)
)
);
}
onChange(id, checked) {
switch (id) {
case 'live-update':
settingsCookie["bda-css-0"] = checked;
mainCore.saveSettings();
break;
}
}
onClick(id) {
let self = this;
switch (id) {
case 'attach':
if ($("#editor-detached").length) self.props.attach();
2017-04-30 03:11:22 +02:00
BDV2.reactDom.unmountComponentAtNode(self.root);
self.root.remove();
2017-04-30 03:11:22 +02:00
break;
case 'update':
self.updateCss();
break;
case 'save':
self.saveCss();
break;
}
}
updateCss() {
if ($("#customcss").length == 0) {
$("head").append('<style id="customcss"></style>');
}
$("#customcss").html(this.editor.session.getValue()).detach().appendTo(document.head);
2017-04-30 03:11:22 +02:00
}
saveCss() {
window.bdStorage.set("bdcustomcss", btoa(this.editor.session.getValue()));
2017-04-30 03:11:22 +02:00
}
}
class V2C_CssEditor extends BDV2.reactComponent {
constructor(props) {
super(props);
let self = this;
2018-01-09 04:24:00 +01:00
self.props.lines = 0;
2017-04-30 03:11:22 +02:00
self.setInitialState();
self.attach = self.attach.bind(self);
self.detachedEditor = BDV2.react.createElement(V2C_CssEditorDetached, { attach: self.attach });
2017-04-30 03:11:22 +02:00
self.onClick = self.onClick.bind(self);
self.updateCss = self.updateCss.bind(self);
self.saveCss = self.saveCss.bind(self);
self.detach = self.detach.bind(self);
}
setInitialState() {
this.state = {
'detached': this.props.detached || window.bdtemp.editorDetached
};
}
componentDidMount() {
// this.updateLineCount();
this.editor = ace.edit("bd-customcss-editor");
this.editor.setTheme("ace/theme/monokai");
this.editor.session.setMode("ace/mode/css");
this.editor.setShowPrintMargin(false);
this.editor.setFontSize(14);
this.editor.on('change', () => {
if (!settingsCookie["bda-css-0"]) return;
this.saveCss();
this.updateCss();
});
}
componentWillUnmount() {
this.editor.destroy();
2017-04-30 03:11:22 +02:00
}
componentDidUpdate(prevProps, prevState) {
let self = this;
if (prevState.detached && !self.state.detached) {
BDV2.reactDom.unmountComponentAtNode(self.detachedRoot);
}
}
codeMirror() {
}
get options() {
return {
lineNumbers: true,
mode: 'css',
indentUnit: 4,
theme: 'material',
scrollbarStyle: 'simple'
};
}
get css() {
let _ccss = window.bdStorage.get("bdcustomcss");
let ccss = "";
if (_ccss && _ccss !== "") {
ccss = atob(_ccss);
}
return ccss;
}
2018-01-09 04:24:00 +01:00
updateLineCount() {
let lineCount = this.refs.editor.value.split('\n').length;
if (lineCount == this.props.lines) return;
this.refs.lines.textContent = Array.from(new Array(lineCount), (_, i) => i + 1).join(".\n") + ".";
this.props.lines = lineCount;
}
2017-04-30 03:11:22 +02:00
render() {
let self = this;
let { detached } = self.state;
return BDV2.react.createElement(
"div",
{ className: "content-column default", style: { padding: '60px 40px 0px' } },
detached && BDV2.react.createElement(
"div",
{ id: "editor-detached" },
BDV2.react.createElement(V2Components.SettingsTitle, { text: "Custom CSS Editor" }),
BDV2.react.createElement(
"h3",
null,
"Editor Detached"
),
BDV2.react.createElement(
"button",
{ className: "btn btn-primary", onClick: () => {
self.attach();
} },
"Attach"
)
),
!detached && BDV2.react.createElement(
"div",
null,
BDV2.react.createElement(V2Components.SettingsTitle, { text: "Custom CSS Editor" }),
2018-01-09 04:24:00 +01:00
BDV2.react.createElement("div", {className: "editor-wrapper"},
BDV2.react.createElement("div", {id: "bd-customcss-editor", className: "editor", ref: "editor"}, self.css)
2018-01-09 04:24:00 +01:00
),
2017-04-30 03:11:22 +02:00
BDV2.react.createElement(
"div",
{ id: "bd-customcss-attach-controls" },
BDV2.react.createElement(
"ul",
{ className: "checkbox-group" },
BDV2.react.createElement(V2Components.Checkbox, { id: "live-update", text: "Live Update", onChange: this.onChange, checked: settingsCookie["bda-css-0"] })
),
BDV2.react.createElement(
"div",
{ id: "bd-customcss-detach-controls-button" },
BDV2.react.createElement(
"button",
{ style: { borderRadius: "3px 0 0 3px", borderRight: "1px solid #3f4146" }, className: "btn btn-primary", onClick: () => {
self.onClick("update");
} },
"Update"
),
BDV2.react.createElement(
"button",
{ style: { borderRadius: "0", borderLeft: "1px solid #2d2d2d", borderRight: "1px solid #2d2d2d" }, className: "btn btn-primary", onClick: () => {
self.onClick("save");
} },
"Save"
),
BDV2.react.createElement(
"button",
{ style: { borderRadius: "0 3px 3px 0", borderLeft: "1px solid #3f4146" }, className: "btn btn-primary", onClick: () => {
self.onClick("detach");
} },
"Detach"
),
BDV2.react.createElement(
"span",
{ style: { fontSize: "10px", marginLeft: "5px" } },
"Unsaved changes are lost on detach"
)
)
)
)
);
}
onClick(arg) {
let self = this;
switch (arg) {
case 'update':
self.updateCss();
break;
case 'save':
self.saveCss();
break;
case 'detach':
self.detach();
break;
}
}
onChange(id, checked) {
switch (id) {
case 'live-update':
settingsCookie["bda-css-0"] = checked;
mainCore.saveSettings();
break;
}
}
updateCss() {
if ($("#customcss").length == 0) {
$("head").append('<style id="customcss"></style>');
}
$("#customcss").html(this.editor.session.getValue()).detach().appendTo(document.head);
2017-04-30 03:11:22 +02:00
}
saveCss() {
window.bdStorage.set("bdcustomcss", btoa(this.editor.session.getValue()));
2017-04-30 03:11:22 +02:00
}
detach() {
let self = this;
self.setState({
'detached': true
});
let droot = self.detachedRoot;
if (!droot) {
console.log("FAILED TO INJECT ROOT: .app");
return;
}
BDV2.reactDom.render(self.detachedEditor, droot);
}
get detachedRoot() {
let _root = $("#bd-customcss-detach-container");
if (!_root.length) {
if (!this.injectDetachedRoot()) return null;
return this.detachedRoot;
}
return _root[0];
}
injectDetachedRoot() {
if (!$(".app").length) return false;
$("<div/>", {
id: 'bd-customcss-detach-container'
}).insertAfter($(".app"));
return true;
}
attach() {
let self = this;
self.setState({
'detached': false
});
}
}
class V2C_List extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
return BDV2.react.createElement(
"ul",
{ className: this.props.className },
this.props.children
);
}
}
class V2C_ContentColumn extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
return BDV2.react.createElement(
"div",
{ className: "content-column default" },
BDV2.react.createElement(
"h2",
{ className: "ui-form-title h2 margin-reset margin-bottom-20" },
this.props.title
),
this.props.children
);
}
}
class V2C_PluginCard extends BDV2.reactComponent {
constructor(props) {
super(props);
let self = this;
self.onChange = self.onChange.bind(self);
self.showSettings = self.showSettings.bind(self);
self.setInitialState();
self.hasSettings = typeof self.props.plugin.getSettingsPanel === "function";
2018-01-09 04:24:00 +01:00
self.settingsPanel = "";
2017-04-30 03:11:22 +02:00
}
setInitialState() {
this.state = {
'checked': pluginCookie[this.props.plugin.getName()],
'settings': false
};
}
componentDidUpdate() {
if (this.state.settings) {
2017-04-30 13:02:42 +02:00
if (typeof this.settingsPanel === "object") {
this.refs.settingspanel.appendChild(this.settingsPanel);
}
2017-12-24 07:51:24 +01:00
if (!settingsCookie['fork-ps-3']) return;
var isHidden = (container, element) => {
let cTop = container.scrollTop;
let cBottom = cTop + container.clientHeight;
let eTop = element.offsetTop;
let eBottom = eTop + element.clientHeight;
return (eTop < cTop || eBottom > cBottom);
2018-01-09 04:24:00 +01:00
};
2017-12-24 07:51:24 +01:00
let self = $(BDV2.reactDom.findDOMNode(this));
let container = self.parents('.scroller');
if (!isHidden(container[0], self[0])) return;
container.animate({
scrollTop: self.offset().top - container.offset().top + container.scrollTop() - 30
}, 300);
2017-04-30 03:11:22 +02:00
}
}
render() {
2017-04-30 13:02:42 +02:00
let self = this;
2017-04-30 03:11:22 +02:00
let { plugin } = this.props;
let name = plugin.getName();
let author = plugin.getAuthor();
let description = plugin.getDescription();
let version = plugin.getVersion();
2017-11-01 19:52:57 +01:00
let website = bdplugins[name].website;
let source = bdplugins[name].source;
//let { settingsPanel } = this;
2017-04-30 03:11:22 +02:00
if (this.state.settings) {
2017-12-22 23:06:56 +01:00
try { self.settingsPanel = plugin.getSettingsPanel(); }
catch (err) { utils.err("Unable to get settings panel for " + plugin.getName() + ".", err); }
2017-11-01 18:28:04 +01:00
return BDV2.react.createElement("li", {className: "settings-open ui-switch-item"},
BDV2.react.createElement("div", {style: { float: "right", cursor: "pointer" }, onClick: () => {
2017-11-01 18:12:29 +01:00
this.refs.settingspanel.innerHTML = "";
2017-11-01 18:28:04 +01:00
self.setState({'settings': false });
}},
2017-04-30 03:11:22 +02:00
BDV2.react.createElement(V2Components.XSvg, null)
),
2017-12-22 23:06:56 +01:00
typeof self.settingsPanel === 'object' && BDV2.react.createElement("div", { id: `plugin-settings-${name}`, className: "plugin-settings", ref: "settingspanel" }),
typeof self.settingsPanel !== 'object' && BDV2.react.createElement("div", { id: `plugin-settings-${name}`, className: "plugin-settings", ref: "settingspanel", dangerouslySetInnerHTML: { __html: self.settingsPanel } })
2017-04-30 03:11:22 +02:00
);
}
2017-11-01 18:12:29 +01:00
return BDV2.react.createElement("li", {"data-name": name, "data-version": version, className: "settings-closed ui-switch-item"},
BDV2.react.createElement("div", {className: "bda-header"},
2017-11-01 17:09:58 +01:00
BDV2.react.createElement("span", {className: "bda-header-title" },
BDV2.react.createElement("span", {className: "bda-name" }, name),
" v",
BDV2.react.createElement("span", {className: "bda-version" }, version),
" by ",
BDV2.react.createElement("span", {className: "bda-author" }, author)
),
BDV2.react.createElement("label", {className: "ui-switch-wrapper ui-flex-child", style: { flex: '0 0 auto' }},
2017-11-01 16:21:55 +01:00
BDV2.react.createElement("input", { checked: this.state.checked, onChange: this.onChange, className: "ui-switch-checkbox", type: "checkbox" }),
2017-11-01 18:12:29 +01:00
BDV2.react.createElement("div", { className: this.state.checked ? "ui-switch checked" : "ui-switch" })
2017-04-30 03:11:22 +02:00
)
),
2017-11-01 18:12:29 +01:00
BDV2.react.createElement("div", {className: "bda-description-wrap scroller-wrap fade"},
BDV2.react.createElement("div", {className: "bda-description scroller"}, description)
2017-11-01 16:21:55 +01:00
),
2017-12-24 07:51:24 +01:00
(website || source || this.hasSettings) && BDV2.react.createElement("div", {className: "bda-footer"},
2017-11-01 18:12:29 +01:00
BDV2.react.createElement("span", {className: "bda-links"},
website && BDV2.react.createElement("a", {className: "bda-link", href: website, target: "_blank"}, "Website"),
website && source && " | ",
source && BDV2.react.createElement("a", {className: "bda-link", href: source, target: "_blank"}, "Source")
),
this.hasSettings && BDV2.react.createElement("button", {onClick: this.showSettings, className: "bda-settings-button", disabled: !this.state.checked}, "Settings")
2017-04-30 03:11:22 +02:00
)
);
}
onChange() {
2017-11-01 18:34:00 +01:00
this.setState({'checked': !this.state.checked});
pluginModule.togglePlugin(this.props.plugin.getName());
2017-04-30 03:11:22 +02:00
}
showSettings() {
if (!this.hasSettings) return;
2017-11-01 18:28:04 +01:00
this.setState({'settings': true});
2017-04-30 03:11:22 +02:00
}
}
class V2C_ThemeCard extends BDV2.reactComponent {
constructor(props) {
super(props);
this.setInitialState();
this.onChange = this.onChange.bind(this);
}
setInitialState() {
this.state = {
'checked': themeCookie[this.props.theme.name]
};
}
render() {
let { theme } = this.props;
2017-10-31 10:12:58 +01:00
let name = theme.name;
2017-04-30 03:11:22 +02:00
let description = theme.description;
let version = theme.version;
let author = theme.author;
2017-11-01 18:12:29 +01:00
let website = bdthemes[name].website;
let source = bdthemes[name].source;
2017-11-01 17:09:58 +01:00
2017-11-01 18:28:04 +01:00
return BDV2.react.createElement("li", {"data-name": name, "data-version": version, className: "settings-closed ui-switch-item"},
BDV2.react.createElement("div", {className: "bda-header"},
2017-11-01 17:09:58 +01:00
BDV2.react.createElement("span", {className: "bda-header-title" },
BDV2.react.createElement("span", {className: "bda-name" }, name),
" v",
BDV2.react.createElement("span", {className: "bda-version" }, version),
" by ",
BDV2.react.createElement("span", {className: "bda-author" }, author)
),
2017-11-01 17:56:51 +01:00
BDV2.react.createElement("label", {className: "ui-switch-wrapper ui-flex-child", style: { flex: '0 0 auto' }},
BDV2.react.createElement("input", { checked: this.state.checked, onChange: this.onChange, className: "ui-switch-checkbox", type: "checkbox" }),
2017-11-01 18:12:29 +01:00
BDV2.react.createElement("div", { className: this.state.checked ? "ui-switch checked" : "ui-switch" })
2017-11-01 17:56:51 +01:00
)
2017-04-30 03:11:22 +02:00
),
2017-11-01 18:28:04 +01:00
BDV2.react.createElement("div", {className: "bda-description-wrap scroller-wrap fade"},
BDV2.react.createElement("div", {className: "bda-description scroller"}, description)
2017-11-01 17:09:58 +01:00
),
2017-12-24 07:51:24 +01:00
(website || source) && BDV2.react.createElement("div", {className: "bda-footer"},
2017-11-01 18:12:29 +01:00
BDV2.react.createElement("span", {className: "bda-links"},
website && BDV2.react.createElement("a", {className: "bda-link", href: website, target: "_blank"}, "Website"),
website && source && " | ",
source && BDV2.react.createElement("a", {className: "bda-link", href: source, target: "_blank"}, "Source")
)
2017-04-30 03:11:22 +02:00
)
);
}
onChange() {
2017-11-01 18:34:00 +01:00
this.setState({'checked': !this.state.checked});
themeModule.toggleTheme(this.props.theme.name);
2017-04-30 03:11:22 +02:00
}
}
class V2Cs_TabBar {
static get Item() {
return V2C_TabBarItem;
}
static get Header() {
return V2C_TabBarHeader;
}
static get Separator() {
return V2C_TabBarSeparator;
}
}
2018-01-09 04:24:00 +01:00
class V2Components {
static get SettingsPanel() {
return V2C_SettingsPanel;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
static get Switch() {
return V2C_Switch;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
static get Scroller() {
return V2C_Scroller;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
static get TabBar() {
return V2Cs_TabBar;
}
static get SideBar() {
return V2C_SideBar;
}
static get Tools() {
return V2C_Tools;
}
static get SettingsTitle() {
return V2C_SettingsTitle;
}
static get CssEditor() {
return V2C_CssEditor;
}
static get Checkbox() {
return V2C_Checkbox;
}
static get List() {
return V2C_List;
}
static get PluginCard() {
return V2C_PluginCard;
}
static get ThemeCard() {
return V2C_ThemeCard;
}
static get ContentColumn() {
return V2C_ContentColumn;
}
static get XSvg() {
return V2C_XSvg;
}
static get Layer() {
return V2C_Layer;
}
static get SidebarView() {
return V2C_SidebarView;
}
static get ServerCard() {
return V2C_ServerCard;
2017-04-30 03:11:22 +02:00
}
}
2018-01-09 04:24:00 +01:00
class V2_SettingsPanel_Sidebar {
2017-04-30 03:11:22 +02:00
2018-01-09 04:24:00 +01:00
constructor(onClick) {
this.onClick = onClick;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
get items() {
return [{ 'text': 'Core', 'id': 'core' }, { 'text': 'Zere\'s Fork', 'id': 'fork' }, { 'text': 'Emotes', 'id': 'emotes' }, { 'text': 'Custom CSS', 'id': 'customcss' }, { 'text': 'Plugins', 'id': 'plugins' }, { 'text': 'Themes', 'id': 'themes' }];
}
get component() {
2017-04-30 03:11:22 +02:00
return BDV2.react.createElement(
2018-01-09 04:24:00 +01:00
"span",
null,
BDV2.react.createElement(V2Components.SideBar, { onClick: this.onClick, headerText: "Bandaged BD", items: this.items }),
2017-04-30 03:11:22 +02:00
BDV2.react.createElement(
"div",
2018-01-09 04:24:00 +01:00
{ style: { fontSize: "12px", fontWeight: "600", color: "#72767d", padding: "2px 10px" } },
`BD v${bdVersion}, JS v${jsVersion} by `,
BDV2.react.createElement(
"a",
{ href: "https://github.com/Jiiks/", target: "_blank" },
"Jiiks"
)
2017-04-30 03:11:22 +02:00
),
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
2017-04-30 03:11:22 +02:00
"div",
2018-01-09 04:24:00 +01:00
{ style: { fontSize: "12px", fontWeight: "600", color: "#72767d", padding: "2px 10px" } },
`BBD v${bbdVersion} by `,
BDV2.react.createElement(
"a",
{ href: "https://github.com/rauenzi/", target: "_blank" },
"Zerebos"
)
2017-04-30 03:11:22 +02:00
)
);
}
2018-01-09 04:24:00 +01:00
get root() {
let _root = $("#bd-settings-sidebar");
if (!_root.length) {
if (!this.injectRoot()) return null;
return this.root;
}
return _root[0];
}
injectRoot() {
2018-02-05 23:48:19 +01:00
let changeLog = $("[class*='side-'] > [class*='item-']:not([class*=Danger])").last();
2018-01-09 04:24:00 +01:00
if (!changeLog.length) return false;
$("<span/>", { 'id': 'bd-settings-sidebar' }).insertBefore(changeLog.prev());
return true;
2017-04-30 03:11:22 +02:00
}
render() {
2018-01-09 04:24:00 +01:00
let root = this.root;
if (!root) {
2018-02-05 23:48:19 +01:00
console.log("FAILED TO LOCATE ROOT: [class*='side-'] > [class*='item-']:not([class*=Danger])");
2018-01-09 04:24:00 +01:00
return;
}
BDV2.reactDom.render(this.component, root);
}
}
2017-04-30 03:11:22 +02:00
class V2_SettingsPanel {
constructor() {
let self = this;
self.sideBarOnClick = self.sideBarOnClick.bind(self);
self.onChange = self.onChange.bind(self);
self.updateSettings = this.updateSettings.bind(self);
self.sidebar = new V2_SettingsPanel_Sidebar(self.sideBarOnClick);
}
get root() {
let _root = $("#bd-settingspane-container");
if (!_root.length) {
if (!this.injectRoot()) return null;
return this.root;
}
return _root[0];
}
injectRoot() {
if (!$(".layer .ui-standard-sidebar-view, .layer-kosS71 .ui-standard-sidebar-view").length) return false;
$(".layer .ui-standard-sidebar-view, .layer-kosS71 .ui-standard-sidebar-view").append($("<div/>", {
2017-04-30 03:11:22 +02:00
class: 'content-region',
id: 'bd-settingspane-container'
}));
return true;
}
get coreSettings() {
return this.getSettings("core");
2017-12-24 07:51:24 +01:00
}
get forkSettings() {
return this.getSettings("fork");
2017-04-30 03:11:22 +02:00
}
get emoteSettings() {
return this.getSettings("emote");
}
getSettings(category) {
return Object.keys(settings).reduce((arr, key) => {
let setting = settings[key];
if (setting.cat === category && setting.implemented && !setting.hidden) {
setting.text = key;
arr.push(setting);
}
return arr;
}, []);
}
sideBarOnClick(id) {
let self = this;
$(".content-region").first().hide();
$(self.root).show();
switch (id) {
case 'core':
self.renderCoreSettings();
break;
2017-12-24 07:51:24 +01:00
case 'fork':
self.renderForkSettings();
break;
2017-04-30 03:11:22 +02:00
case 'emotes':
self.renderEmoteSettings();
break;
case 'customcss':
self.renderCustomCssEditor();
break;
case 'plugins':
self.renderPluginPane();
break;
case 'themes':
self.renderThemePane();
break;
}
}
2017-11-03 04:05:33 +01:00
onClick() {}
2017-04-30 03:11:22 +02:00
onChange(id, checked) {
settingsCookie[id] = checked;
this.updateSettings();
}
updateSettings() {
2017-10-30 22:33:38 +01:00
let _c = settingsCookie;
if (_c["bda-es-0"]) {
$("#twitchcord-button-container").show();
} else {
$("#twitchcord-button-container").hide();
}
if (_c["bda-gs-b"]) {
$("body").addClass("bd-blue");
} else {
$("body").removeClass("bd-blue");
}
if (_c["bda-gs-2"]) {
$("body").addClass("bd-minimal");
} else {
$("body").removeClass("bd-minimal");
}
if (_c["bda-gs-3"]) {
$("body").addClass("bd-minimal-chan");
} else {
$("body").removeClass("bd-minimal-chan");
}
if (_c["bda-gs-1"]) {
$("#bd-pub-li").show();
} else {
$("#bd-pub-li").hide();
}
if (_c["bda-gs-4"]) {
voiceMode.enable();
} else {
voiceMode.disable();
}
if (_c["bda-gs-5"]) {
$("#app-mount").addClass("bda-dark");
} else {
$("#app-mount").removeClass("bda-dark");
}
2017-11-04 06:59:30 +01:00
if (document.querySelector('.messages')) {
let elem = document.querySelector('.messages');
if (_c["bda-gs-6"]) {
mainCore.inject24Hour(elem);
} else {
mainCore.remove24Hour(elem);
}
if (_c["bda-gs-7"] && document.querySelector('.messages')) {
mainCore.injectColoredText(elem);
} else {
mainCore.removeColoredText(elem);
}
}
2017-12-24 07:51:24 +01:00
if (_c["fork-es-2"]) {
$('.emote').each(() => {
2018-01-09 04:24:00 +01:00
$(this).addClass("stop-animation");
2017-12-24 07:51:24 +01:00
});
}
else {
$('.emote').each(() => {
2018-01-09 04:24:00 +01:00
$(this).removeClass("stop-animation");
2017-12-24 07:51:24 +01:00
});
}
$(document).off('mouseover', '.emote');
//Pretty emote titles
var emoteNamePopup = $("<div class='tipsy tipsy-se' style='display: block; top: 82px; left: 1630.5px; visibility: visible; opacity: 0.8;'><div class='tipsy-inner'></div></div>");
$(document).on("mouseover", ".emote", function () {
var emote = $(this);
if (_c["fork-es-2"] && _c["bda-es-8"]) emote.removeClass("stop-animation");
if (!_c["bda-es-6"]) return;
var x = emote.offset();
var title = emote.attr("alt");
2018-01-09 04:24:00 +01:00
var modifier = emote.attr("data-modifier");
2017-12-24 07:51:24 +01:00
if (modifier && _c["fork-es-1"]) title = title + ":" + modifier;
emoteNamePopup.find(".tipsy-inner").text(title);
$(".app").append($(emoteNamePopup));
var nodecenter = x.left + (emote.outerWidth() / 2);
emoteNamePopup.css("left", nodecenter - (emoteNamePopup.outerWidth() / 2));
emoteNamePopup.css('top', x.top - emoteNamePopup.outerHeight());
});
$(document).on("mouseleave", ".emote", function () {
if (_c["bda-es-6"]) $(".tipsy").remove();
if (_c["fork-es-2"] && _c["bda-es-8"]) $(this).addClass("stop-animation");
});
2017-10-30 22:33:38 +01:00
if (_c["bda-gs-8"]) {
2017-12-24 07:51:24 +01:00
dMode.enable(_c["fork-dm-1"]);
2017-10-30 22:33:38 +01:00
} else {
dMode.disable();
}
mainCore.saveSettings();
2017-04-30 03:11:22 +02:00
}
renderSidebar() {
let self = this;
2018-02-05 23:48:19 +01:00
$("[class*='side-'] > [class*='item-']").off('click.v2settingspanel').on('click.v2settingspanel', () => {
2017-04-30 03:11:22 +02:00
BDV2.reactDom.unmountComponentAtNode(self.root);
$(self.root).hide();
$(".content-region").first().show();
});
self.sidebar.render();
}
get coreComponent() {
2018-03-30 05:08:50 +02:00
return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [BDV2.react.createElement(V2Components.SettingsPanel, { key: "cspanel", title: "Core Settings", onChange: this.onChange, settings: this.coreSettings }), BDV2.react.createElement(V2Components.Tools, { key: "tools" })] });
2017-04-30 03:11:22 +02:00
}
2017-12-24 07:51:24 +01:00
get forkComponent() {
return BDV2.react.createElement(V2Components.Scroller, {
2018-03-30 05:08:50 +02:00
contentColumn: true,
2017-12-24 07:51:24 +01:00
fade: true,
dark: true,
children: [
BDV2.react.createElement(V2Components.SettingsPanel, { key: "fspanel", title: "Zere's Fork Settings", onChange: this.onChange, settings: this.forkSettings, button: {
2018-01-09 04:24:00 +01:00
title: "Clear Emote Cache",
2018-01-09 22:32:02 +01:00
onClick: () => { emoteModule.clearEmoteData(); emoteModule.init(); quickEmoteMenu.init(); }
2017-12-24 07:51:24 +01:00
}}),
BDV2.react.createElement(V2Components.Tools, { key: "tools" })
]
}
);
}
2017-04-30 03:11:22 +02:00
get emoteComponent() {
2018-03-30 05:08:50 +02:00
return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [BDV2.react.createElement(V2Components.SettingsPanel, { key: "espanel", title: "Emote Settings", onChange: this.onChange, settings: this.emoteSettings }), BDV2.react.createElement(V2Components.Tools, { key: "tools" })] });
2017-04-30 03:11:22 +02:00
}
get customCssComponent() {
2018-03-30 05:08:50 +02:00
return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [BDV2.react.createElement(V2Components.CssEditor, { key: "csseditor" }), BDV2.react.createElement(V2Components.Tools, { key: "tools" })] });
2017-04-30 03:11:22 +02:00
}
get pluginsComponent() {
let plugins = Object.keys(bdplugins).reduce((arr, key) => {
arr.push(BDV2.react.createElement(V2Components.PluginCard, { key: key, plugin: bdplugins[key].plugin }));return arr;
}, []);
let list = BDV2.react.createElement(V2Components.List, { key: "plugin-list", className: "bda-slist", children: plugins });
2017-10-29 22:20:45 +01:00
let pfBtn = BDV2.react.createElement("button", {key: "folder-button", className: 'bd-pfbtn', onClick: () => { betterDiscordIPC.send('asynchronous-message', { 'arg': 'opendir', 'path': 'plugindir' }); }}, "Open Plugin Folder");
2017-05-12 21:45:19 +02:00
let contentColumn = BDV2.react.createElement(V2Components.ContentColumn, { key: "pcolumn", title: "Plugins", children: [pfBtn, list] });
2018-03-30 05:08:50 +02:00
return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [contentColumn, BDV2.react.createElement(V2Components.Tools, { key: "tools" })] });
2017-04-30 03:11:22 +02:00
}
get themesComponent() {
let themes = Object.keys(bdthemes).reduce((arr, key) => {
arr.push(BDV2.react.createElement(V2Components.ThemeCard, { key: key, theme: bdthemes[key] }));return arr;
}, []);
let list = BDV2.react.createElement(V2Components.List, { key: "theme-list", className: "bda-slist", children: themes });
2017-10-29 22:20:45 +01:00
let tfBtn = BDV2.react.createElement("button", {key: "folder-button", className: 'bd-pfbtn', onClick: () => { betterDiscordIPC.send('asynchronous-message', { 'arg': 'opendir', 'path': 'themedir' }); }}, "Open Theme Folder");
2017-05-12 21:45:19 +02:00
let contentColumn = BDV2.react.createElement(V2Components.ContentColumn, { key: "tcolumn", title: "Themes", children: [tfBtn, list] });
2018-03-30 05:08:50 +02:00
return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [contentColumn, BDV2.react.createElement(V2Components.Tools, { key: "tools" })] });
2017-04-30 03:11:22 +02:00
}
renderCoreSettings() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layer .ui-standard-sidebar-view");
return;
}
BDV2.reactDom.render(this.coreComponent, root);
}
2017-12-24 07:51:24 +01:00
renderForkSettings() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layer .ui-standard-sidebar-view");
return;
}
BDV2.reactDom.render(this.forkComponent, root);
}
2017-04-30 03:11:22 +02:00
renderEmoteSettings() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layer .ui-standard-sidebar-view");
return;
}
BDV2.reactDom.render(this.emoteComponent, root);
}
renderCustomCssEditor() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layer .ui-standard-sidebar-view");
return;
}
BDV2.reactDom.render(this.customCssComponent, root);
}
renderPluginPane() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layer .ui-standard-sidebar-view");
return;
}
BDV2.reactDom.render(this.pluginsComponent, root);
}
renderThemePane() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layer .ui-standard-sidebar-view");
return;
}
BDV2.reactDom.render(this.themesComponent, root);
}
}
2018-01-09 04:24:00 +01:00
class V2C_Layer extends BDV2.reactComponent {
constructor(props) {
super(props);
}
componentDidMount() {
$(window).on(`keyup.${this.props.id}`, e => {
if (e.which === 27) {
BDV2.reactDom.unmountComponentAtNode(this.refs.root.parentNode);
}
});
2018-03-29 09:56:07 +02:00
$(`#${this.props.id}`).animate({opacity: 1}, {
step: function(now, fx) {
$(this).css("transform", `scale(${1.1 - 0.1*now}) translateZ(0px)`);
},
duration: 200,
done: () => {$(`#${this.props.id}`).css("opacity", "").css("transform", "");}
});
2018-01-09 04:24:00 +01:00
}
componentWillUnmount() {
$(window).off(`keyup.${this.props.id}`);
2018-03-29 09:56:07 +02:00
$(`#${this.props.id}`).animate({opacity: 0}, {
step: function(now, fx) {
$(this).css("transform", `scale(${1.1 - 0.1*now}) translateZ(0px)`);
},
duration: 200,
done: () => {$(`#${this.props.rootId}`).remove();}
});
$('[class*="layer-"]').animate({opacity: 1}, {
step: function(now, fx) {
$(this).css("transform", `scale(${0.07*now + 0.93}) translateZ(0px)`);
},
duration: 200,
done: () => {$('[class*="layer-"]').css("opacity", "").css("transform", "");}
});
}
componentWillMount() {
$('[class*="layer-"]').animate({opacity: 0}, {
step: function(now, fx) {
$(this).css("transform", `scale(${0.07*now + 0.93}) translateZ(0px)`);
},
duration: 200
});
2018-01-09 04:24:00 +01:00
}
render() {
return BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "layer bd-layer layer-kosS71", id: this.props.id, ref: "root", style: {opacity: 0, transform: "scale(1.1) translateZ(0px)"} },
2018-01-09 04:24:00 +01:00
this.props.children
);
}
}
class V2C_SidebarView extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
let { sidebar, content, tools } = this.props.children;
return BDV2.react.createElement(
"div",
{ className: "ui-standard-sidebar-view" },
BDV2.react.createElement(
"div",
{ className: "sidebar-region" },
2018-03-29 09:56:07 +02:00
BDV2.react.createElement(V2Components.Scroller, { key: "sidebarScroller", ref: "sidebarScroller", sidebar: true, fade: sidebar.fade || true, dark: sidebar.dark || true, children: sidebar.component })
2018-01-09 04:24:00 +01:00
),
BDV2.react.createElement("div", {className: "content-region"},
BDV2.react.createElement("div", {className: "content-transition-wrap"},
BDV2.react.createElement("div", {className: "scrollerWrap-2uBjct content-region-scroller-wrap scrollerThemed-19vinI themeGhost-10fio9 scrollerTrack-3hhmU0"},
BDV2.react.createElement("div", {className: "scroller-fzNley content-region-scroller scroller", ref: "contentScroller"},
2018-01-09 04:24:00 +01:00
BDV2.react.createElement("div", {className: "content-column default"}, content.component),
tools.component
)
)
)
)
);
}
}
class V2_PublicServers {
constructor() {}
get component() {
return BDV2.react.createElement(V2Components.Layer, { rootId: "pubslayerroot", id: "pubslayer", children: BDV2.react.createElement(V2C_PublicServers, { rootId: "pubslayerroot" }) });
}
get root() {
let _root = document.getElementById("pubslayerroot");
if (!_root) {
if (!this.injectRoot()) return null;
return this.root;
}
return _root;
}
injectRoot() {
if (!$(".layers, .layers-20RVFW").length) return false;
$(".layers, .layers-20RVFW").append($("<div/>", {
2018-01-09 04:24:00 +01:00
id: 'pubslayerroot'
}));
return true;
}
render() {
let root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layers");
return;
}
BDV2.reactDom.render(this.component, root);
}
get button() {
let btn = $("<div/>", {
class: 'guild',
id: 'bd-pub-li',
css: {
'height': '20px',
'display': settingsCookie['bda-gs-1'] ? "" : "none"
}
}).append($("<div/>", {
class: 'guild-inner',
css: {
'height': '20px',
'border-radius': '4px'
}
}).append($("<a/>", {
}).append($("<div/>", {
text: 'public',
id: 'bd-pub-button',
css: {
'line-height': '20px',
'font-size': '12px'
},
click: () => { this.render(); }
}))));
return btn;
}
initialize() {
let guilds = $(".guilds>:first-child");
guilds.after(this.button);
}
}
class V2C_ServerCard extends BDV2.reactComponent {
constructor(props) {
super(props);
2018-03-29 09:56:07 +02:00
if (!this.props.server.iconUrl) this.props.server.iconUrl = this.props.fallback;
2018-01-09 04:24:00 +01:00
this.state = {
imageError: false,
joined: this.props.guildList.includes(this.props.server.identifier)
};
}
render() {
let { server } = this.props;
return BDV2.react.createElement(
2018-03-29 09:56:07 +02:00
"div", // cardPrimary-ZVL9Jr
{ className: `card-3DrRmC cardPrimary-ZVL9Jr marginBottom8-1mABJ4 bd-server-card${server.pinned ? ' bd-server-card-pinned' : ''}` },
// BDV2.react.createElement(
// "div",
// { className: "flex-lFgbSz flex-3B1Tl4 horizontal-2BEEBe horizontal-2VE-Fw flex-3B1Tl4 directionRow-yNbSvJ justifyStart-2yIZo0 alignStretch-1hwxMa noWrap-v6g9vO" },
BDV2.react.createElement("img", { ref: "img", className: "bd-server-image", src: server.iconUrl, onError: this.handleError.bind(this) }),
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "flexChild-1KGW5q bd-server-content" },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "flex-lFgbSz flex-3B1Tl4 horizontal-2BEEBe horizontal-2VE-Fw flex-3B1Tl4 directionRow-yNbSvJ noWrap-v6g9vO bd-server-header" },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
2018-03-29 09:56:07 +02:00
"h5",
{ className: "h5-3KssQU defaultColor-v22dK1 margin-reset bd-server-name" },
server.name
2018-01-09 04:24:00 +01:00
),
BDV2.react.createElement(
2018-03-29 09:56:07 +02:00
"h5",
{ className: "h5-3KssQU defaultColor-v22dK1 margin-reset bd-server-member-count" },
server.members,
" Members"
2018-01-09 04:24:00 +01:00
)
),
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "flex-lFgbSz flex-3B1Tl4 horizontal-2BEEBe horizontal-2VE-Fw flex-3B1Tl4 directionRow-yNbSvJ noWrap-v6g9vO" },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "scrollerWrap-2uBjct scrollerThemed-19vinI themeGhostHairline-2H8SiW scrollerFade-28dRsO bd-server-description-container"},
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "scroller-fzNley scroller bd-server-description" },
2018-01-09 04:24:00 +01:00
server.description
)
)
),
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "flex-lFgbSz flex-3B1Tl4 horizontal-2BEEBe horizontal-2VE-Fw flex-3B1Tl4 directionRow-yNbSvJ noWrap-v6g9vO bd-server-footer" },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
2018-03-29 09:56:07 +02:00
{ className: "flexChild-1KGW5q bd-server-tags", style: { flex: "1 1 auto" } },
2018-01-09 04:24:00 +01:00
server.categories.join(', ')
),
this.state.joined && BDV2.react.createElement(
"button",
2018-03-29 09:56:07 +02:00
{ type: "button", className: "button-2t3of8 lookFilled-luDKDo colorBrand-3PmwCE sizeMin-1Wh1KC grow-25YQ8u colorGreen-22At8E", style: { minHeight: "12px", marginTop: "4px", backgroundColor: "#3ac15c" } },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
{ className: "ui-button-contents" },
"Joined"
)
),
server.error && BDV2.react.createElement(
"button",
2018-03-29 09:56:07 +02:00
{ type: "button", className: "button-2t3of8 lookFilled-luDKDo colorBrand-3PmwCE sizeMin-1Wh1KC grow-25YQ8u disabled-uc2Cqc", style: { minHeight: "12px", marginTop: "4px", backgroundColor: "#c13a3a" } },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
{ className: "ui-button-contents" },
"Error"
)
),
2018-03-29 09:56:07 +02:00
!server.error && !this.state.joined && BDV2.react.createElement(
2018-01-09 04:24:00 +01:00
"button",
2018-03-29 09:56:07 +02:00
{ type: "button", className: "button-2t3of8 lookFilled-luDKDo colorBrand-3PmwCE sizeMin-1Wh1KC grow-25YQ8u", style: { minHeight: "12px", marginTop: "4px" }, onClick: () => {this.join();} },
2018-01-09 04:24:00 +01:00
BDV2.react.createElement(
"div",
{ className: "ui-button-contents" },
"Join"
)
)
)
)
2018-03-29 09:56:07 +02:00
// )
2018-01-09 04:24:00 +01:00
);
}
handleError() {
2018-03-29 09:56:07 +02:00
this.props.server.iconUrl = this.props.fallback;
2018-01-09 04:24:00 +01:00
this.setState({imageError: true});
}
join() {
2018-03-29 09:56:07 +02:00
this.props.join(this);
//this.setState({joined: true});
2018-01-09 04:24:00 +01:00
}
}
class V2C_PublicServers extends BDV2.reactComponent {
constructor(props) {
super(props);
this.setInitialState();
this.close = this.close.bind(this);
this.changeCategory = this.changeCategory.bind(this);
this.search = this.search.bind(this);
this.searchKeyDown = this.searchKeyDown.bind(this);
this.checkConnection = this.checkConnection.bind(this);
this.join = this.join.bind(this);
2018-03-29 09:56:07 +02:00
this.connect = this.connect.bind(this);
2018-01-09 04:24:00 +01:00
this.GuildStore = BDV2.WebpackModules.findByUniqueProperties(["getGuilds"]);
this.AvatarDefaults = BDV2.WebpackModules.findByUniqueProperties(["getUserAvatarURL", "DEFAULT_AVATARS"]);
this.InviteActions = BDV2.WebpackModules.findByUniqueProperties(['acceptInvite']);
2018-03-29 09:56:07 +02:00
this.SortedGuildStore = BDV2.WebpackModules.findByUniqueProperties(['getSortedGuilds']);
2018-01-09 04:24:00 +01:00
}
componentDidMount() {
this.checkConnection();
}
setInitialState() {
this.state = {
'selectedCategory': -1,
'title': 'Loading...',
'loading': true,
'servers': [],
'next': null,
'connection': {
'state': 0,
'user': null
}
};
}
close() {
BDV2.reactDom.unmountComponentAtNode(document.getElementById(this.props.rootId));
}
search(query, clear) {
let self = this;
$.ajax({
method: 'GET',
2018-03-29 09:56:07 +02:00
url: `${self.endPoint}${query}${query ? "&schema=new" : "?schema=new"}`,
2018-01-09 04:24:00 +01:00
success: data => {
let servers = data.results.reduce((arr, server) => {
server.joined = false;
arr.push(server);
// arr.push(<V2Components.ServerCard server={server} join={self.join}/>);
return arr;
}, []);
if (!clear) {
servers = self.state.servers.concat(servers);
} else {
//servers.unshift(self.bdServer);
}
2018-03-29 09:56:07 +02:00
let hasNext = true;
2018-01-09 04:24:00 +01:00
let end = data.size + data.from;
2018-03-29 09:56:07 +02:00
data.next = `?from=${end}`;
if (self.state.term) data.next += `&term=${self.state.term}`;
if (self.state.selectedCategory) data.next += `&category=${self.categoryButtons[self.state.selectedCategory]}`;
2018-01-09 04:24:00 +01:00
if (end >= data.total) {
end = data.total;
data.next = null;
}
let title = `Showing 1-${end} of ${data.total} results in ${self.categoryButtons[self.state.selectedCategory]}`;
if (self.state.term) title += ` for ${self.state.term}`;
self.setState({
'loading': false,
'title': title,
'servers': servers,
'next': data.next
});
if (clear) {
2018-02-28 08:25:06 +01:00
//console.log(self);
self.refs.sbv.refs.contentScroller.scrollTop = 0;
2018-01-09 04:24:00 +01:00
}
},
error: (jqXHR) => {
self.setState({
'loading': false,
'title': 'Failed to load servers. Check console for details'
});
}
});
}
2018-03-29 09:56:07 +02:00
join(serverCard) {
if (serverCard.props.pinned) return this.InviteActions.acceptInvite(serverCard.props.invite_code);
$.ajax({
method: 'GET',
url: `${this.joinEndPoint}/${serverCard.props.server.identifier}`,
headers: {
Accept: "application/json;",
"Content-Type": "application/json;" ,
"x-discord-id": this.state.connection.user.id,
"x-discord-token": this.state.connection.user.accessToken
},
crossDomain: true,
xhrFields: {
withCredentials: true
},
success: data => {
serverCard.setState({joined: true});
}
});
}
connect() {
let self = this;
let options = self.windowOptions;
options.x = Math.round(window.screenX + window.innerWidth / 2 - options.width / 2);
options.y = Math.round(window.screenY + window.innerHeight / 2 - options.height / 2);
self.joinWindow = new (window.require('electron').remote.BrowserWindow)(options);
let sub = window.location.hostname.split('.')[0];
let url = self.connectEndPoint + (sub === 'canary' || sub === 'ptb' ? `/${sub}` : '');
self.joinWindow.webContents.on('did-navigate', (event, url) => {
if (url != "https://discordservers.com/") return;
self.joinWindow.close();
self.checkConnection();
});
self.joinWindow.loadURL(url);
}
get windowOptions() {
return {
width: 500,
height: 550,
backgroundColor: '#282b30',
show: true,
resizable: false,
maximizable: false,
minimizable: false,
alwaysOnTop: true,
frame: false,
center: false
};
}
2018-01-09 04:24:00 +01:00
get bdServer() {
let server = {
"name": "BetterDiscord",
"online": "7500+",
"members": "20000+",
"categories": ["community", "programming", "support"],
"description": "Official BetterDiscord server for support etc",
"identifier": "86004744966914048",
2018-03-29 09:56:07 +02:00
"iconUrl": "https://cdn.discordapp.com/icons/86004744966914048/c8d49dc02248e1f55caeb897c3e1a26e.png",
2018-01-09 04:24:00 +01:00
"nativejoin": true,
"invite_code": "0Tmfo5ZbORCRqbAd",
"pinned": true
};
2018-03-29 09:56:07 +02:00
let guildList = this.SortedGuildStore.guildPositions;
2018-01-09 04:24:00 +01:00
let defaultList = this.AvatarDefaults.DEFAULT_AVATARS;
return BDV2.react.createElement(V2Components.ServerCard, { server: server, pinned: true, join: this.join, guildList: guildList, fallback: defaultList[Math.floor(Math.random() * 5)] });
}
get endPoint() {
return 'https://search.discordservers.com';
}
get joinEndPoint() {
return 'https://join.discordservers.com';
}
get connectEndPoint() {
return 'https://join.discordservers.com/connect';
}
checkConnection() {
let self = this;
try {
$.ajax({
method: 'GET',
2018-03-29 09:56:07 +02:00
url: `${self.joinEndPoint}/session`,
headers: {
Accept: "application/json;",
"Content-Type": "application/json;"
},
crossDomain: true,
xhrFields: {
withCredentials: true
},
2018-01-09 04:24:00 +01:00
success: data => {
self.setState({
'selectedCategory': 0,
'connection': {
'state': 2,
'user': data
}
});
self.search("", true);
2018-03-29 09:56:07 +02:00
2018-01-09 04:24:00 +01:00
},
error: jqXHR => {
if (jqXHR.status === 403 || jqXHR.status === 404) {
//Not connected
self.setState({
'title': 'Not connected to discordservers.com!',
'loading': true,
'selectedCategory': -1,
'connection': {
'state': 1,
'user': null
}
});
return;
}
}
});
}
catch(error) {
self.setState({
'title': 'Not connected to discordservers.com!',
'loading': true,
'selectedCategory': -1,
'connection': {
'state': 1,
'user': null
}
});
}
}
render() {
return BDV2.react.createElement(V2Components.SidebarView, { ref: "sbv", children: this.component });
}
get component() {
return {
'sidebar': {
'component': this.sidebar
},
'content': {
'component': this.content
},
'tools': {
'component': BDV2.react.createElement(V2Components.Tools, { key: "pt", ref: "tools", onClick: this.close })
}
};
}
get sidebar() {
return BDV2.react.createElement(
"div",
{ className: "sidebar", key: "ps" },
BDV2.react.createElement(
"div",
{ className: "ui-tab-bar SIDE" },
BDV2.react.createElement(
"div",
{ className: "ui-tab-bar-header", style: { fontSize: "16px" } },
"Public Servers"
),
BDV2.react.createElement(V2Components.TabBar.Separator, null),
this.searchInput,
BDV2.react.createElement(V2Components.TabBar.Separator, null),
BDV2.react.createElement(V2Components.TabBar.Header, { text: "Categories" }),
this.categoryButtons.map((value, index) => {
return BDV2.react.createElement(V2Components.TabBar.Item, { id: index, onClick: this.changeCategory, key: index, text: value, selected: this.state.selectedCategory === index });
}),
BDV2.react.createElement(V2Components.TabBar.Separator, null),
2018-03-29 09:56:07 +02:00
this.footer,
this.connection
2018-01-09 04:24:00 +01:00
)
);
}
get searchInput() {
return BDV2.react.createElement(
"div",
{ className: "ui-form-item" },
BDV2.react.createElement(
"div",
{ className: "ui-text-input flex-vertical", style: { width: "172px", marginLeft: "10px" } },
BDV2.react.createElement("input", { ref: "searchinput", onKeyDown: this.searchKeyDown, onChange: () => {}, type: "text", className: "input default", placeholder: "Search...", maxLength: "50" })
)
);
}
searchKeyDown(e) {
let self = this;
if (self.state.loading || e.which !== 13) return;
self.setState({
'loading': true,
'title': 'Loading...',
'term': e.target.value
});
let query = `?term=${e.target.value}`;
if (self.state.selectedCategory !== 0) {
query += `&category=${self.categoryButtons[self.state.selectedCategory]}`;
}
self.search(query, true);
}
get categoryButtons() {
return ["All", "FPS Games", "MMO Games", "Strategy Games", "Sports Games", "Puzzle Games", "Retro Games", "Party Games", "Tabletop Games", "Sandbox Games", "Simulation Games", "Community", "Language", "Programming", "Other"];
}
changeCategory(id) {
let self = this;
if (self.state.loading) return;
self.refs.searchinput.value = "";
self.setState({
'loading': true,
'selectedCategory': id,
'title': 'Loading...',
'term': null
});
if (id === 0) {
self.search("", true);
return;
}
self.search(`?category=${self.categoryButtons[id]}`, true);
}
get content() {
let self = this;
2018-03-29 09:56:07 +02:00
let guildList = this.SortedGuildStore.guildPositions;
2018-01-09 04:24:00 +01:00
let defaultList = this.AvatarDefaults.DEFAULT_AVATARS;
if (self.state.connection.state === 1) return self.notConnected;
return [BDV2.react.createElement(
"div",
{ ref: "content", key: "pc", className: "content-column default" },
BDV2.react.createElement(V2Components.SettingsTitle, { text: self.state.title }),
self.bdServer,
self.state.servers.map((server, index) => {
2018-03-29 09:56:07 +02:00
return BDV2.react.createElement(V2Components.ServerCard, { key: server.identifier, server: server, join: self.join, guildList: guildList, fallback: defaultList[Math.floor(Math.random() * 5)] });
2018-01-09 04:24:00 +01:00
}),
self.state.next && BDV2.react.createElement(
"button",
{ type: "button", onClick: () => {
2018-03-29 09:56:07 +02:00
if (self.state.loading) return;self.setState({ 'loading': true }); self.search(self.state.next, false);
2018-01-09 04:24:00 +01:00
}, className: "ui-button filled brand small grow", style: { width: "100%", marginTop: "10px", marginBottom: "10px" } },
BDV2.react.createElement(
"div",
{ className: "ui-button-contents" },
self.state.loading ? 'Loading' : 'Load More'
)
),
self.state.servers.length > 0 && BDV2.react.createElement(V2Components.SettingsTitle, { text: self.state.title })
)];
}
2018-03-29 09:56:07 +02:00
get notConnected() {
let self = this;
//return BDV2.react.createElement(V2Components.SettingsTitle, { text: self.state.title });
return [BDV2.react.createElement(
"div",
{ key: "ncc", ref: "content", className: "content-column default" },
BDV2.react.createElement(
"h2",
{ className: "ui-form-title h2 margin-reset margin-bottom-20" },
"Not connected to discordservers.com!",
BDV2.react.createElement(
"button",
{ onClick: self.connect, type: "button", className: "ui-button filled brand small grow", style: { display: "inline-block", minHeight: "18px", marginLeft: "10px", lineHeight: "14px" } },
BDV2.react.createElement(
"div",
{ className: "ui-button-contents" },
"Connect"
)
)
), self.bdServer
)];
}
2018-01-09 04:24:00 +01:00
get footer() {
return BDV2.react.createElement(
"div",
{ className: "ui-tab-bar-header" },
BDV2.react.createElement(
"a",
{ href: "https://discordservers.com", target: "_blank" },
"Discordservers.com"
)
);
}
2018-03-29 09:56:07 +02:00
get connection() {
let self = this;
let { connection } = self.state;
if (connection.state !== 2) return BDV2.react.createElement("span", null);
return BDV2.react.createElement(
"span",
null,
BDV2.react.createElement(V2Components.TabBar.Separator, null),
BDV2.react.createElement(
"span",
{ style: { color: "#b9bbbe", fontSize: "10px", marginLeft: "10px" } },
"Connected as: ",
`${connection.user.username}#${connection.user.discriminator}`
),
BDV2.react.createElement(
"div",
{ style: { padding: "5px 10px 0 10px" } },
BDV2.react.createElement(
"button",
{ style: { width: "100%", minHeight: "20px" }, type: "button", className: "ui-button filled brand small grow" },
BDV2.react.createElement(
"div",
{ className: "ui-button-contents", onClick: self.connect },
"Reconnect"
)
)
)
);
}
2018-01-09 04:24:00 +01:00
}