/* 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 */ /* 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); })(); /* global DiscordNative:false */ 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}); }; var bdSettings = {}; var bdSettingsStorage = {}; var releaseChannel = DiscordNative.globals.releaseChannel; bdSettingsStorage.initialize = function() { let fs = require("fs"); let data = {stable: {}, canary: {}, ptb: {}}; if (fs.existsSync(bdConfig.dataPath + "/bdsettings.json")) { try { data = JSON.parse(fs.readFileSync(bdConfig.dataPath + "/bdsettings.json")); // Convery to new style. To be removed a month from 10/14/2018 if (data.hasOwnProperty("settings")) data = {[releaseChannel]: data}; } catch (err) { data = {stable: {}, canary: {}, ptb: {}}; } } if (data) bdSettings = data; else bdSettings = {stable: {}, canary: {}, ptb: {}}; }; bdSettingsStorage.get = function(key) { if (bdSettings[releaseChannel][key]) return bdSettings[releaseChannel][key]; return null; }; bdSettingsStorage.set = function(key, data) { let fs = require("fs"); bdSettings[releaseChannel][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, quickEmoteMenu, voiceMode, pluginModule, themeModule, dMode, publicServersModule; var jsVersion = 1.792; var supportedVersion = "0.2.81"; var bbdVersion = "0.1.1"; 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"}, "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"}, "Normalize Classes": {id: "fork-ps-4", info: "Adds stable classes to elements to help themes. (e.g. adds .da-channels to .channels-Ie2l6A)", 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-ps-4": true, "fork-es-2": false, "fork-es-3": true }; var settingsCookie = {}; var bdpluginErrors, bdthemeErrors; // define for backwards compatibility var bdConfig = null; function Core(config) { window.bdConfig = config; } var classNormalizer; 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.log("Initializing Settings"); this.initSettings(); classNormalizer = new ClassNormalizer(); emoteModule = new EmoteModule(); quickEmoteMenu = new QuickEmoteMenu(); Utils.log("Initializing EmoteModule"); window.emotePromise = emoteModule.init().then(() => { emoteModule.initialized = true; Utils.log("Initializing QuickEmoteMenu"); quickEmoteMenu.init(); }); publicServersModule = new V2_PublicServers(); voiceMode = new VoiceMode(); dMode = new devMode(); //Incase were too fast function gwDefer() { //console.log(new Date().getTime() + " Defer"); if (document.querySelectorAll(`.${BDV2.guildClasses.guilds} .${BDV2.guildClasses.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); 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, 100); }); }; Core.prototype.injectExternals = function() { Utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"); }; Core.prototype.initSettings = function () { bdSettingsStorage.initialize(); 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 () { 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 */ var BdApi = { get React() { return BDV2.react; }, get ReactDOM() { return BDV2.reactDom; } }; //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 || BDV2.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 bda-link-website", href: website, target: "_blank"}, "Website"), website && source && " | ", source && BDV2.react.createElement("a", {className: "bda-link bda-link-source", 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} 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); Utils.onRemoved(root, () => { BDV2.reactDom.unmountComponentAtNode(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; const root = $("
", { "class": "content-region", "id": "bd-settingspane-container" }); $(".layer-3QrUeG .ui-standard-sidebar-view, .layer-3QrUeG .ui-standard-sidebar-view").append(root); Utils.onRemoved(root[0], () => { BDV2.reactDom.unmountComponentAtNode(root[0]); }); 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 (_c["bda-gs-6"]) { mainCore.inject24Hour(); } if (_c["bda-gs-7"]) { mainCore.injectColoredText(); } else { mainCore.removeColoredText(); } if (_c["fork-ps-4"]) classNormalizer.start(); else classNormalizer.stop(); 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) { $(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) { $(this).css("transform", `scale(${1.1 - 0.1 * now}) translateZ(0px)`); }, duration: 200, done: () => {$(`#${this.props.rootId}`).remove();} }); $("[class*=\"layer-\"]").removeClass("publicServersOpen").animate({opacity: 1}, { step: function(now) { $(this).css("transform", `scale(${0.07 * now + 0.93}) translateZ(0px)`); }, duration: 200, done: () => {$("[class*=\"layer-\"]").css("opacity", "").css("transform", "");} }); } componentWillMount() { $("[class*=\"layer-\"]").addClass("publicServersOpen").animate({opacity: 0}, { step: function(now) { $(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": BDV2.guildClasses.guild, "id": "bd-pub-li", "css": { height: "20px", display: settingsCookie["bda-gs-1"] ? "" : "none" } }).append($("
", { "class": BDV2.guildClasses.guildInner, "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 = $(`.${BDV2.guildClasses.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(); } 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 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: () => { 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: () => { 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}` : "") + "?betterDiscord"; self.joinWindow.webContents.on("did-navigate", (event, url) => { if (url != "https://join.discordservers.com/session") 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/292e7f6bfff2b71dfd13e508a859aedd.webp", 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) => { 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" ) ) ) ); } }