From bd3503043741138a4cd66339642b9a5fe721fe0c Mon Sep 17 00:00:00 2001 From: Zack Rauen Date: Sun, 14 Oct 2018 03:45:56 -0400 Subject: [PATCH] some refactoring fixes #49 #53 #56 #51 Refactoring of Utils, bdSettingsStorage. Change load order to quickEmoteMenu. Update 24hour patch. Update CDNs. Adjust emote render patch. Move Emote cache check to render process. Officially remove dependency on jquery-cookie --- LICENSE | 2 +- js/main.js | 530 +++++++++++++++++++++++-------------------------- js/main.min.js | 8 +- 3 files changed, 255 insertions(+), 285 deletions(-) diff --git a/LICENSE b/LICENSE index 58c3eea6..c19c6dc4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2015-present Jiiks | Jiiks.net +Copyright (c) 2015-present Jiiks | 2017-present Zack Rauen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/js/main.js b/js/main.js index 119efc68..83cf5d8f 100644 --- a/js/main.js +++ b/js/main.js @@ -66,6 +66,7 @@ document.body.appendChild(v2Loader); })(); +/* global DiscordNative:false */ window.bdStorage = {}; window.bdStorage.get = function(i) { @@ -84,43 +85,47 @@ window.bdPluginStorage.set = function(pn, i, v) { var bdSettings = {}; var bdSettingsStorage = {}; +var releaseChannel = DiscordNative.globals.releaseChannel; bdSettingsStorage.initialize = function() { let fs = require("fs"); - let data = {}; + 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 = {}; + data = {stable: {}, canary: {}, ptb: {}}; } } if (data) bdSettings = data; - else bdSettings = {}; + else bdSettings = {stable: {}, canary: {}, ptb: {}}; }; bdSettingsStorage.get = function(key) { - if (bdSettings[key]) return bdSettings[key]; + if (bdSettings[releaseChannel][key]) return bdSettings[releaseChannel][key]; return null; }; bdSettingsStorage.set = function(key, data) { let fs = require("fs"); - bdSettings[key] = data; + bdSettings[releaseChannel][key] = data; try { fs.writeFileSync(bdConfig.dataPath + "/bdsettings.json", JSON.stringify(bdSettings, null, 4)); return true; } catch (err) { - utils.err(err); + Utils.err(err); return false; } }; -var settingsPanel, emoteModule, utils, quickEmoteMenu, voiceMode, pluginModule, themeModule, dMode, publicServersModule; +var settingsPanel, emoteModule, quickEmoteMenu, voiceMode, pluginModule, themeModule, dMode, publicServersModule; var jsVersion = 1.792; var supportedVersion = "0.2.81"; -var bbdVersion = "0.1.0"; +var bbdVersion = "0.1.1"; var mainCore; @@ -221,16 +226,19 @@ Core.prototype.init = async function() { return; } - utils = new Utils(); - await utils.getHash(); - utils.log("Initializing Settings"); + Utils.log("Initializing Settings"); this.initSettings(); classNormalizer = new ClassNormalizer(); emoteModule = new EmoteModule(); - utils.log("Initializing EmoteModule"); - window.emotePromise = emoteModule.init().then(() => {emoteModule.initialized = true;}); - publicServersModule = new V2_PublicServers(); 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(); @@ -243,7 +251,7 @@ Core.prototype.init = async function() { self.injectExternals(); - utils.log("Updating Settings"); + Utils.log("Updating Settings"); settingsPanel = new V2_SettingsPanel(); settingsPanel.updateSettings(); @@ -251,18 +259,15 @@ Core.prototype.init = async function() { if (!bdpluginErrors) bdpluginErrors = []; if (!bdthemeErrors) bdthemeErrors = []; - utils.log("Loading Plugins"); + Utils.log("Loading Plugins"); pluginModule = new PluginModule(); pluginModule.loadPlugins(); - utils.log("Loading Themes"); + Utils.log("Loading Themes"); themeModule = new ThemeModule(); themeModule.loadThemes(); $("#customcss").detach().appendTo(document.head); - - utils.log("Initializing QuickEmoteMenu"); - quickEmoteMenu.init(); window.addEventListener("beforeunload", function(){ if (settingsCookie["bda-dc-0"]) document.querySelector(".btn.btn-disconnect").click(); @@ -279,14 +284,14 @@ Core.prototype.init = async function() { self.saveSettings(); } - utils.log("Removing Loading Icon"); + Utils.log("Removing Loading Icon"); document.getElementsByClassName("bd-loaderv2")[0].remove(); - utils.log("Initializing Main Observer"); + Utils.log("Initializing Main Observer"); self.initObserver(); // Show loading errors if (settingsCookie["fork-ps-1"]) { - utils.log("Collecting Startup Errors"); + Utils.log("Collecting Startup Errors"); self.showStartupErrors(); } } @@ -302,20 +307,11 @@ Core.prototype.init = async function() { }; Core.prototype.injectExternals = function() { - utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"); + Utils.injectJs("https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"); }; Core.prototype.initSettings = function () { - // $.removeCookie('the_cookie', { path: '/' }); bdSettingsStorage.initialize(); - - if ($.cookie("better-discord")) { - settingsCookie = JSON.parse($.cookie("better-discord")); - this.saveSettings(); - $.removeCookie("better-discord", {path: "/"}); - return; - } - if (!bdSettingsStorage.get("settings")) { settingsCookie = defaultCookie; this.saveSettings(); @@ -377,9 +373,14 @@ Core.prototype.initObserver = function () { Core.prototype.inject24Hour = function() { if (this.cancel24Hour) return; - this.cancel24Hour = Utils.monkeyPatch(BDV2.TimeFormatter, "calendarFormat", {before: ({methodArguments}) => { + const twelveHour = new RegExp(`([0-9]{1,2}):([0-9]{1,2})\\s(AM|PM)`); + + this.cancel24Hour = Utils.monkeyPatch(BDV2.TimeFormatter, "calendarFormat", {after: (data) => { if (!settingsCookie["bda-gs-6"]) return; - methodArguments[0]._locale._abbr = "en-GB"; + const matched = data.returnValue.match(twelveHour); + if (!matched || matched.length !== 4) return; + if (matched[3] === "AM") return data.returnValue = data.returnValue.replace(matched[0], `${matched[1] === "12" ? "00" : matched[1].padStart(2, "0")}:${matched[2]}`); + return data.returnValue = data.returnValue.replace(matched[0], `${parseInt(matched[1]) + 12}:${matched[2]}`); }}); }; @@ -480,7 +481,7 @@ Core.prototype.showStartupErrors = function() { if (err.error) { error.find("a").on("click", (e) => { e.preventDefault(); - utils.err(`Error details for ${err.name ? err.name : err.file}.`, err.error); + Utils.err(`Error details for ${err.name ? err.name : err.file}.`, err.error); }); } } @@ -592,7 +593,7 @@ EmoteModule.prototype.init = async function () { let emoteInfo = { TwitchGlobal: { url: "https://twitchemotes.com/api_cache/v3/global.json", - backup: "https://" + bdConfig.updater.CDN + "/" + bdConfig.repo + "/BetterDiscordApp/" + bdConfig.hash + "/data/emotedata_twitch_global.json", + backup: "https://cdn.staticaly.com/gh/rauenzi/BetterDiscordApp/master/data/emotedata_twitch_global.json", variable: "TwitchGlobal", oldVariable: "emotesTwitch", getEmoteURL: (e) => `https://static-cdn.jtvnw.net/emoticons/v1/${e.id}/1.0`, @@ -600,7 +601,7 @@ EmoteModule.prototype.init = async function () { }, TwitchSubscriber: { url: "https://twitchemotes.com/api_cache/v3/subscriber.json", - backup: "https://" + bdConfig.updater.CDN + "/" + bdConfig.repo + "/BetterDiscordApp/" + bdConfig.hash + "/data/emotedata_twitch_subscriber.json", + backup: "https://cdn.staticaly.com/gh/rauenzi/BetterDiscordApp/master/data/emotedata_twitch_subscriber.json", variable: "TwitchSubscriber", oldVariable: "subEmotesTwitch", parser: (data) => { @@ -621,7 +622,7 @@ EmoteModule.prototype.init = async function () { getOldData: (url) => url.match(/\/([0-9]+)\//)[1] }, FrankerFaceZ: { - url: "https://" + bdConfig.updater.CDN + "/" + bdConfig.repo + "/BetterDiscordApp/" + bdConfig.hash + "/data/emotedata_ffz.json", + url: "https://cdn.staticaly.com/gh/rauenzi/BetterDiscordApp/master/data/emotedata_ffz.json", variable: "FrankerFaceZ", oldVariable: "emotesFfz", getEmoteURL: (e) => `https://cdn.frankerfacez.com/emoticon/${e}/1`, @@ -643,7 +644,7 @@ EmoteModule.prototype.init = async function () { getOldData: (url) => url }, BTTV2: { - url: "https://" + bdConfig.updater.CDN + "/" + bdConfig.repo + "/BetterDiscordApp/" + bdConfig.hash + "/data/emotedata_bttv.json", + url: "https://cdn.staticaly.com/gh/rauenzi/BetterDiscordApp/master/data/emotedata_bttv.json", variable: "BTTV2", oldVariable: "emotesBTTV2", getEmoteURL: (e) => `https://cdn.betterttv.net/emote/${e}/1x`, @@ -666,10 +667,10 @@ EmoteModule.prototype.init = async function () { for (let n = 0; n < nodes.length; n++) { const node = nodes[n]; if (typeof(node) !== "string") continue; - const words = node.split(/([^\s]+)([\s]|$)/g); + const words = node.split(/([^\s]+)([\s]|$)/g); for (let c = 0, clen = this.categories.length; c < clen; c++) { for (let w = 0, wlen = words.length; w < wlen; w++) { - let emote = words[w]; + let emote = words[w]; let emoteSplit = emote.split(":"); let emoteName = emoteSplit[0]; let emoteModifier = emoteSplit[1] ? emoteSplit[1] : ""; @@ -694,15 +695,14 @@ EmoteModule.prototype.init = async function () { } if (!window.bdEmotes[current][emoteName] || !settingsCookie[window.bdEmoteSettingIDs[current]]) continue; - const results = nodes[n].match(new RegExp(`([\\s]|^)${utils.escape(emoteModifier ? emoteName + ":" + emoteModifier : emoteName)}([\\s]|$)`)); - if (!results) continue; + const results = nodes[n].match(new RegExp(`([\\s]|^)${Utils.escape(emoteModifier ? emoteName + ":" + emoteModifier : emoteName)}([\\s]|$)`)); + if (!results) continue; const pre = nodes[n].substring(0, results.index + results[1].length); const post = nodes[n].substring(results.index + results[0].length - results[2].length); nodes[n] = pre; const emoteComponent = BDV2.react.createElement(BDEmote, {name: emoteName, url: window.bdEmotes[current][emoteName], modifier: emoteModifier}); nodes.splice(n + 1, 0, post); nodes.splice(n + 1, 0, emoteComponent); - n = n + 2; } } } @@ -728,8 +728,8 @@ EmoteModule.prototype.clearEmoteData = async function() { let emoteFile = "emote_data.json"; let file = bdConfig.dataPath + emoteFile; let exists = _fs.existsSync(file); - if (exists) _fs.unlinkSync(file); + window.bdStorage.set("emoteCacheDate", (new Date()).toJSON()); window.bdEmotes = { TwitchGlobal: {}, @@ -748,19 +748,30 @@ EmoteModule.prototype.goBack = async function(emoteInfo) { } }; +EmoteModule.prototype.isCacheValid = function() { + const cacheDate = new Date(window.bdStorage.get("emoteCacheDate") || null); + const currentDate = new Date(); + const daysBetween = Math.round(Math.abs((currentDate.getTime() - cacheDate.getTime()) / (24 * 60 * 60 * 1000))); + if (daysBetween > bdConfig.cache.days) { + window.bdStorage.set("emoteCacheDate", currentDate.toJSON()); + return false; + } + return true; +}; + EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { - let _fs = require("fs"); - let emoteFile = "emote_data.json"; - let file = bdConfig.dataPath + emoteFile; - let exists = _fs.existsSync(file); + const _fs = require("fs"); + const emoteFile = "emote_data.json"; + const file = bdConfig.dataPath + emoteFile; + const exists = _fs.existsSync(file); - if (exists && !bdConfig.cache.expired) { + if (exists && this.isCacheValid()) { if (settingsCookie["fork-ps-2"]) mainCore.showToast("Loading emotes from cache.", {type: "info"}); - utils.log("[Emotes] Loading emotes from local cache."); + Utils.log("[Emotes] Loading emotes from local cache."); - let data = await new Promise(resolve => { + const data = await new Promise(resolve => { _fs.readFile(file, "utf8", (err, data) => { - utils.log("[Emotes] Emotes loaded from cache."); + Utils.log("[Emotes] Emotes loaded from cache."); if (err) data = {}; resolve(data); }); @@ -769,7 +780,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { let isValid = Utils.testJSON(data); if (isValid) window.bdEmotes = JSON.parse(data); - for (let e in emoteInfo) { + for (const e in emoteInfo) { isValid = Object.keys(window.bdEmotes[emoteInfo[e].variable]).length > 0; } @@ -778,7 +789,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { return; } - utils.log("[Emotes] Cache was corrupt, downloading..."); + Utils.log("[Emotes] Cache was corrupt, downloading..."); _fs.unlinkSync(file); } @@ -794,7 +805,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { if (settingsCookie["fork-ps-2"]) mainCore.showToast("All emotes successfully downloaded.", {type: "success"}); try { _fs.writeFileSync(file, JSON.stringify(window.bdEmotes), "utf8"); } - catch (err) { utils.err("[Emotes] Could not save emote data.", err); } + catch (err) { Utils.err("[Emotes] Could not save emote data.", err); } quickEmoteMenu.init(); }; @@ -806,12 +817,12 @@ EmoteModule.prototype.downloadEmotes = function(emoteMeta) { timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000 }; - utils.log("[Emotes] Downloading: " + emoteMeta.variable); + Utils.log("[Emotes] Downloading: " + emoteMeta.variable); return new Promise((resolve, reject) => { request(options, (error, response, body) => { if (error) { - utils.err("[Emotes] Could not download " + emoteMeta.variable, error); + Utils.err("[Emotes] Could not download " + emoteMeta.variable, error); if (emoteMeta.backup) { emoteMeta.url = emoteMeta.backup; emoteMeta.backup = null; @@ -826,7 +837,7 @@ EmoteModule.prototype.downloadEmotes = function(emoteMeta) { parsedData = JSON.parse(body); } catch (err) { - utils.err("[Emotes] Could not download " + emoteMeta.variable, error); + Utils.err("[Emotes] Could not download " + emoteMeta.variable, error); if (emoteMeta.backup) { emoteMeta.url = emoteMeta.backup; emoteMeta.backup = null; @@ -841,14 +852,14 @@ EmoteModule.prototype.downloadEmotes = function(emoteMeta) { parsedData[emote] = emoteMeta.getEmoteURL(parsedData[emote]); } resolve(parsedData); - utils.log("[Emotes] Downloaded: " + emoteMeta.variable); + Utils.log("[Emotes] Downloaded: " + emoteMeta.variable); }); }); }; EmoteModule.prototype.getBlacklist = function () { return new Promise(resolve => { - $.getJSON("https://cdn.rawgit.com/rauenzi/betterDiscordApp/" + _hash + "/data/emotefilter.json", function (data) { + $.getJSON("https://cdn.staticaly.com/gh/rauenzi/BetterDiscordApp/master/data/emotefilter.json", function (data) { resolve(bemotes = data.blacklist); }); }); @@ -868,7 +879,7 @@ EmoteModule.prototype.autoCapitalize = function () { if (lastWord == "danSgame") return; var ret = this.capitalize(lastWord.toLowerCase()); if (ret !== null && ret !== undefined) { - utils.insertText(utils.getTextArea()[0], text.replace(lastWord, ret)); + Utils.insertText(Utils.getTextArea()[0], text.replace(lastWord, ret)); } } }); @@ -1011,8 +1022,8 @@ QuickEmoteMenu.prototype.switchQem = function(id) { emoteIcon.off(); emoteIcon.on("click", function () { var emote = $(this).attr("title"); - var ta = utils.getTextArea(); - utils.insertText(ta[0], ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote); + var ta = Utils.getTextArea(); + Utils.insertText(ta[0], ta.val().slice(-1) == " " ? ta.val() + emote : ta.val() + " " + emote); }); }; @@ -1078,202 +1089,175 @@ QuickEmoteMenu.prototype.updateFavorites = function () { * Date: 26/08/2015 - 15:54 * https://github.com/Jiiks/BetterDiscordApp */ - -var _hash; - -function Utils() { - -} - -Utils.prototype.getTextArea = function () { - return $(".channelTextArea-1LDbYG textarea"); -}; - -Utils.prototype.insertText = function (textarea, text) { - textarea.focus(); - textarea.selectionStart = 0; - textarea.selectionEnd = textarea.value.length; - document.execCommand("insertText", false, text); -}; - -Utils.prototype.jqDefer = function (fnc) { - if (window.jQuery) { - fnc(); - } - else { - setTimeout(function () { - this.jqDefer(fnc); - }, 100); - } -}; - -Utils.prototype.getHash = function () { - return new Promise((resolve) => { - $.getJSON("https://api.github.com/repos/rauenzi/BetterDiscordApp/commits/master").done(function (data) { - _hash = data.sha; - bdConfig.hash = _hash; - resolve(_hash); - }).fail(() => { - _hash = _bdhash || "48844445d65c6fb5a019eff14d7dcffcc1744071"; - resolve(_hash); - }); - }); -}; - -Utils.prototype.loadHtml = function (html, callback) { - var container = $("
", { - "class": "bd-container" - }).appendTo("body"); - - //TODO Inject these in next core update - html = "//cdn.rawgit.com/Jiiks/BetterDiscordApp/" + _hash + "/html/" + html + ".html"; - - container.load(html, callback()); -}; - -Utils.prototype.injectJs = function (uri) { - $("