/* BetterDiscordApp Core JavaScript * Version: 1.78 * Author: Jiiks | http://jiiks.net * Date: 27/08/2015 - 16:36 * Last Update: 01/05/2016 * https://github.com/Jiiks/BetterDiscordApp */ /* global Proxy, bdplugins, bdthemes, betterDiscordIPC, bdVersion, version, BDV2, webpackJsonp */ /* eslint-disable no-console */ /*Localstorage fix*/ (function() { let __fs = window.require("fs"); 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/'; let localStorageFile = "localStorage.json"; let __data = {}; if(__fs.existsSync(`${__dataPath}${localStorageFile}`)) { try { __data = JSON.parse(__fs.readFileSync(`${__dataPath}${localStorageFile}`)); }catch(err) { console.log(err); } } else if(__fs.existsSync(localStorageFile)) { try { __data = JSON.parse(__fs.readFileSync(localStorageFile)); }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() { __fs.writeFileSync(`${__dataPath}${localStorageFile}`, JSON.stringify(this), null, 4); }; var __proxy = new Proxy(__ls, { set: function(target, name, val) { __ls[name] = val; __ls.save(); }, get: function(target, name) { return __ls[name] || null; } }); window.localStorage = __proxy; })(); (() => { let v2Loader = document.createElement('div'); v2Loader.className = "bd-loaderv2"; v2Loader.title = "BetterDiscord is loading..."; document.body.appendChild(v2Loader); })(); 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); }); var bdSettings = {}; var bdSettingsStorage = {}; bdSettingsStorage.initialize = function() { let fs = require("fs"); let data = {}; if (fs.existsSync(bdConfig.dataPath + "/bdsettings.json")) { try { data = JSON.parse(fs.readFileSync(bdConfig.dataPath + "/bdsettings.json")); } catch (err) { data = {}; } } if (data) bdSettings = data; else bdSettings = {}; } bdSettingsStorage.get = function(key) { if (bdSettings[key]) return bdSettings[key]; else return null; } bdSettingsStorage.set = function(key, data) { let fs = require("fs"); bdSettings[key] = data; try { fs.writeFileSync(bdConfig.dataPath + "/bdsettings.json", JSON.stringify(bdSettings, null, 4)); return true; } catch(err) { utils.err(err); return false; } } var settingsPanel, emoteModule, utils, quickEmoteMenu, voiceMode, pluginModule, themeModule, dMode, publicServersModule; var jsVersion = 1.792; var supportedVersion = "0.2.81"; var bbdVersion = "0.0.7"; var mainObserver; var twitchEmoteUrlStart = "https://static-cdn.jtvnw.net/emoticons/v1/"; var twitchEmoteUrlEnd = "/1.0"; var ffzEmoteUrlStart = "https://cdn.frankerfacez.com/emoticon/"; var ffzEmoteUrlEnd = "/1"; var bttvEmoteUrlStart = "https://cdn.betterttv.net/emote/"; var bttvEmoteUrlEnd = "/1x"; var mainCore; var settings = { "Save logs locally": { "id": "bda-gs-0", "info": "Saves chat logs locally", "implemented": false, "hidden": false, "cat": "core"}, "Public Servers": { "id": "bda-gs-1", "info": "Display public servers button", "implemented": true, "hidden": false, "cat": "core"}, "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"}, "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"}, "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"}, "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"}, "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"}, "Download Emotes": { "id": "fork-es-3", "info": "Download emotes when the cache is expired", "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"}, }; var defaultCookie = { "version": jsVersion, "bda-gs-0": false, "bda-gs-1": true, "bda-gs-2": false, "bda-gs-3": false, "bda-gs-4": false, "bda-gs-5": true, "bda-gs-6": false, "bda-gs-7": false, "bda-gs-8": false, "bda-es-0": true, "bda-es-1": true, "bda-es-2": true, "bda-es-3": false, "bda-es-4": false, "bda-es-5": true, "bda-es-6": true, "bda-es-7": true, "bda-gs-b": false, "bda-es-8": true, "bda-jd": true, "bda-dc-0": false, "bda-css-0": false, "bda-css-1": false, "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, "fork-es-3": true }; var settingsCookie = {}; var bdpluginErrors, bdthemeErrors; // define for backwards compatibility 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; } var emoteModulePromise; Core.prototype.init = async function() { var self = this; bdConfig.deferLoaded = false; 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 + ").

Please download the latest version from BetterDiscord.net"); return; } utils = new Utils(); await utils.getHash(); utils.log("Initializing Settings"); this.initSettings(); emoteModule = new EmoteModule(); utils.log("Initializing EmoteModule"); emoteModule.init().then(() => {emoteModule.initialized = true;}); publicServersModule = new V2_PublicServers(); quickEmoteMenu = new QuickEmoteMenu(); voiceMode = new VoiceMode(); dMode = new devMode(); //Incase were too fast function gwDefer() { //console.log(new Date().getTime() + " Defer"); if (document.querySelectorAll('.guilds .guild').length > 0) { //console.log(new Date().getTime() + " Defer Loaded"); bdConfig.deferLoaded = true; self.injectExternals(); utils.log("Updating Settings"); settingsPanel = new V2_SettingsPanel(); settingsPanel.updateSettings(); // Add check for backwards compatibility if (!bdpluginErrors) bdpluginErrors = []; if (!bdthemeErrors) bdthemeErrors = []; utils.log("Loading Plugins"); pluginModule = new PluginModule(); pluginModule.loadPlugins(); utils.log("Loading Themes"); themeModule = new ThemeModule(); themeModule.loadThemes(); $("#customcss").detach().appendTo(document.head); utils.log("Initializing QuickEmoteMenu"); quickEmoteMenu.init(); window.addEventListener("beforeunload", function(){ if(settingsCookie["bda-dc-0"]){ document.querySelector('.btn.btn-disconnect').click(); } }); publicServersModule.initialize(); emoteModule.autoCapitalize(); /*Display new features in BetterDiscord*/ if (settingsCookie["version"] < jsVersion) { //var cl = self.constructChangelog(); settingsCookie["version"] = jsVersion; self.saveSettings(); } utils.log("Removing Loading Icon"); document.getElementsByClassName("bd-loaderv2")[0].remove(); utils.log("Initializing Main Observer"); self.initObserver(); // Show loading errors if (settingsCookie["fork-ps-1"]) { utils.log("Collecting Startup Errors"); self.showStartupErrors(); } } else { setTimeout(gwDefer, 100); } } $(document).ready(function () { setTimeout(gwDefer, 1000); }); }; Core.prototype.injectExternals = function() { utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js") }; Core.prototype.initSettings = function () { // $.removeCookie('the_cookie', { path: '/' }); bdSettingsStorage.initialize(); if ($.cookie("better-discord")) { settingsCookie = JSON.parse($.cookie("better-discord")); this.saveSettings(); $.removeCookie("better-discord", { path: '/' }); return; } if (!bdSettingsStorage.get("settings")) { settingsCookie = defaultCookie; this.saveSettings(); } else { this.loadSettings(); $('`); if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${bdthemes[theme].name} v${bdthemes[theme].version} has been applied.`); }; ThemeModule.prototype.disableTheme = function (theme) { themeCookie[theme] = false; this.saveThemeData(); $(`#${utils.escapeID(bdthemes[theme].name)}`).remove(); if (settingsCookie["fork-ps-2"]) mainCore.showToast(`${bdthemes[theme].name} v${bdthemes[theme].version} has been removed.`); }; ThemeModule.prototype.toggleTheme = function (theme) { if (themeCookie[theme]) this.disableTheme(theme); else this.enableTheme(theme); }; ThemeModule.prototype.loadThemeData = function () { if ($.cookie("bd-themes")) { themeCookie = JSON.parse($.cookie("bd-themes")); this.saveThemeData(); $.removeCookie("bd-themes", { path: '/' }); return; } let saved = bdSettingsStorage.get("themes"); if (saved) { themeCookie = saved; } }; ThemeModule.prototype.saveThemeData = function () { bdSettingsStorage.set("themes", themeCookie); }; /* 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) { $("head").append($(''); } $("#customcss").html(this.editor.session.getValue()).detach().appendTo(document.head); } saveCss() { window.bdStorage.set("bdcustomcss", btoa(this.editor.session.getValue())); } } class V2C_CssEditor extends BDV2.reactComponent { constructor(props) { super(props); let self = this; self.props.lines = 0; self.setInitialState(); self.attach = self.attach.bind(self); self.detachedEditor = BDV2.react.createElement(V2C_CssEditorDetached, { attach: self.attach }); 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(); } 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; } 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; } 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" }), BDV2.react.createElement("div", {className: "editor-wrapper"}, BDV2.react.createElement("div", {id: "bd-customcss-editor", className: "editor", ref: "editor"}, self.css) ), 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(''); } $("#customcss").html(this.editor.session.getValue()).detach().appendTo(document.head); } saveCss() { window.bdStorage.set("bdcustomcss", btoa(this.editor.session.getValue())); } 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; $("
", { 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"; self.settingsPanel = ""; } setInitialState() { this.state = { 'checked': pluginCookie[this.props.plugin.getName()], 'settings': false }; } componentDidUpdate() { if (this.state.settings) { if (typeof this.settingsPanel === "object") { this.refs.settingspanel.appendChild(this.settingsPanel); } 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); }; 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); } } render() { let self = this; let { plugin } = this.props; let name = plugin.getName(); let author = plugin.getAuthor(); let description = plugin.getDescription(); let version = plugin.getVersion(); let website = bdplugins[name].website; let source = bdplugins[name].source; //let { settingsPanel } = this; if (this.state.settings) { try { self.settingsPanel = plugin.getSettingsPanel(); } catch (err) { utils.err("Unable to get settings panel for " + plugin.getName() + ".", err); } return BDV2.react.createElement("li", {className: "settings-open ui-switch-item"}, BDV2.react.createElement("div", {style: { float: "right", cursor: "pointer" }, onClick: () => { this.refs.settingspanel.innerHTML = ""; self.setState({'settings': false }); }}, BDV2.react.createElement(V2Components.XSvg, null) ), 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 } }) ); } return BDV2.react.createElement("li", {"data-name": name, "data-version": version, className: "settings-closed ui-switch-item"}, BDV2.react.createElement("div", {className: "bda-header"}, 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' }}, BDV2.react.createElement("input", { checked: this.state.checked, onChange: this.onChange, className: "ui-switch-checkbox", type: "checkbox" }), BDV2.react.createElement("div", { className: this.state.checked ? "ui-switch checked" : "ui-switch" }) ) ), BDV2.react.createElement("div", {className: "bda-description-wrap scroller-wrap fade"}, BDV2.react.createElement("div", {className: "bda-description scroller"}, description) ), (website || source || this.hasSettings) && BDV2.react.createElement("div", {className: "bda-footer"}, 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") ) ); } onChange() { this.setState({'checked': !this.state.checked}); pluginModule.togglePlugin(this.props.plugin.getName()); } showSettings() { if (!this.hasSettings) return; this.setState({'settings': true}); } } 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; let name = theme.name; let description = theme.description; let version = theme.version; let author = theme.author; let website = bdthemes[name].website; let source = bdthemes[name].source; return BDV2.react.createElement("li", {"data-name": name, "data-version": version, className: "settings-closed ui-switch-item"}, BDV2.react.createElement("div", {className: "bda-header"}, 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' }}, BDV2.react.createElement("input", { checked: this.state.checked, onChange: this.onChange, className: "ui-switch-checkbox", type: "checkbox" }), BDV2.react.createElement("div", { className: this.state.checked ? "ui-switch checked" : "ui-switch" }) ) ), BDV2.react.createElement("div", {className: "bda-description-wrap scroller-wrap fade"}, BDV2.react.createElement("div", {className: "bda-description scroller"}, description) ), (website || source) && BDV2.react.createElement("div", {className: "bda-footer"}, 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") ) ) ); } onChange() { this.setState({'checked': !this.state.checked}); themeModule.toggleTheme(this.props.theme.name); } } class V2Cs_TabBar { static get Item() { return V2C_TabBarItem; } static get Header() { return V2C_TabBarHeader; } static get Separator() { return V2C_TabBarSeparator; } } class V2Components { static get SettingsPanel() { return V2C_SettingsPanel; } static get Switch() { return V2C_Switch; } static get Scroller() { return V2C_Scroller; } 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; } } class V2_SettingsPanel_Sidebar { constructor(onClick) { this.onClick = onClick; } 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() { return BDV2.react.createElement( "span", null, BDV2.react.createElement(V2Components.SideBar, { onClick: this.onClick, headerText: "Bandaged BD", items: this.items }), BDV2.react.createElement( "div", { 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" ) ), BDV2.react.createElement( "div", { 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" ) ) ); } get root() { let _root = $("#bd-settings-sidebar"); if (!_root.length) { if (!this.injectRoot()) return null; return this.root; } return _root[0]; } injectRoot() { let changeLog = $("[class*='side-'] > [class*='item-']:not([class*=Danger])").last(); if (!changeLog.length) return false; $("", { 'id': 'bd-settings-sidebar' }).insertBefore(changeLog.prev()); return true; } render() { let root = this.root; if (!root) { console.log("FAILED TO LOCATE ROOT: [class*='side-'] > [class*='item-']:not([class*=Danger])"); return; } BDV2.reactDom.render(this.component, root); } } 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-3QrUeG .ui-standard-sidebar-view, .layer-3QrUeG .ui-standard-sidebar-view").length) return false; $(".layer-3QrUeG .ui-standard-sidebar-view, .layer-3QrUeG .ui-standard-sidebar-view").append($("
", { class: 'content-region', id: 'bd-settingspane-container' })); return true; } get coreSettings() { return this.getSettings("core"); } get forkSettings() { return this.getSettings("fork"); } 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; case 'fork': self.renderForkSettings(); break; case 'emotes': self.renderEmoteSettings(); break; case 'customcss': self.renderCustomCssEditor(); break; case 'plugins': self.renderPluginPane(); break; case 'themes': self.renderThemePane(); break; } } onClick() {} onChange(id, checked) { settingsCookie[id] = checked; this.updateSettings(); } updateSettings() { 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"); } 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); } } if (_c["fork-es-2"]) { $('.emote').each(() => { $(this).addClass("stop-animation"); }); } else { $('.emote').each(() => { $(this).removeClass("stop-animation"); }); } $(document).off('mouseover', '.emote'); //Pretty emote titles var emoteNamePopup = $("
"); $(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"); var modifier = emote.attr("data-modifier"); 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"); }); if (_c["bda-gs-8"]) { dMode.enable(_c["fork-dm-1"]); } else { dMode.disable(); } mainCore.saveSettings(); } renderSidebar() { let self = this; $("[class*='side-'] > [class*='item-']").off('click.v2settingspanel').on('click.v2settingspanel', () => { BDV2.reactDom.unmountComponentAtNode(self.root); $(self.root).hide(); $(".content-region").first().show(); }); self.sidebar.render(); } get coreComponent() { 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" })] }); } get forkComponent() { return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [ BDV2.react.createElement(V2Components.SettingsPanel, { key: "fspanel", title: "Zere's Fork Settings", onChange: this.onChange, settings: this.forkSettings, button: { title: "Clear Emote Cache", onClick: () => { emoteModule.clearEmoteData(); emoteModule.init(); quickEmoteMenu.init(); } }}), BDV2.react.createElement(V2Components.Tools, { key: "tools" }) ] } ); } get emoteComponent() { 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" })] }); } get customCssComponent() { 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" })] }); } 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 }); let pfBtn = BDV2.react.createElement("button", {key: "folder-button", className: 'bd-pfbtn', onClick: () => { betterDiscordIPC.send('asynchronous-message', { 'arg': 'opendir', 'path': 'plugindir' }); }}, "Open Plugin Folder"); let contentColumn = BDV2.react.createElement(V2Components.ContentColumn, { key: "pcolumn", title: "Plugins", children: [pfBtn, list] }); return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [contentColumn, BDV2.react.createElement(V2Components.Tools, { key: "tools" })] }); } 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 }); let tfBtn = BDV2.react.createElement("button", {key: "folder-button", className: 'bd-pfbtn', onClick: () => { betterDiscordIPC.send('asynchronous-message', { 'arg': 'opendir', 'path': 'themedir' }); }}, "Open Theme Folder"); let contentColumn = BDV2.react.createElement(V2Components.ContentColumn, { key: "tcolumn", title: "Themes", children: [tfBtn, list] }); return BDV2.react.createElement(V2Components.Scroller, { contentColumn: true, fade: true, dark: true, children: [contentColumn, BDV2.react.createElement(V2Components.Tools, { key: "tools" })] }); } 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); } 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); } 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); } } 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); } }); $(`#${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", "");} }); } componentWillUnmount() { $(window).off(`keyup.${this.props.id}`); $(`#${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 }); } render() { return BDV2.react.createElement( "div", { className: "layer bd-layer layer-3QrUeG", id: this.props.id, ref: "root", style: {opacity: 0, transform: "scale(1.1) translateZ(0px)"} }, 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" }, BDV2.react.createElement(V2Components.Scroller, { key: "sidebarScroller", ref: "sidebarScroller", sidebar: true, fade: sidebar.fade || true, dark: sidebar.dark || true, children: sidebar.component }) ), BDV2.react.createElement("div", {className: "content-region"}, BDV2.react.createElement("div", {className: "content-transition-wrap"}, BDV2.react.createElement("div", {className: "scrollerWrap-2lJEkd content-region-scroller-wrap scrollerThemed-2oenus themeGhost-28MSn0 scrollerTrack-1ZIpsv"}, BDV2.react.createElement("div", {className: "scroller-2FKFPG content-region-scroller scroller", ref: "contentScroller"}, 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-3iHuyZ").length) return false; $(".layers, .layers-3iHuyZ").append($("
", { 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 = $("
", { class: 'guild', id: 'bd-pub-li', css: { 'height': '20px', 'display': settingsCookie['bda-gs-1'] ? "" : "none" } }).append($("
", { class: 'guild-inner', css: { 'height': '20px', 'border-radius': '4px' } }).append($("", { }).append($("
", { 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); if (!this.props.server.iconUrl) this.props.server.iconUrl = this.props.fallback; this.state = { imageError: false, joined: this.props.guildList.includes(this.props.server.identifier) }; } render() { let { server } = this.props; return BDV2.react.createElement( "div", // cardPrimary-1Hv-to { className: `card-3Qj_Yx cardPrimary-1Hv-to marginBottom8-AtZOdT bd-server-card${server.pinned ? ' bd-server-card-pinned' : ''}` }, // BDV2.react.createElement( // "div", // { className: "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY flex-1O1GKY directionRow-3v3tfG justifyStart-2yIZo0 alignStretch-1hwxMa noWrap-3jynv6" }, BDV2.react.createElement("img", { ref: "img", className: "bd-server-image", src: server.iconUrl, onError: this.handleError.bind(this) }), BDV2.react.createElement( "div", { className: "flexChild-faoVW3 bd-server-content" }, BDV2.react.createElement( "div", { className: "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6 bd-server-header" }, BDV2.react.createElement( "h5", { className: "h5-18_1nd defaultColor-1_ajX0 margin-reset bd-server-name" }, server.name ), BDV2.react.createElement( "h5", { className: "h5-18_1nd defaultColor-1_ajX0 margin-reset bd-server-member-count" }, server.members, " Members" ) ), BDV2.react.createElement( "div", { className: "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6" }, BDV2.react.createElement( "div", { className: "scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d scrollerFade-1Ijw5y bd-server-description-container"}, BDV2.react.createElement( "div", { className: "scroller-2FKFPG scroller bd-server-description" }, server.description ) ) ), BDV2.react.createElement( "div", { className: "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6 bd-server-footer" }, BDV2.react.createElement( "div", { className: "flexChild-faoVW3 bd-server-tags", style: { flex: "1 1 auto" } }, server.categories.join(', ') ), this.state.joined && BDV2.react.createElement( "button", { type: "button", className: "button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN colorGreen-29iAKY", style: { minHeight: "12px", marginTop: "4px", backgroundColor: "#3ac15c" } }, BDV2.react.createElement( "div", { className: "ui-button-contents" }, "Joined" ) ), server.error && BDV2.react.createElement( "button", { type: "button", className: "button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN disabled-9aF2ug", style: { minHeight: "12px", marginTop: "4px", backgroundColor: "#c13a3a" } }, BDV2.react.createElement( "div", { className: "ui-button-contents" }, "Error" ) ), !server.error && !this.state.joined && BDV2.react.createElement( "button", { type: "button", className: "button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN", style: { minHeight: "12px", marginTop: "4px" }, onClick: () => {this.join();} }, BDV2.react.createElement( "div", { className: "ui-button-contents" }, "Join" ) ) ) ) // ) ); } handleError() { this.props.server.iconUrl = this.props.fallback; this.setState({imageError: true}); } join() { this.props.join(this); //this.setState({joined: true}); } } 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); this.connect = this.connect.bind(this); this.GuildStore = BDV2.WebpackModules.findByUniqueProperties(["getGuilds"]); this.AvatarDefaults = BDV2.WebpackModules.findByUniqueProperties(["getUserAvatarURL", "DEFAULT_AVATARS"]); this.InviteActions = BDV2.WebpackModules.findByUniqueProperties(['acceptInvite']); this.SortedGuildStore = BDV2.WebpackModules.findByUniqueProperties(['getSortedGuilds']); } componentDidMount() { this.checkConnection(); mainCore.alert("Not Working", "Hi there,

While the public servers module was fixed on our end, DiscordServers.com is having issue with their sessions API that we need for this to work. So unfortunately until they fix that, the public servers module won't work :(") } 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', url: `${self.endPoint}${query}${query ? "&schema=new" : "?schema=new"}`, success: data => { let servers = data.results.reduce((arr, server) => { server.joined = false; arr.push(server); // arr.push(); return arr; }, []); if (!clear) { servers = self.state.servers.concat(servers); } else { //servers.unshift(self.bdServer); } let hasNext = true; let end = data.size + data.from; 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]}`; 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) { //console.log(self); self.refs.sbv.refs.contentScroller.scrollTop = 0; } }, error: (jqXHR) => { self.setState({ 'loading': false, 'title': 'Failed to load servers. Check console for details' }); } }); } 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 }; } get bdServer() { let server = { "name": "BetterDiscord", "online": "7500+", "members": "20000+", "categories": ["community", "programming", "support"], "description": "Official BetterDiscord server for support etc", "identifier": "86004744966914048", "iconUrl": "https://cdn.discordapp.com/icons/86004744966914048/c8d49dc02248e1f55caeb897c3e1a26e.png", "nativejoin": true, "invite_code": "0Tmfo5ZbORCRqbAd", "pinned": true }; let guildList = this.SortedGuildStore.guildPositions; 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', url: `${self.joinEndPoint}/session`, headers: { Accept: "application/json;", "Content-Type": "application/json;" }, crossDomain: true, xhrFields: { withCredentials: true }, success: data => { self.setState({ 'selectedCategory': 0, 'connection': { 'state': 2, 'user': data } }); self.search("", true); }, 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), this.footer, this.connection ) ); } 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; let guildList = this.SortedGuildStore.guildPositions; 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) => { return BDV2.react.createElement(V2Components.ServerCard, { key: server.identifier, server: server, join: self.join, guildList: guildList, fallback: defaultList[Math.floor(Math.random() * 5)] }); }), self.state.next && BDV2.react.createElement( "button", { type: "button", onClick: () => { if (self.state.loading) return;self.setState({ 'loading': true }); self.search(self.state.next, false); }, 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 }) )]; } 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 )]; } get footer() { return BDV2.react.createElement( "div", { className: "ui-tab-bar-header" }, BDV2.react.createElement( "a", { href: "https://discordservers.com", target: "_blank" }, "Discordservers.com" ) ); } 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" ) ) ) ); } }