v1.62 Css fixes and new emote menu

This commit is contained in:
Jiiks 2016-04-09 09:04:34 +03:00
parent 4ad2fa5c38
commit 7cbfc6f19a
4 changed files with 254 additions and 220 deletions

File diff suppressed because one or more lines are too long

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
* https://github.com/Jiiks/BetterDiscordApp
*/
var settingsPanel, emoteModule, utils, quickEmoteMenu, opublicServers, voiceMode, pluginModule, themeModule, customCssEditor;
var jsVersion = 1.61;
var jsVersion = 1.62;
var supportedVersion = "0.2.5";
var mainObserver;
@ -26,7 +26,8 @@ var settings = {
"Minimal Mode": { "id": "bda-gs-2", "info": "Hide elements and reduce the size of elements.", "implemented": true, "hidden": false},
"Voice Mode": { "id": "bda-gs-4", "info": "Only show voice chat", "implemented": true, "hidden": false},
"Hide Channels": { "id": "bda-gs-3", "info": "Hide channels in minimal mode", "implemented": true, "hidden": false},
"Quick Emote Menu": { "id": "bda-es-0", "info": "Show quick emote menu for adding emotes", "implemented": true, "hidden": false},
"Emote Menu": { "id": "bda-es-0", "info": "Show Twitch/Favourite emotes in emote menu", "implemented": true, "hidden": false},
"Emoji Menu": { "id": "bda-es-9", "info": "Show/Hide Discord emoji menu", "implemented": true, "hidden": false},
"Show Emotes": { "id": "bda-es-7", "info": "Show any emotes", "implemented": true, "hidden": false},
"FrankerFaceZ Emotes": { "id": "bda-es-1", "info": "Show FrankerFaceZ Emotes", "implemented": true, "hidden": false},
"BetterTTV Emotes": { "id": "bda-es-2", "info": "Show BetterTTV Emotes", "implemented": true, "hidden": false},
@ -37,7 +38,7 @@ var settings = {
"Show emote modifiers": { "id": "bda-es-8", "info": "Enable/Disable emote mods", "implemented": true, "hidden": false},
"Voice Disconnect": { "id": "bda-dc-0", "info": "Disconnect from voice server when closing Discord", "implemented": true, "hidden": false},
"Custom css live update": { "id": "bda-css-0", "info": "", "implemented": true, "hidden": true },
"Custom css auto udpate": { "id": "bda-css-1", "info": "", "implemented": true, "hidden": true }
"Custom css auto udpate": { "id": "bda-css-1", "info": "", "implemented": true, "hidden": true },
};
var links = {
@ -66,11 +67,15 @@ var defaultCookie = {
"bda-es-8": true,
"bda-dc-0": false,
"bda-css-0": false,
"bda-css-1": false
"bda-css-1": false,
"bda-es-9": true
};
var bdchangelog = {
"changes": {
"emotemenu": {
"title": "v1.62 : Brand new emote menu that fits in Discord emoji menu!"
},
"cccss": {
"title": "v1.61 : New custom CSS editor",
"text": "The custom CSS editor now has options and can be detached!",
@ -103,6 +108,11 @@ var bdchangelog = {
}
},
"fixes": {
"modal": {
"title": "v1.62 : Fixed modals",
"text": "Fixed broken modal introduced by 0.0.287",
"imt": ""
},
"emotes": {
"title": "v1.59 : Native sub emote mods",
"text": "Emote mods now work with native sub emotes!",
@ -240,15 +250,22 @@ Core.prototype.saveSettings = function () {
Core.prototype.loadSettings = function () {
settingsCookie = JSON.parse($.cookie("better-discord"));
};
var botlist = ["119598467310944259"]; //Temp
Core.prototype.initObserver = function () {
mainObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if($(mutation.target).find(".emoji-picker").length) {
var fc = mutation.target.firstChild;
if(fc.classList.contains("popout")) {
quickEmoteMenu.obsCallback($(fc));
}
}
if (typeof pluginModule !== "undefined") pluginModule.rawObserver(mutation);
if (mutation.target.getAttribute('class') != null) {
//console.log(mutation.target)
if(mutation.target.classList.contains('title-wrap') || mutation.target.classList.contains('chat')){
quickEmoteMenu.obsCallback();
// quickEmoteMenu.obsCallback();
voiceMode.obsCallback();
if (typeof pluginModule !== "undefined") pluginModule.channelSwitch();
}
@ -271,10 +288,10 @@ Core.prototype.constructChangelog = function () {
var changeLog = '' +
'<div id="bd-wn-modal" class="modal" style="opacity:1;">' +
' <div class="modal-inner">' +
' <div id="bdcl" class="change-log"> ' +
' <div class="header">' +
' <div id="bdcl" class="markdown-modal change-log"> ' +
' <div class="markdown-modal-header">' +
' <strong>What\'s new in BetterDiscord JS' + jsVersion + '</strong>' +
' <button class="close" onclick=\'$("#bd-wn-modal").remove();\'></button>' +
' <button class="markdown-modal-close" onclick=\'$("#bd-wn-modal").remove();\'></button>' +
' </div><!--header-->' +
' <div class="scroller-wrap">' +
' <div class="scroller">';
@ -451,7 +468,6 @@ EmoteModule.prototype.getNodes = function (node) {
nodes.push(next);
}
return nodes;
};
@ -518,14 +534,11 @@ EmoteModule.prototype.injectEmote = function (node) {
var emoteClass = "";
var allowedClasses = ["emoteflip", "emotespin", "emotepulse", "emotespin2", "emotespin3", "emote1spin", "emote2spin", "emote3spin", "emotetr", "emotebl", "emotebr", "emoteshake", "emoteshake2", "emoteshake3", "emoteflap"];
if(word.indexOf(":") > -1) {
// userEmoteCss = true;
//sWord = word.split(":")[0];
var split = word.split(/:(?!.*:)/);
if (split[0] != "" && split[1] != "") {
userEmoteCss = true;
sWord = split[0];
if(settingsCookie["bda-es-8"]) {
// emoteClass = "emote" + word.split(":")[1];
emoteClass = "emote" + split[1];
if(allowedClasses.indexOf(emoteClass) < 0) {
emoteClass = "";
@ -599,7 +612,6 @@ EmoteModule.prototype.injectEmote = function (node) {
} else {
inject();
}
};
EmoteModule.prototype.autoCapitalize = function () {
@ -737,7 +749,6 @@ PublicServers.prototype.show = function () {
}
});
this.loadServers(dataset, false);
var self = this;
$(document).on("mouseup.bdps",function(e) {
@ -868,179 +879,154 @@ PublicServers.prototype.joinServer = function (code) {
* https://github.com/Jiiks/BetterDiscordApp
*/
var emoteBtn, emoteMenu;
var eiarr = [1, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14];
function QuickEmoteMenu() {
}
QuickEmoteMenu.prototype.init = function (reload) {
QuickEmoteMenu.prototype.init = function() {
emoteBtn = null;
$(".channel-textarea").first().removeClass("emotemenu-enabled");
if (!emoteMenu) {
this.initEmoteList();
$(document).on("mousedown", function(e) {
if(e.target.id != "rmenu") $("#rmenu").remove();
});
var fe = localStorage["bdfavemotes"];
if (fe != undefined) {
this.favoriteEmotes = JSON.parse(atob(fe));
}
var menuOpen;
var qmeHeader="";
qmeHeader += "<div id=\"bda-qem\">";
qmeHeader += " <button class=\"active\" id=\"bda-qem-twitch\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Twitch<\/button>";
qmeHeader += " <button id=\"bda-qem-favourite\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Favourite<\/button>";
qmeHeader += " <button id=\"bda-qem-emojis\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Emojis<\/buttond>";
qmeHeader += "<\/div>";
this.qmeHeader = qmeHeader;
emoteBtn = $("<div/>", {
id: "twitchcord-button-container",
style: "display:none"
}).append($("<button/>", {
id: "twitchcord-button",
onclick: "return false;"
}));
$(".content.flex-spacer.flex-horizontal .flex-spacer.flex-vertical form").append(emoteBtn);
emoteMenu.detach();
emoteBtn.append(emoteMenu);
$("#twitchcord-button").on("click", function () {
menuOpen = !menuOpen;
if (menuOpen) {
$("#bdemotemenustyle").html('.twitchcord-button-open { background-image:url(https://static-cdn.jtvnw.net/emoticons/v1/' + eiarr[Math.floor(Math.random() * eiarr.length)] + '/1.0) !important; }');
emoteMenu.addClass("emotemenu-open");
$(this).addClass("twitchcord-button-open");
} else {
emoteMenu.removeClass();
$(this).removeClass();
var teContainer="";
teContainer += "<div id=\"bda-qem-twitch-container\">";
teContainer += " <div class=\"scroller-wrap fade\">";
teContainer += " <div class=\"scroller\">";
teContainer += " <div class=\"emote-menu-inner\">";
for (var emote in emotesTwitch.emotes) {
if (emotesTwitch.emotes.hasOwnProperty(emote)) {
var id = emotesTwitch.emotes[emote].image_id;
teContainer += "<div class=\"emote-container\">";
teContainer += " <img class=\"emote-icon\" id=\""+emote+"\" alt=\"\" src=\"https://static-cdn.jtvnw.net/emoticons/v1/"+id+"/1.0\" title=\""+emote+"\">";
teContainer += " </img>";
teContainer += "</div>";
}
return false;
});
$(document).off("click.bdem").on("click.bdem", function () {
if (menuOpen) {
menuOpen = !menuOpen;
emoteMenu.removeClass();
$("#twitchcord-button").removeClass();
}
});
$("#emote-menu").on("click", function () {
$("#rmenu").hide();
return false;
});
if (settingsCookie["bda-es-0"]) {
$(".channel-textarea").first().addClass("emotemenu-enabled");
emoteBtn.show();
}
teContainer += " <\/div>";
teContainer += " <\/div>";
teContainer += " <\/div>";
teContainer += "<\/div>";
this.teContainer = teContainer;
var faContainer="";
faContainer += "<div id=\"bda-qem-favourite-container\">";
faContainer += " <div class=\"scroller-wrap fade\">";
faContainer += " <div class=\"scroller\">";
faContainer += " <div class=\"emote-menu-inner\">";
for (var emote in this.favoriteEmotes) {
var url = this.favoriteEmotes[emote];
faContainer += "<div class=\"emote-container\">";
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\""+url+"\" title=\""+emote+"\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>";
faContainer += " </img>";
faContainer += "</div>";
}
faContainer += " <\/div>";
faContainer += " <\/div>";
faContainer += " <\/div>";
faContainer += "<\/div>";
this.faContainer = faContainer;
};
QuickEmoteMenu.prototype.favContext = function(e, em) {
e.stopPropagation();
var menu = $('<div/>', { id: "rmenu", "data-emoteid": $(em).prop("title"), text: "Remove" });
menu.css({
top: e.pageY - $("#bda-qem-favourite-container").offset().top,
left: e.pageX - $("#bda-qem-favourite-container").offset().left
});
$(em).parent().append(menu);
menu.on("click", function(e) {
e.preventDefault();
e.stopPropagation();
$(this).remove();
console.log($(this).data("emoteid"));
delete quickEmoteMenu.favoriteEmotes[$(this).data("emoteid")];
quickEmoteMenu.updateFavorites();
return false;
});
return false;
};
QuickEmoteMenu.prototype.switchHandler = function(e) {
this.switchQem($(e).attr("id"));
};
QuickEmoteMenu.prototype.switchQem = function(id) {
var twitch = $("#bda-qem-twitch");
var fav = $("#bda-qem-favourite");
var emojis = $("#bda-qem-emojis");
twitch.removeClass("active");
fav.removeClass("active");
emojis.removeClass("active");
$(".emoji-picker").hide();
$("#bda-qem-favourite-container").hide();
$("#bda-qem-twitch-container").hide();
switch(id) {
case "bda-qem-twitch":
twitch.addClass("active");
$("#bda-qem-twitch-container").show();
break;
case "bda-qem-favourite":
fav.addClass("active");
$("#bda-qem-favourite-container").show();
break;
case "bda-qem-emojis":
emojis.addClass("active");
$(".emoji-picker").show();
break;
}
this.lastTab = id;
var emoteIcon = $(".emote-icon");
emoteIcon.off();
emoteIcon.on("click", function () {
var emote = $(this).attr("title");
var ta = $(".channel-textarea-inner textarea");
ta.val(ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote);
});
var fe = localStorage["bdfavemotes"];
if (fe != undefined) {
favoriteEmotes = JSON.parse(atob(fe));
this.updateFavorites();
}
};
var bdfw = {};
QuickEmoteMenu.prototype.obsCallback = function (e) {
QuickEmoteMenu.prototype.obsCallback = function () {
if (!emoteBtn) return;
if (!$(".content.flex-spacer.flex-horizontal .flex-spacer.flex-vertical form")) return;
var tcbtn = $("#twitchcord-button-container");
if (tcbtn.parent().prop("tagName") == undefined) {
quickEmoteMenu = new QuickEmoteMenu();
quickEmoteMenu.init(true);
if(!settingsCookie["bda-es-9"]) {
e.addClass("bda-qme-hidden");
} else {
e.removeClass("bda-qme-hidden");
}
};
var favoriteEmotes = {};
if(!settingsCookie["bda-es-0"]) return;
var self = this;
QuickEmoteMenu.prototype.initEmoteList = function () {
e.prepend(this.qmeHeader);
e.append(this.teContainer);
e.append(this.faContainer);
emoteMenu = $("<div/>", {
id: "emote-menu"
});
var emoteMenuHeader = $("<div/>", {
id: "emote-menu-header"
});
var emoteMenuBody = $("<div/>", {
id: "emote-menu-inner"
});
var emoteMenuBodyFav = $("<div/>", {
id: "emote-menu-inner-fav",
css: {
"display": "none"
}
});
var globalTab = $("<div/>", {
class: "emote-menu-tab emote-menu-tab-selected",
id: "emgb",
text: "Global",
click: function () {
$("#emfa").removeClass("emote-menu-tab-selected");
$("#emgb").addClass("emote-menu-tab-selected");
$("#emote-menu-inner-fav").hide();
$("#emote-menu-inner").show();
}
});
var favoriteTab = $("<div/>", {
class: "emote-menu-tab",
id: "emfa",
text: "Favorite",
click: function () {
$("#emgb").removeClass("emote-menu-tab-selected");
$("#emfa").addClass("emote-menu-tab-selected");
$("#emote-menu-inner").hide();
$("#emote-menu-inner-fav").show();
}
});
emoteMenuHeader.append(globalTab);
emoteMenuHeader.append(favoriteTab);
emoteMenu.append(emoteMenuHeader);
var swrapper = $("<div/>", {
class: "scroller-wrap"
});
var scroller = $("<div/>", {
class: "scroller"
});
swrapper.append(scroller);
scroller.append(emoteMenuBody);
scroller.append(emoteMenuBodyFav);
emoteMenu.append(swrapper);
for (var emote in emotesTwitch.emotes) {
if (emotesTwitch.emotes.hasOwnProperty(emote)) {
var id = emotesTwitch.emotes[emote].image_id;
emoteMenuBody.append($("<div/>", {
class: "emote-container"
}).append($("<img/>", {
class: "emote-icon",
id: emote,
alt: "",
src: "https://static-cdn.jtvnw.net/emoticons/v1/" + id + "/1.0",
title: emote
})));
}
}
if(this.lastTab == undefined) {
this.lastTab = "bda-qem-favourite";
}
this.switchQem(this.lastTab);
};
QuickEmoteMenu.prototype.favorite = function (name, url) {
if (!favoriteEmotes.hasOwnProperty(name)) {
favoriteEmotes[name] = url;
if (!this.favoriteEmotes.hasOwnProperty(name)) {
this.favoriteEmotes[name] = url;
}
this.updateFavorites();
@ -1048,55 +1034,27 @@ QuickEmoteMenu.prototype.favorite = function (name, url) {
QuickEmoteMenu.prototype.updateFavorites = function () {
if (!$("#rmenu").length) {
$("body").append('<div id="rmenu"><ul><a href="#">Remove</a></ul></div>');
$(document).on("click", function () {
$("#rmenu").hide();
});
var faContainer="";
faContainer += "<div id=\"bda-qem-favourite-container\">";
faContainer += " <div class=\"scroller-wrap fade\">";
faContainer += " <div class=\"scroller\">";
faContainer += " <div class=\"emote-menu-inner\">";
for (var emote in this.favoriteEmotes) {
var url = this.favoriteEmotes[emote];
faContainer += "<div class=\"emote-container\">";
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\""+url+"\" title=\""+emote+"\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>";
faContainer += " </img>";
faContainer += "</div>";
}
faContainer += " <\/div>";
faContainer += " <\/div>";
faContainer += " <\/div>";
faContainer += "<\/div>";
this.faContainer = faContainer;
$("#rmenu").on("click", function(e) { $(this).hide(); return false; });
$("#bda-qem-favourite-container").replaceWith(faContainer);
var self = this;
var emoteMenuBody = $("#emote-menu-inner-fav");
emoteMenuBody.empty();
for (var emote in favoriteEmotes) {
var url = favoriteEmotes[emote];
var econtainer = $("<div/>", {
class: "emote-container"
});
var icon = $("<img/>", {
class: "emote-icon",
alt: "",
src: url,
title: emote
}).appendTo(econtainer);
emoteMenuBody.append(econtainer);
icon.off("click").on("click", function (e) {
var emote = $(this).attr("title");
var ta = $(".channel-textarea-inner textarea");
ta.val(ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote);
});
icon.off("contextmenu").on("contextmenu", function (e) {
var title = $(this).attr("title");
var menu = $("#rmenu");
menu.find("a").off("click").on("click", function () {
delete favoriteEmotes[title];
self.updateFavorites();
});
menu.hide();
menu.css({
top: e.pageY,
left: e.pageX
});
menu.show();
return false;
});
}
window.localStorage["bdfavemotes"] = btoa(JSON.stringify(favoriteEmotes));
window.localStorage["bdfavemotes"] = btoa(JSON.stringify(this.favoriteEmotes));
};
@ -1539,7 +1497,6 @@ SettingsPanel.prototype.construct = function () {
}
}
defer();
};
/* BetterDiscordApp Utilities JavaScript
@ -1873,7 +1830,6 @@ BdWSocket.prototype.open = function (host) {
} catch (err) {
utils.log(err);
}
};
BdWSocket.prototype.onOpen = function () {

29
js/main.min.js vendored
View File

@ -1,11 +1,12 @@
var settingsPanel,emoteModule,utils,quickEmoteMenu,opublicServers,voiceMode,pluginModule,themeModule,customCssEditor;var jsVersion=1.61;var supportedVersion="0.2.5";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},"Public Servers":{"id":"bda-gs-1","info":"Display public servers button","implemented":true,"hidden":false},"Minimal Mode":{"id":"bda-gs-2","info":"Hide elements and reduce the size of elements.","implemented":true,"hidden":false},"Voice Mode":{"id":"bda-gs-4","info":"Only show voice chat","implemented":true,"hidden":false},"Hide Channels":{"id":"bda-gs-3","info":"Hide channels in minimal mode","implemented":true,"hidden":false},"Quick Emote Menu":{"id":"bda-es-0","info":"Show quick emote menu for adding emotes","implemented":true,"hidden":false},"Show Emotes":{"id":"bda-es-7","info":"Show any emotes","implemented":true,"hidden":false},"FrankerFaceZ Emotes":{"id":"bda-es-1","info":"Show FrankerFaceZ Emotes","implemented":true,"hidden":false},"BetterTTV Emotes":{"id":"bda-es-2","info":"Show BetterTTV Emotes","implemented":true,"hidden":false},"Emote Autocomplete":{"id":"bda-es-3","info":"Autocomplete emote commands","implemented":false,"hidden":false},"Emote Auto Capitalization":{"id":"bda-es-4","info":"Autocapitalize emote commands","implemented":true,"hidden":false},"Override Default Emotes":{"id":"bda-es-5","info":"Override default emotes","implemented":false,"hidden":false},"Show Names":{"id":"bda-es-6","info":"Show emote names on hover","implemented":true,"hidden":false},"Show emote modifiers":{"id":"bda-es-8","info":"Enable/Disable emote mods","implemented":true,"hidden":false},"Voice Disconnect":{"id":"bda-dc-0","info":"Disconnect from voice server when closing Discord","implemented":true,"hidden":false},"Custom css live update":{"id":"bda-css-0","info":"","implemented":true,"hidden":true},"Custom css auto udpate":{"id":"bda-css-1","info":"","implemented":true,"hidden":true}};var links={"Jiiks.net":{"text":"Jiiks.net","href":"http://jiiks.net","target":"_blank"},"twitter":{"text":"Twitter","href":"http://twitter.com/jiiksi","target":"_blank"},"github":{"text":"Github","href":"http://github.com/jiiks","target":"_blank"}};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-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-es-8":true,"bda-jd":true,"bda-es-8":true,"bda-dc-0":false,"bda-css-0":false,"bda-css-1":false};var bdchangelog={"changes":{"cccss":{"title":"v1.61 : New custom CSS editor","text":"The custom CSS editor now has options and can be detached!","img":""},"vdc":{"title":"v1.61 : Voice Disconnect","text":"Disconnect from voice server when closing Discord!","img":""},"pslist":{"title":"v1.60 : New public server list!","text":'New and shiny public server list powered by <a href="https://www.discordservers.com/" target="_blank">DiscordServers.com</a>!',"img":""},"api":{"title":"v1.59 : New plugin api callback","text":"Use the `observer(e)` callback instead of creating your own MutationObserver","img":""},"emotemods":{"title":"v1.59 : New emote mods!","text":"The following emote mods have been added: :shake2, :shake3, :flap","img":""},"minmode":{"title":"v1.59: Minimal mode","text":"Minimal mode embed fixed size has been removed","img":""}},"fixes":{"emotes":{"title":"v1.59 : Native sub emote mods","text":"Emote mods now work with native sub emotes!","img":""},"emotes2":{"title":"v1.59 : Emote mods and custom emotes","text":"Emote mods will no longer interfere with custom emotes using :","img":""}}};var settingsCookie={};function Core(){}
var settingsPanel,emoteModule,utils,quickEmoteMenu,opublicServers,voiceMode,pluginModule,themeModule,customCssEditor;var jsVersion=1.62;var supportedVersion="0.2.5";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},"Public Servers":{"id":"bda-gs-1","info":"Display public servers button","implemented":true,"hidden":false},"Minimal Mode":{"id":"bda-gs-2","info":"Hide elements and reduce the size of elements.","implemented":true,"hidden":false},"Voice Mode":{"id":"bda-gs-4","info":"Only show voice chat","implemented":true,"hidden":false},"Hide Channels":{"id":"bda-gs-3","info":"Hide channels in minimal mode","implemented":true,"hidden":false},"Emote Menu":{"id":"bda-es-0","info":"Show Twitch/Favourite emotes in emote menu","implemented":true,"hidden":false},"Emoji Menu":{"id":"bda-es-9","info":"Show/Hide Discord emoji menu","implemented":true,"hidden":false},"Show Emotes":{"id":"bda-es-7","info":"Show any emotes","implemented":true,"hidden":false},"FrankerFaceZ Emotes":{"id":"bda-es-1","info":"Show FrankerFaceZ Emotes","implemented":true,"hidden":false},"BetterTTV Emotes":{"id":"bda-es-2","info":"Show BetterTTV Emotes","implemented":true,"hidden":false},"Emote Autocomplete":{"id":"bda-es-3","info":"Autocomplete emote commands","implemented":false,"hidden":false},"Emote Auto Capitalization":{"id":"bda-es-4","info":"Autocapitalize emote commands","implemented":true,"hidden":false},"Override Default Emotes":{"id":"bda-es-5","info":"Override default emotes","implemented":false,"hidden":false},"Show Names":{"id":"bda-es-6","info":"Show emote names on hover","implemented":true,"hidden":false},"Show emote modifiers":{"id":"bda-es-8","info":"Enable/Disable emote mods","implemented":true,"hidden":false},"Voice Disconnect":{"id":"bda-dc-0","info":"Disconnect from voice server when closing Discord","implemented":true,"hidden":false},"Custom css live update":{"id":"bda-css-0","info":"","implemented":true,"hidden":true},"Custom css auto udpate":{"id":"bda-css-1","info":"","implemented":true,"hidden":true},};var links={"Jiiks.net":{"text":"Jiiks.net","href":"http://jiiks.net","target":"_blank"},"twitter":{"text":"Twitter","href":"http://twitter.com/jiiksi","target":"_blank"},"github":{"text":"Github","href":"http://github.com/jiiks","target":"_blank"}};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-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-es-8":true,"bda-jd":true,"bda-es-8":true,"bda-dc-0":false,"bda-css-0":false,"bda-css-1":false,"bda-es-9":true};var bdchangelog={"changes":{"emotemenu":{"title":"v1.62 : Brand new emote menu that fits in Discord emoji menu!"},"cccss":{"title":"v1.61 : New custom CSS editor","text":"The custom CSS editor now has options and can be detached!","img":""},"vdc":{"title":"v1.61 : Voice Disconnect","text":"Disconnect from voice server when closing Discord!","img":""},"pslist":{"title":"v1.60 : New public server list!","text":'New and shiny public server list powered by <a href="https://www.discordservers.com/" target="_blank">DiscordServers.com</a>!',"img":""},"api":{"title":"v1.59 : New plugin api callback","text":"Use the `observer(e)` callback instead of creating your own MutationObserver","img":""},"emotemods":{"title":"v1.59 : New emote mods!","text":"The following emote mods have been added: :shake2, :shake3, :flap","img":""},"minmode":{"title":"v1.59: Minimal mode","text":"Minimal mode embed fixed size has been removed","img":""}},"fixes":{"modal":{"title":"v1.62 : Fixed modals","text":"Fixed broken modal introduced by 0.0.287","imt":""},"emotes":{"title":"v1.59 : Native sub emote mods","text":"Emote mods now work with native sub emotes!","img":""},"emotes2":{"title":"v1.59 : Emote mods and custom emotes","text":"Emote mods will no longer interfere with custom emotes using :","img":""}}};var settingsCookie={};function Core(){}
Core.prototype.init=function(){var self=this;if(version<supportedVersion){this.alert("Not Supported","BetterDiscord v"+version+"(your version)"+" is not supported by the latest js("+jsVersion+").<br><br> Please download the latest version from <a href='https://betterdiscord.net' target='_blank'>BetterDiscord.net</a>");return;}
utils=new Utils();var sock=new BdWSocket();sock.start();utils.getHash();emoteModule=new EmoteModule();quickEmoteMenu=new QuickEmoteMenu();voiceMode=new VoiceMode();emoteModule.init();this.initSettings();this.initObserver();function gwDefer(){console.log(new Date().getTime()+" Defer");if($(".guilds-wrapper .guilds").children().length>0){console.log(new Date().getTime()+" Defer Loaded");var guilds=$(".guilds>li:first-child");var showChannelsButton=$("<button/>",{class:"btn",id:"bd-show-channels",text:"R",css:{"cursor":"pointer"},click:function(){settingsCookie["bda-gs-3"]=false;$("body").removeClass("bd-minimal-chan");self.saveSettings();}});$(".guilds-wrapper").prepend(showChannelsButton);opublicServers=new PublicServers();customCssEditor=new CustomCssEditor();pluginModule=new PluginModule();pluginModule.loadPlugins();if(typeof(themesupport2)!=="undefined"){themeModule=new ThemeModule();themeModule.loadThemes();}
settingsPanel=new SettingsPanel();settingsPanel.init();quickEmoteMenu.init(false);$("#tc-settings-button").on("click",function(){settingsPanel.show();});window.addEventListener("beforeunload",function(){if(settingsCookie["bda-dc-0"]){$('.btn.btn-disconnect').click();}});opublicServers.init();emoteModule.autoCapitalize();if(settingsCookie["version"]<jsVersion){var cl=self.constructChangelog();$("body").append(cl);settingsCookie["version"]=jsVersion;self.saveSettings();}
$("head").append("<style>.CodeMirror{ min-width:100%; }</style>");$("head").append('<style id="bdemotemenustyle"></style>');}else{setTimeout(gwDefer,100);}}
$(document).ready(function(){setTimeout(gwDefer,1000);});};Core.prototype.initSettings=function(){if($.cookie("better-discord")==undefined){settingsCookie=defaultCookie;this.saveSettings();}else{this.loadSettings();for(var setting in defaultCookie){if(settingsCookie[setting]==undefined){settingsCookie[setting]=defaultCookie[setting];this.saveSettings();}}}};Core.prototype.saveSettings=function(){$.cookie("better-discord",JSON.stringify(settingsCookie),{expires:365,path:'/'});};Core.prototype.loadSettings=function(){settingsCookie=JSON.parse($.cookie("better-discord"));};var botlist=["119598467310944259"];Core.prototype.initObserver=function(){mainObserver=new MutationObserver(function(mutations){mutations.forEach(function(mutation){if(typeof pluginModule!=="undefined")pluginModule.rawObserver(mutation);if(mutation.target.getAttribute('class')!=null){if(mutation.target.classList.contains('title-wrap')||mutation.target.classList.contains('chat')){quickEmoteMenu.obsCallback();voiceMode.obsCallback();if(typeof pluginModule!=="undefined")pluginModule.channelSwitch();}
$(document).ready(function(){setTimeout(gwDefer,1000);});};Core.prototype.initSettings=function(){if($.cookie("better-discord")==undefined){settingsCookie=defaultCookie;this.saveSettings();}else{this.loadSettings();for(var setting in defaultCookie){if(settingsCookie[setting]==undefined){settingsCookie[setting]=defaultCookie[setting];this.saveSettings();}}}};Core.prototype.saveSettings=function(){$.cookie("better-discord",JSON.stringify(settingsCookie),{expires:365,path:'/'});};Core.prototype.loadSettings=function(){settingsCookie=JSON.parse($.cookie("better-discord"));};var botlist=["119598467310944259"];Core.prototype.initObserver=function(){mainObserver=new MutationObserver(function(mutations){mutations.forEach(function(mutation){if($(mutation.target).find(".emoji-picker").length){var fc=mutation.target.firstChild;if(fc.classList.contains("popout")){quickEmoteMenu.obsCallback($(fc));}}
if(typeof pluginModule!=="undefined")pluginModule.rawObserver(mutation);if(mutation.target.getAttribute('class')!=null){if(mutation.target.classList.contains('title-wrap')||mutation.target.classList.contains('chat')){voiceMode.obsCallback();if(typeof pluginModule!=="undefined")pluginModule.channelSwitch();}
if(mutation.target.getAttribute('class').indexOf('scroller messages')!=-1){if(typeof pluginModule!=="undefined")pluginModule.newMessage();}}
emoteModule.obsCallback(mutation);});});mainObserver.observe(document,{childList:true,subtree:true});};Core.prototype.constructChangelog=function(){var changeLog=''+'<div id="bd-wn-modal" class="modal" style="opacity:1;">'+' <div class="modal-inner">'+' <div id="bdcl" class="change-log"> '+' <div class="header">'+' <strong>What\'s new in BetterDiscord JS'+jsVersion+'</strong>'+' <button class="close" onclick=\'$("#bd-wn-modal").remove();\'></button>'+' </div><!--header-->'+' <div class="scroller-wrap">'+' <div class="scroller">';if(bdchangelog.changes!=null){changeLog+=''+'<h1 class="changelog-added">'+' <span>New Stuff</span>'+'</h1>'+'<ul>';for(var change in bdchangelog.changes){change=bdchangelog.changes[change];changeLog+=''+'<li>'+' <strong>'+change.title+'</strong>'+' <div>'+change.text+'</div>'+'</li>';}
emoteModule.obsCallback(mutation);});});mainObserver.observe(document,{childList:true,subtree:true});};Core.prototype.constructChangelog=function(){var changeLog=''+'<div id="bd-wn-modal" class="modal" style="opacity:1;">'+' <div class="modal-inner">'+' <div id="bdcl" class="markdown-modal change-log"> '+' <div class="markdown-modal-header">'+' <strong>What\'s new in BetterDiscord JS'+jsVersion+'</strong>'+' <button class="markdown-modal-close" onclick=\'$("#bd-wn-modal").remove();\'></button>'+' </div><!--header-->'+' <div class="scroller-wrap">'+' <div class="scroller">';if(bdchangelog.changes!=null){changeLog+=''+'<h1 class="changelog-added">'+' <span>New Stuff</span>'+'</h1>'+'<ul>';for(var change in bdchangelog.changes){change=bdchangelog.changes[change];changeLog+=''+'<li>'+' <strong>'+change.title+'</strong>'+' <div>'+change.text+'</div>'+'</li>';}
changeLog+='</ul>';}
if(bdchangelog.fixes!=null){changeLog+=''+'<h1 class="changelog-fixed">'+' <span>Fixed</span>'+'</h1>'+'<ul>';for(var fix in bdchangelog.fixes){fix=bdchangelog.fixes[fix];changeLog+=''+'<li>'+' <strong>'+fix.title+'</strong>'+' <div>'+fix.text+'</div>'+'</li>';}
changeLog+='</ul>';}
@ -29,15 +30,17 @@ if(typeof emotesBTTV2!=='undefined'&&settingsCookie["bda-es-2"]){if(emotesBTTV2.
if(edited){setTimeout(inject,250);}else{inject();}};EmoteModule.prototype.autoCapitalize=function(){var self=this;$('body').delegate($(".channel-textarea-inner textarea"),'keyup change paste',function(){if(!settingsCookie["bda-es-4"])return;var text=$(".channel-textarea-inner textarea").val();if(text==undefined)return;var lastWord=text.split(" ").pop();if(lastWord.length>3){if(lastWord=="danSgame")return;var ret=self.capitalize(lastWord.toLowerCase());if(ret!==null&&ret!==undefined){$(".channel-textarea-inner textarea").val(text.replace(lastWord,ret));}}});};EmoteModule.prototype.capitalize=function(value){var res=emotesTwitch.emotes;for(var p in res){if(res.hasOwnProperty(p)&&value==(p+'').toLowerCase()){return p;}}};function PublicServers(){}
PublicServers.prototype.getPanel=function(){return this.container;};PublicServers.prototype.init=function(){var self=this;var guilds=$(".guilds>li:first-child");guilds.after($("<li></li>",{id:"bd-pub-li",css:{"height":"20px","display":settingsCookie["bda-gs-1"]==true?"":"none"}}).append($("<div/>",{class:"guild-inner",css:{"height":"20px","border-radius":"4px"}}).append($("<a/>").append($("<div/>",{css:{"line-height":"20px","font-size":"12px"},text:"public",id:"bd-pub-button"})))));$("#bd-pub-button").on("click",function(){self.show();});var panelBase="";panelBase+="<div id=\"pubs-container\">";panelBase+=" <div id=\"pubs-spinner\">";panelBase+=" <span class=\"spinner\" type=\"wandering-cubes\"><span class=\"spinner-inner spinner-wandering-cubes\"><span class=\"spinner-item\"><\/span><span class=\"spinner-item\"><\/span><\/span><\/span>";panelBase+=" <\/div>";panelBase+=" <div id=\"pubs-header\">";panelBase+=" <h2 id=\"pubs-header-title\">Public Servers<\/h2>";panelBase+=" <button id=\"sbtn\">Search<\/button>";panelBase+=" <input id=\"sterm\" type=\"text\" placeholder=\"Search term...\"\/>";panelBase+=" <\/div>";panelBase+=" <div class=\"scroller-wrap\">";panelBase+=" <div class=\"scroller\">";panelBase+=" <div id=\"slist\" class=\"servers-listing\">";panelBase+=" ";panelBase+=" <\/div>";panelBase+=" <\/div>";panelBase+=" <\/div>";panelBase+=" <div id=\"pubs-footer\">";panelBase+=" <div>Server list provided by <a href=\"https:\/\/www.discordservers.com\/\" target=\"_blank\">DiscordServers.com<\/a><\/div>";panelBase+=" <\/div>";panelBase+="<\/div>";this.container=panelBase;if($("#bd-pub-li").length<1){setTimeout(function(){self.init();},250);}};PublicServers.prototype.show=function(){var self=this;$("body").append(this.getPanel());var dataset={"sort":[{"online":"desc"}],"from":0,"size":20,"query":{"filtered":{"query":{"match_all":{}}}}};$("#sbtn").on("click",function(){self.search();});$("#sterm").on("keyup",function(e){if(e.keyCode==13){self.search();}});this.loadServers(dataset,false);var self=this;$(document).on("mouseup.bdps",function(e){if(!$("#bd-pub-button").is(e.target)&&!$("#pubs-container").is(e.target)&&$("#pubs-container").has(e.target).length===0){self.hide();}});};PublicServers.prototype.hide=function(){$("#pubs-container").remove();$(document).off("mouseup.bdps");};PublicServers.prototype.loadServers=function(dataset,search){var self=this;$("#sbtn").prop("disabled",true);$("#sterm").prop("disabled",true);$("#slist").empty();$("#pubs-spinner").show();$.ajax({type:"POST",dataType:"json",url:"https://search-discordservers-izrtub5nprzrl76ugyy6hdooe4.us-west-1.es.amazonaws.com/app/_search",crossDomain:true,data:JSON.stringify(dataset),success:function(data){var hits=data.hits.hits;if(search){$("#pubs-header-title").text("Public Servers - Search Results: "+hits.length);}else{$("#pubs-header-title").text("Public Servers");}
hits.forEach(function(hit){var source=hit._source;var icode=source.invite_code;var html='<div class="server-row">';html+='<div class="server-icon" style="background-image:url('+source.icon+')"></div>';html+='<div class="server-info server-name">';html+='<span>'+source.name+' by '+source.owner.name+'</span>';html+='</div>';html+='<div class="server-info server-members">';html+='<span>'+source.online+'/'+source.members+' Members</span>';html+='</div>';html+='<div class="server-info server-region">';html+='<span>'+source.region+'</span>';html+='</div>';html+='<div class="server-info">';html+='<button data-server-invite-code='+icode+'>Join</button>';html+='</div>';html+='</div>';$("#slist").append(html);$("button[data-server-invite-code="+icode+"]").on("click",function(){self.joinServer(icode);});});},done:function(){$("#pubs-spinner").hide();$("#sbtn").prop("disabled",false);$("#sterm").prop("disabled",false);},always:function(){$("#pubs-spinner").hide();$("#sbtn").prop("disabled",false);$("#sterm").prop("disabled",false);},error:function(){$("#pubs-spinner").hide();$("#sbtn").prop("disabled",false);$("#sterm").prop("disabled",false);},complete:function(){$("#pubs-spinner").hide();$("#sbtn").prop("disabled",false);$("#sterm").prop("disabled",false);}});};PublicServers.prototype.search=function(){var dataset={"sort":[{"online":"desc"}],"from":0,"size":20,"query":{"filtered":{"query":{"match_all":{}}}}};var filter={"filter":{"and":[{"query":{"match_phrase_prefix":{"name":$("#sterm").val()}}}]}};if($("#sterm").val()){$.extend(dataset,filter);}
this.loadServers(dataset,true);};PublicServers.prototype.joinServer=function(code){$(".guilds-add").click();$(".action.join .btn").click();$(".create-guild-container input").val(code);$(".form.join-server .btn-primary").click();};var emoteBtn,emoteMenu;var eiarr=[1,3,4,6,7,8,10,11,12,13,14];function QuickEmoteMenu(){}
QuickEmoteMenu.prototype.init=function(reload){emoteBtn=null;$(".channel-textarea").first().removeClass("emotemenu-enabled");if(!emoteMenu){this.initEmoteList();}
var menuOpen;emoteBtn=$("<div/>",{id:"twitchcord-button-container",style:"display:none"}).append($("<button/>",{id:"twitchcord-button",onclick:"return false;"}));$(".content.flex-spacer.flex-horizontal .flex-spacer.flex-vertical form").append(emoteBtn);emoteMenu.detach();emoteBtn.append(emoteMenu);$("#twitchcord-button").on("click",function(){menuOpen=!menuOpen;if(menuOpen){$("#bdemotemenustyle").html('.twitchcord-button-open { background-image:url(https://static-cdn.jtvnw.net/emoticons/v1/'+eiarr[Math.floor(Math.random()*eiarr.length)]+'/1.0) !important; }');emoteMenu.addClass("emotemenu-open");$(this).addClass("twitchcord-button-open");}else{emoteMenu.removeClass();$(this).removeClass();}
return false;});$(document).off("click.bdem").on("click.bdem",function(){if(menuOpen){menuOpen=!menuOpen;emoteMenu.removeClass();$("#twitchcord-button").removeClass();}});$("#emote-menu").on("click",function(){$("#rmenu").hide();return false;});if(settingsCookie["bda-es-0"]){$(".channel-textarea").first().addClass("emotemenu-enabled");emoteBtn.show();}
var emoteIcon=$(".emote-icon");emoteIcon.off();emoteIcon.on("click",function(){var emote=$(this).attr("title");var ta=$(".channel-textarea-inner textarea");ta.val(ta.val().slice(-1)==" "?ta.val()+emote:ta.val()+" "+emote);});var fe=localStorage["bdfavemotes"];if(fe!=undefined){favoriteEmotes=JSON.parse(atob(fe));this.updateFavorites();}};var bdfw={};QuickEmoteMenu.prototype.obsCallback=function(){if(!emoteBtn)return;if(!$(".content.flex-spacer.flex-horizontal .flex-spacer.flex-vertical form"))return;var tcbtn=$("#twitchcord-button-container");if(tcbtn.parent().prop("tagName")==undefined){quickEmoteMenu=new QuickEmoteMenu();quickEmoteMenu.init(true);}};var favoriteEmotes={};QuickEmoteMenu.prototype.initEmoteList=function(){emoteMenu=$("<div/>",{id:"emote-menu"});var emoteMenuHeader=$("<div/>",{id:"emote-menu-header"});var emoteMenuBody=$("<div/>",{id:"emote-menu-inner"});var emoteMenuBodyFav=$("<div/>",{id:"emote-menu-inner-fav",css:{"display":"none"}});var globalTab=$("<div/>",{class:"emote-menu-tab emote-menu-tab-selected",id:"emgb",text:"Global",click:function(){$("#emfa").removeClass("emote-menu-tab-selected");$("#emgb").addClass("emote-menu-tab-selected");$("#emote-menu-inner-fav").hide();$("#emote-menu-inner").show();}});var favoriteTab=$("<div/>",{class:"emote-menu-tab",id:"emfa",text:"Favorite",click:function(){$("#emgb").removeClass("emote-menu-tab-selected");$("#emfa").addClass("emote-menu-tab-selected");$("#emote-menu-inner").hide();$("#emote-menu-inner-fav").show();}});emoteMenuHeader.append(globalTab);emoteMenuHeader.append(favoriteTab);emoteMenu.append(emoteMenuHeader);var swrapper=$("<div/>",{class:"scroller-wrap"});var scroller=$("<div/>",{class:"scroller"});swrapper.append(scroller);scroller.append(emoteMenuBody);scroller.append(emoteMenuBodyFav);emoteMenu.append(swrapper);for(var emote in emotesTwitch.emotes){if(emotesTwitch.emotes.hasOwnProperty(emote)){var id=emotesTwitch.emotes[emote].image_id;emoteMenuBody.append($("<div/>",{class:"emote-container"}).append($("<img/>",{class:"emote-icon",id:emote,alt:"",src:"https://static-cdn.jtvnw.net/emoticons/v1/"+id+"/1.0",title:emote})));}}};QuickEmoteMenu.prototype.favorite=function(name,url){if(!favoriteEmotes.hasOwnProperty(name)){favoriteEmotes[name]=url;}
this.updateFavorites();};QuickEmoteMenu.prototype.updateFavorites=function(){if(!$("#rmenu").length){$("body").append('<div id="rmenu"><ul><a href="#">Remove</a></ul></div>');$(document).on("click",function(){$("#rmenu").hide();});}
$("#rmenu").on("click",function(e){$(this).hide();return false;});var self=this;var emoteMenuBody=$("#emote-menu-inner-fav");emoteMenuBody.empty();for(var emote in favoriteEmotes){var url=favoriteEmotes[emote];var econtainer=$("<div/>",{class:"emote-container"});var icon=$("<img/>",{class:"emote-icon",alt:"",src:url,title:emote}).appendTo(econtainer);emoteMenuBody.append(econtainer);icon.off("click").on("click",function(e){var emote=$(this).attr("title");var ta=$(".channel-textarea-inner textarea");ta.val(ta.val().slice(-1)==" "?ta.val()+emote:ta.val()+" "+emote);});icon.off("contextmenu").on("contextmenu",function(e){var title=$(this).attr("title");var menu=$("#rmenu");menu.find("a").off("click").on("click",function(){delete favoriteEmotes[title];self.updateFavorites();});menu.hide();menu.css({top:e.pageY,left:e.pageX});menu.show();return false;});}
window.localStorage["bdfavemotes"]=btoa(JSON.stringify(favoriteEmotes));};function CustomCssEditor(){}
CustomCssEditor.prototype.init=function(){var self=this;self.hideBackdrop=false;self.editor=CodeMirror.fromTextArea(document.getElementById("bd-custom-css-ta"),{lineNumbers:true,mode:'css',indentUnit:4,theme:'neat'});self.editor.on("change",function(cm){var css=cm.getValue();self.applyCustomCss(css,false,false);});var attachEditor="";attachEditor+="<div id=\"bd-customcss-attach-controls\">";attachEditor+=" <ul class=\"checkbox-group\">";attachEditor+=" <li>";attachEditor+=" <div class=\"checkbox\" onclick=\"settingsPanel.updateSetting(this);\">";attachEditor+=" <div class=\"checkbox-inner\"><input id=\"bda-css-0\" type=\"checkbox\" "+(settingsCookie["bda-css-0"]?"checked":"")+"><span><\/span><\/div>";attachEditor+=" <span title=\"Update client css while typing\">Live Update<\/span>";attachEditor+=" <\/div>";attachEditor+=" <\/li>";attachEditor+=" <li>";attachEditor+=" <div class=\"checkbox\" onclick=\"settingsPanel.updateSetting(this);\">";attachEditor+=" <div class=\"checkbox-inner\"><input id=\"bda-css-1\" type=\"checkbox\" "+(settingsCookie["bda-css-1"]?"checked":"")+"><span><\/span><\/div>";attachEditor+=" <span title=\"Autosave css to localstorage when typing\">Autosave<\/span>";attachEditor+=" <\/div>";attachEditor+=" <\/li>";attachEditor+=" <li>";attachEditor+=" <div class=\"checkbox\" onclick=\"settingsPanel.updateSetting(this);\">";attachEditor+=" <div class=\"checkbox-inner\"><input id=\"bda-css-2\" type=\"checkbox\" "+(customCssEditor.hideBackdrop?"checked":"")+"><span><\/span><\/div>";attachEditor+=" <span title=\"Hide the callout backdrop to disable modal close events\">Hide Backdrop<\/span>";attachEditor+=" <\/div>";attachEditor+=" <\/li>";attachEditor+=" <\/ul>";attachEditor+=" <div id=\"bd-customcss-detach-controls-buttons\">";attachEditor+=" <button class=\"btn btn-primary\" id=\"bd-customcss-detached-update\" onclick=\"return false;\">Update<\/button>";attachEditor+=" <button class=\"btn btn-primary\" id=\"bd-customcss-detached-save\" onclick=\"return false;\">Save<\/button>";attachEditor+=" <button class=\"btn btn-primary\" id=\"bd-customcss-detached-detach\" onclick=\"customCssEditor.detach(); return false;\">Detach</button>";attachEditor+=" <\/div>";attachEditor+="<\/div>";this.attachEditor=attachEditor;$("#bd-customcss-innerpane").append(attachEditor);$("#bd-customcss-detached-update").on("click",function(){self.applyCustomCss(self.editor.getValue(),true,false);return false;});$("#bd-customcss-detached-save").on("click",function(){self.applyCustomCss(self.editor.getValue(),false,true);return false;});var detachEditor="";detachEditor+="<div id=\"bd-customcss-detach-container\">";detachEditor+=" <div id=\"bd-customcss-detach-editor\">";detachEditor+=" <\/div>";detachEditor+="<\/div>";this.detachedEditor=detachEditor;};CustomCssEditor.prototype.attach=function(){$("#editor-detached").hide();$("#app-mount").removeClass("bd-detached-editor");$("#bd-customcss-pane").append($("#bd-customcss-innerpane"));$("#bd-customcss-detached-detach").show();$("#bd-customcss-detach-container").remove();};CustomCssEditor.prototype.detach=function(){var self=this;this.attach();$("#editor-detached").show();$("#bd-customcss-detached-detach").hide();$("#app-mount").addClass("bd-detached-editor");$(".app").parent().append(this.detachedEditor);$("#bd-customcss-detach-editor").append($("#bd-customcss-innerpane"));};CustomCssEditor.prototype.applyCustomCss=function(css,forceupdate,forcesave){if($("#customcss").length==0){$("head").append('<style id="customcss"></style>');}
this.loadServers(dataset,true);};PublicServers.prototype.joinServer=function(code){$(".guilds-add").click();$(".action.join .btn").click();$(".create-guild-container input").val(code);$(".form.join-server .btn-primary").click();};function QuickEmoteMenu(){}
QuickEmoteMenu.prototype.init=function(){$(document).on("mousedown",function(e){if(e.target.id!="rmenu")$("#rmenu").remove();});var fe=localStorage["bdfavemotes"];if(fe!=undefined){this.favoriteEmotes=JSON.parse(atob(fe));}
var qmeHeader="";qmeHeader+="<div id=\"bda-qem\">";qmeHeader+=" <button class=\"active\" id=\"bda-qem-twitch\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Twitch<\/button>";qmeHeader+=" <button id=\"bda-qem-favourite\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Favourite<\/button>";qmeHeader+=" <button id=\"bda-qem-emojis\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Emojis<\/buttond>";qmeHeader+="<\/div>";this.qmeHeader=qmeHeader;var teContainer="";teContainer+="<div id=\"bda-qem-twitch-container\">";teContainer+=" <div class=\"scroller-wrap fade\">";teContainer+=" <div class=\"scroller\">";teContainer+=" <div class=\"emote-menu-inner\">";for(var emote in emotesTwitch.emotes){if(emotesTwitch.emotes.hasOwnProperty(emote)){var id=emotesTwitch.emotes[emote].image_id;teContainer+="<div class=\"emote-container\">";teContainer+=" <img class=\"emote-icon\" id=\""+emote+"\" alt=\"\" src=\"https://static-cdn.jtvnw.net/emoticons/v1/"+id+"/1.0\" title=\""+emote+"\">";teContainer+=" </img>";teContainer+="</div>";}}
teContainer+=" <\/div>";teContainer+=" <\/div>";teContainer+=" <\/div>";teContainer+="<\/div>";this.teContainer=teContainer;var faContainer="";faContainer+="<div id=\"bda-qem-favourite-container\">";faContainer+=" <div class=\"scroller-wrap fade\">";faContainer+=" <div class=\"scroller\">";faContainer+=" <div class=\"emote-menu-inner\">";for(var emote in this.favoriteEmotes){var url=this.favoriteEmotes[emote];faContainer+="<div class=\"emote-container\">";faContainer+=" <img class=\"emote-icon\" alt=\"\" src=\""+url+"\" title=\""+emote+"\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>";faContainer+=" </img>";faContainer+="</div>";}
faContainer+=" <\/div>";faContainer+=" <\/div>";faContainer+=" <\/div>";faContainer+="<\/div>";this.faContainer=faContainer;};QuickEmoteMenu.prototype.favContext=function(e,em){e.stopPropagation();var menu=$('<div/>',{id:"rmenu","data-emoteid":$(em).prop("title"),text:"Remove"});menu.css({top:e.pageY-$("#bda-qem-favourite-container").offset().top,left:e.pageX-$("#bda-qem-favourite-container").offset().left});$(em).parent().append(menu);menu.on("click",function(e){e.preventDefault();e.stopPropagation();$(this).remove();console.log($(this).data("emoteid"));delete quickEmoteMenu.favoriteEmotes[$(this).data("emoteid")];quickEmoteMenu.updateFavorites();return false;});return false;};QuickEmoteMenu.prototype.switchHandler=function(e){this.switchQem($(e).attr("id"));};QuickEmoteMenu.prototype.switchQem=function(id){var twitch=$("#bda-qem-twitch");var fav=$("#bda-qem-favourite");var emojis=$("#bda-qem-emojis");twitch.removeClass("active");fav.removeClass("active");emojis.removeClass("active");$(".emoji-picker").hide();$("#bda-qem-favourite-container").hide();$("#bda-qem-twitch-container").hide();switch(id){case"bda-qem-twitch":twitch.addClass("active");$("#bda-qem-twitch-container").show();break;case"bda-qem-favourite":fav.addClass("active");$("#bda-qem-favourite-container").show();break;case"bda-qem-emojis":emojis.addClass("active");$(".emoji-picker").show();break;}
this.lastTab=id;var emoteIcon=$(".emote-icon");emoteIcon.off();emoteIcon.on("click",function(){var emote=$(this).attr("title");var ta=$(".channel-textarea-inner textarea");ta.val(ta.val().slice(-1)==" "?ta.val()+emote:ta.val()+" "+emote);});};QuickEmoteMenu.prototype.obsCallback=function(e){if(!settingsCookie["bda-es-9"]){e.addClass("bda-qme-hidden");}else{e.removeClass("bda-qme-hidden");}
if(!settingsCookie["bda-es-0"])return;var self=this;e.prepend(this.qmeHeader);e.append(this.teContainer);e.append(this.faContainer);if(this.lastTab==undefined){this.lastTab="bda-qem-favourite";}
this.switchQem(this.lastTab);};QuickEmoteMenu.prototype.favorite=function(name,url){if(!this.favoriteEmotes.hasOwnProperty(name)){this.favoriteEmotes[name]=url;}
this.updateFavorites();};QuickEmoteMenu.prototype.updateFavorites=function(){var faContainer="";faContainer+="<div id=\"bda-qem-favourite-container\">";faContainer+=" <div class=\"scroller-wrap fade\">";faContainer+=" <div class=\"scroller\">";faContainer+=" <div class=\"emote-menu-inner\">";for(var emote in this.favoriteEmotes){var url=this.favoriteEmotes[emote];faContainer+="<div class=\"emote-container\">";faContainer+=" <img class=\"emote-icon\" alt=\"\" src=\""+url+"\" title=\""+emote+"\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>";faContainer+=" </img>";faContainer+="</div>";}
faContainer+=" <\/div>";faContainer+=" <\/div>";faContainer+=" <\/div>";faContainer+="<\/div>";this.faContainer=faContainer;$("#bda-qem-favourite-container").replaceWith(faContainer);window.localStorage["bdfavemotes"]=btoa(JSON.stringify(this.favoriteEmotes));};function CustomCssEditor(){}
CustomCssEditor.prototype.init=function(){var self=this;self.hideBackdrop=false;self.editor=CodeMirror.fromTextArea(document.getElementById("bd-custom-css-ta"),{lineNumbers:true,mode:'css',indentUnit:4,theme:'neat'});self.editor.on("change",function(cm){var css=cm.getValue();self.applyCustomCss(css,false,false);});var attachEditor="";attachEditor+="<div id=\"bd-customcss-attach-controls\">";attachEditor+=" <ul class=\"checkbox-group\">";attachEditor+=" <li>";attachEditor+=" <div class=\"checkbox\" onclick=\"settingsPanel.updateSetting(this);\">";attachEditor+=" <div class=\"checkbox-inner\"><input id=\"bda-css-0\" type=\"checkbox\" "+(settingsCookie["bda-css-0"]?"checked":"")+"><span><\/span><\/div>";attachEditor+=" <span title=\"Update client css while typing\">Live Update<\/span>";attachEditor+=" <\/div>";attachEditor+=" <\/li>";attachEditor+=" <li>";attachEditor+=" <div class=\"checkbox\" onclick=\"settingsPanel.updateSetting(this);\">";attachEditor+=" <div class=\"checkbox-inner\"><input id=\"bda-css-1\" type=\"checkbox\" "+(settingsCookie["bda-css-1"]?"checked":"")+"><span><\/span><\/div>";attachEditor+=" <span title=\"Autosave css to localstorage when typing\">Autosave<\/span>";attachEditor+=" <\/div>";attachEditor+=" <\/li>";attachEditor+=" <li>";attachEditor+=" <div class=\"checkbox\" onclick=\"settingsPanel.updateSetting(this);\">";attachEditor+=" <div class=\"checkbox-inner\"><input id=\"bda-css-2\" type=\"checkbox\" "+(customCssEditor.hideBackdrop?"checked":"")+"><span><\/span><\/div>";attachEditor+=" <span title=\"Hide the callout backdrop to disable modal close events\">Hide Backdrop<\/span>";attachEditor+=" <\/div>";attachEditor+=" <\/li>";attachEditor+=" <\/ul>";attachEditor+=" <div id=\"bd-customcss-detach-controls-buttons\">";attachEditor+=" <button class=\"btn btn-primary\" id=\"bd-customcss-detached-update\" onclick=\"return false;\">Update<\/button>";attachEditor+=" <button class=\"btn btn-primary\" id=\"bd-customcss-detached-save\" onclick=\"return false;\">Save<\/button>";attachEditor+=" <button class=\"btn btn-primary\" id=\"bd-customcss-detached-detach\" onclick=\"customCssEditor.detach(); return false;\">Detach</button>";attachEditor+=" <\/div>";attachEditor+="<\/div>";this.attachEditor=attachEditor;$("#bd-customcss-innerpane").append(attachEditor);$("#bd-customcss-detached-update").on("click",function(){self.applyCustomCss(self.editor.getValue(),true,false);return false;});$("#bd-customcss-detached-save").on("click",function(){self.applyCustomCss(self.editor.getValue(),false,true);return false;});var detachEditor="";detachEditor+="<div id=\"bd-customcss-detach-container\">";detachEditor+=" <div id=\"bd-customcss-detach-editor\">";detachEditor+=" <\/div>";detachEditor+="<\/div>";this.detachedEditor=detachEditor;};CustomCssEditor.prototype.attach=function(){$("#editor-detached").hide();$("#app-mount").removeClass("bd-detached-editor");$("#bd-customcss-pane").append($("#bd-customcss-innerpane"));$("#bd-customcss-detached-detach").show();$("#bd-customcss-detach-container").remove();};CustomCssEditor.prototype.detach=function(){var self=this;this.attach();$("#editor-detached").show();$("#bd-customcss-detached-detach").hide();$("#app-mount").addClass("bd-detached-editor");$(".app").parent().append(this.detachedEditor);$("#bd-customcss-detach-editor").append($("#bd-customcss-innerpane"));};CustomCssEditor.prototype.applyCustomCss=function(css,forceupdate,forcesave){if($("#customcss").length==0){$("head").append('<style id="customcss"></style>');}
if(forceupdate||settingsCookie["bda-css-0"]){$("#customcss").html(css);}
if(forcesave||settingsCookie["bda-css-1"]){localStorage.setItem("bdcustomcss",btoa(css));}};var settingsButton=null;var panel=null;function SettingsPanel(){utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.9.0/codemirror.min.js");utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.9.0/mode/css/css.min.js");utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.4.2/Sortable.min.js");}
SettingsPanel.prototype.init=function(){var self=this;self.construct();var body=$("body");if(settingsCookie["bda-es-0"]){$("#twitchcord-button-container").show();}else{$("#twitchcord-button-container").hide();}
@ -53,7 +56,7 @@ if(settingsCookie["bda-gs-1"]){$("#bd-pub-li").show();}else{$("#bd-pub-li").hide
if(settingsCookie["bda-gs-4"]){voiceMode.enable();}else{voiceMode.disable();}
if(settingsCookie["bda-es-6"]){emoteNamePopup=$("<div class='tipsy tipsy-se' style='display: block; top: 82px; left: 1630.5px; visibility: visible; opacity: 0.8;'><div class='tipsy-inner'></div></div>");$(document).on("mouseover",".emote",function(){var x=$(this).offset();var title=$(this).attr("alt");$(emoteNamePopup).find(".tipsy-inner").text(title);$(emoteNamePopup).css('left',x.left-25);$(emoteNamePopup).css('top',x.top-32);$("div[data-reactid='.0.1.1']").append($(emoteNamePopup));});$(document).on("mouseleave",".emote",function(){$(".tipsy").remove();});}else{$(document).off('mouseover','.emote');}
mainCore.saveSettings();};SettingsPanel.prototype.construct=function(){var self=this;panel=$("<div/>",{id:"bd-pane",class:"settings-inner",css:{"display":"none"}});var settingsInner=''+'<div class="scroller-wrap">'+' <div class="scroller settings-wrapper settings-panel">'+' <div class="tab-bar TOP">'+' <div class="tab-bar-item bd-tab" id="bd-settings-tab" onclick="settingsPanel.changeTab(\'bd-settings-tab\');">Settings</div>'+' <div class="tab-bar-item bd-tab" id="bd-customcss-tab" onclick="settingsPanel.changeTab(\'bd-customcss-tab\');">Custom CSS</div>'+' <div class="tab-bar-item bd-tab" id="bd-plugins-tab" onclick="settingsPanel.changeTab(\'bd-plugins-tab\');">Plugins</div>'+' <div class="tab-bar-item bd-tab" id="bd-themes-tab" onclick="settingsPanel.changeTab(\'bd-themes-tab\');">Themes</div>'+' </div>'+' <div class="bd-settings">'+' <div class="bd-pane control-group" id="bd-settings-pane" style="display:none;">'+' <ul class="checkbox-group">';for(var setting in settings){var sett=settings[setting];var id=sett["id"];if(sett["implemented"]&&!sett["hidden"]){settingsInner+=''+'<li>'+'<div class="checkbox" onclick="settingsPanel.updateSetting(this);" >'+'<div class="checkbox-inner">'+'<input type="checkbox" id="'+id+'" '+(settingsCookie[id]?"checked":"")+'>'+'<span></span>'+'</div>'+'<span>'+setting+" - "+sett["info"]+'</span>'+'</div>'+'</li>';}}
var ccss=atob(localStorage.getItem("bdcustomcss"));customCssEditor.applyCustomCss(ccss,true,false);settingsInner+='</ul>'+' </div>'+''+' <div class="bd-pane control-group" id="bd-customcss-pane" style="display:none;">'+' <div id="editor-detached" style="display:none;">'+' <h3>Editor Detached</h3>'+' <button class="btn btn-primary" onclick="customCssEditor.attach(); return false;">Attach</button>'+' </div>'+' <div id="bd-customcss-innerpane"><textarea id="bd-custom-css-ta">'+ccss+'</textarea></div>'+' </div>'+''+' <div class="bd-pane control-group" id="bd-plugins-pane" style="display:none;">'+' <table class="bd-g-table">'+' <thead><tr><th>Name</th><th>Description</th><th>Author</th><th>Version</th><th></th><th></th></tr></thead><tbody>';$.each(bdplugins,function(){var plugin=this["plugin"];settingsInner+=''+'<tr>'+' <td>'+plugin.getName()+'</td>'+' <td width="99%"><textarea>'+plugin.getDescription()+'</textarea></td>'+' <td>'+plugin.getAuthor()+'</td>'+' <td>'+plugin.getVersion()+'</td>'+' <td><button class="bd-psb" onclick="pluginModule.showSettings(\''+plugin.getName()+'\'); return false;"></button></td>'+' <td>'+' <div class="checkbox" onclick="pluginModule.handlePlugin(this);">'+' <div class="checkbox-inner">'+' <input id="'+plugin.getName()+'" type="checkbox" '+(pluginCookie[plugin.getName()]?"checked":"")+'>'+' <span></span>'+' </div>'+' </div>'+' </td>'+'</tr>';});settingsInner+='</tbody></table>'+' </div>'+' <div class="bd-pane control-group" id="bd-themes-pane" style="display:none;">';if(typeof(themesupport2)==="undefined"){settingsInner+=''+' Your version does not support themes. Download the latest version.';}else{settingsInner+=''+' <table class="bd-g-table">'+' <thead><tr><th>Name</th><th>Description</th><th>Author</th><th>Version</th><th></th></tr></thead><tbody>';$.each(bdthemes,function(){settingsInner+=''+'<tr>'+' <td>'+this["name"].replace(/_/g," ")+'</td>'+' <td width="99%"><textarea>'+this["description"]+'</textarea></td>'+' <td>'+this["author"]+'</td>'+' <td>'+this["version"]+'</td>'+' <td>'+' <div class="checkbox" onclick="themeModule.handleTheme(this);">'+' <div class="checkbox-inner">'+' <input id="ti'+this["name"]+'" type="checkbox" '+(themeCookie[this["name"]]?"checked":"")+'>'+' <span></span>'+' </div>'+' </div>'+' </td>'+'</tr>';});settingsInner+='</tbody></table>';}
var ccss=atob(localStorage.getItem("bdcustomcss"));customCssEditor.applyCustomCss(ccss,true,false);settingsInner+='</ul>'+' </div>'+''+' <div class="bd-pane control-group" id="bd-customcss-pane" style="display:none;">'+' <div id="editor-detached" style="display:none;">'+' <h3>Editor Detached</h3>'+' <button class="btn btn-primary" onclick="customCssEditor.attach(); return false;">Attach</button>'+' </div>'+' <div id="bd-customcss-innerpane"><textarea id="bd-custom-css-ta">'+ccss+'</textarea></div>'+' </div>'+''+' <div class="bd-pane control-group" id="bd-plugins-pane" style="display:none;">'+' <table class="bd-g-table">'+' <thead><tr><th>Name</th><th>Description</th><th>Author</th><th>Version</th><th></th><th></th></tr></thead><tbody>';$.each(bdplugins,function(){var plugin=this["plugin"];settingsInner+=''+'<tr>'+' <td>'+plugin.getName()+'</td>'+' <td width="99%"><textarea>'+plugin.getDescription()+'</textarea></td>'+' <td>'+plugin.getAuthor()+'</td>'+' <td>'+plugin.getVersion()+'</td>'+' <td><button class="bd-psb" onclick="pluginModule.showSettings(\''+plugin.getName()+'\'); return false;"></button></td>'+' <td>'+' <div class="checkbox" onclick="pluginModule.handlePlugin(this);">'+' <div class="checkbox-inner">'+' <input id="'+plugin.getName()+'" type="checkbox" '+(pluginCookie[plugin.getName()]?"checked":"")+'>'+' <span></span>'+' </div>'+' </div>'+' </td>'+'</tr>';});settingsInner+='</tbody></table>'+' </div>'+' <div class="bd-pane control-group" id="bd-themes-pane" style="display:none;">';if(typeof(themesupport2)==="undefined"){settingsInner+=''+' Your version does not support themes. Download the latest version.';}else{settingsInner+=''+' <table class="bd-g-table">'+' <thead><tr><th>Name</th><th>Description</th><th>Author</th><th>Version</th><th></th></tr></thead><tbody>';$.each(bdthemes,function(){settingsInner+=''+'<tr>'+' <td>'+this["name"].replace(/_/g," ")+'</td>'+' <td width="99%"><textarea>'+this["description"]+'</textarea></td>'+' <td>'+this["author"]+'</td>'+' <td>'+this["version"]+'</td>'+' <td>'+' <div class="checkbox" onclick="themeModule.handleTheme(this);">'+' <div class="checkbox-inner">'+' <input id="ti'+this["name"]+'" type="checkbox" '+(themeCookie[this["name"]]?"checked":"")+'>'+' <span></span>'+' </div>'+' </div>'+' </td>'+'</tr>';});settingsInner+='</tbody></table>';}
settingsInner+=''+' </div>'+''+' </div>'+' </div>'+' <div style="background:#2E3136; color:#ADADAD; height:30px; position:absolute; bottom:0; left:0; right:0;">'+' <span style="line-height:30px;margin-left:10px;">BetterDiscord v'+version+'(JSv'+jsVersion+') by Jiiks</span>'+' <span style="float:right;line-height:30px;margin-right:10px;"><a href="http://betterdiscord.net" target="_blank">BetterDiscord.net</a></span>'+' </div>'+'</div>';function showSettings(){$(".tab-bar-item").removeClass("selected");settingsButton.addClass("selected");$(".form .settings-right .settings-inner").first().hide();panel.show();if(lastTab==""){self.changeTab("bd-settings-tab");}else{self.changeTab(lastTab);}}
settingsButton=$("<div/>",{class:"tab-bar-item",text:"BetterDiscord",id:"bd-settings-new",click:showSettings});panel.html(settingsInner);function defer(){if($(".btn.btn-settings").length<1){setTimeout(defer,100);}else{$(".btn.btn-settings").first().on("click",function(){function innerDefer(){if($(".modal-inner").first().is(":visible")){panel.hide();var tabBar=$(".tab-bar.SIDE").first();$(".tab-bar.SIDE .tab-bar-item").click(function(){$(".form .settings-right .settings-inner").first().show();$("#bd-settings-new").removeClass("selected");panel.hide();});tabBar.append(settingsButton);$(".form .settings-right .settings-inner").last().after(panel);$("#bd-settings-new").removeClass("selected");}else{setTimeout(innerDefer,100);}}
innerDefer();});}}