From ec6cac61f373ec0100f1225d5f987bede497afd2 Mon Sep 17 00:00:00 2001 From: Mirco Wittrien Date: Sat, 26 Jan 2019 23:54:46 +0100 Subject: [PATCH] fixed all BDv2 plugins --- Plugins/CharCounter/CharCounter.plugin.js | 2 - Plugins/ChatAliases/ChatAliases.plugin.js | 2 +- PluginsV2/BadgesEverywhere/index.js | 294 ++-- PluginsV2/BetterFriendCount/index.js | 99 +- PluginsV2/BetterNsfwTag/index.js | 75 +- PluginsV2/BetterPageSearch/index.js | 214 ++- PluginsV2/CharCounter/index.js | 160 ++- PluginsV2/ChatAliases/index.js | 300 ++-- PluginsV2/ChatFilter/index.js | 312 ++--- PluginsV2/CompleteTimestamps/index.js | 336 +++-- PluginsV2/CreationDate/index.js | 184 ++- PluginsV2/DisplayServersAsChannels/index.js | 221 +-- PluginsV2/EditChannels/index.js | 636 +++++---- PluginsV2/EditServers/index.js | 532 ++++--- PluginsV2/EditUsers/index.js | 1386 ++++++++++--------- PluginsV2/EmojiStatistics/index.js | 269 ++-- PluginsV2/FixGermanTranslation/README.md | 5 - PluginsV2/FixGermanTranslation/config.json | 15 - PluginsV2/FixGermanTranslation/index.js | 254 ---- PluginsV2/ForceImagePreviews/index.js | 140 +- PluginsV2/FriendNotifications/index.js | 309 ++--- PluginsV2/GoogleSearchReplace/index.js | 139 +- PluginsV2/GoogleTranslateOption/index.js | 809 ++++++----- PluginsV2/ImageGallery/index.js | 171 ++- PluginsV2/MessageUtilities/index.js | 295 ++-- PluginsV2/MoveablePopups/index.js | 83 +- PluginsV2/NotificationSounds/index.js | 2 +- PluginsV2/OldTitleBar/index.js | 2 +- PluginsV2/PersonalPins/index.js | 2 +- PluginsV2/PinDMs/index.js | 2 +- PluginsV2/RemoveNicknames/index.js | 3 +- PluginsV2/ShowHiddenChannels/index.js | 3 +- PluginsV2/ShowImageDetails/index.js | 3 +- 33 files changed, 3385 insertions(+), 3874 deletions(-) delete mode 100644 PluginsV2/FixGermanTranslation/README.md delete mode 100644 PluginsV2/FixGermanTranslation/config.json delete mode 100644 PluginsV2/FixGermanTranslation/index.js diff --git a/Plugins/CharCounter/CharCounter.plugin.js b/Plugins/CharCounter/CharCounter.plugin.js index a5f37ef05e..e6a44b1fb3 100644 --- a/Plugins/CharCounter/CharCounter.plugin.js +++ b/Plugins/CharCounter/CharCounter.plugin.js @@ -16,8 +16,6 @@ class CharCounter { "Modal":"componentDidMount" }; - this.selecting = false; - this.maxLenghts = { normal: 2000, edit: 2000, diff --git a/Plugins/ChatAliases/ChatAliases.plugin.js b/Plugins/ChatAliases/ChatAliases.plugin.js index bfc0079db0..0a8fe255b5 100644 --- a/Plugins/ChatAliases/ChatAliases.plugin.js +++ b/Plugins/ChatAliases/ChatAliases.plugin.js @@ -228,8 +228,8 @@ class ChatAliases { processStandardSidebarView (instance, wrapper) { if (this.SettingsUpdated) { - BDFDB.WebModules.forceAllUpdates(this); delete this.SettingsUpdated; + BDFDB.WebModules.forceAllUpdates(this); } } diff --git a/PluginsV2/BadgesEverywhere/index.js b/PluginsV2/BadgesEverywhere/index.js index aa4c2e9067..dc1efaaed7 100644 --- a/PluginsV2/BadgesEverywhere/index.js +++ b/PluginsV2/BadgesEverywhere/index.js @@ -3,53 +3,63 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { + this.patchModules = { + "NameTag":"componentDidMount", + "MessageUsername":"componentDidMount" + }; + this.css = ` .BE-badge { display: inline-block; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 16px; - margin: 0 2px; + height: 17px !important; + margin: 0 2px !important; } - .BE-badge-chat { - margin-bottom: -3px; + .BE-badge.BE-badge-chat { + margin-bottom: -3px !important; } - .BE-badge:first-of-type { - margin-left: 5px; + .BE-badge.BE-badge-popout { + margin-bottom: -2px !important; } - .BE-badge:last-of-type { - margin-right: 5px; + .BE-badge.BE-badge:first-of-type { + margin-left: 5px !important; } - .BE-badge-Staff {width:16px} - .BE-badge-Partner {width:21px} - .BE-badge-HypeSquad {width:17px} - .BE-badge-BugHunter {width:17px} - .BE-badge-Nitro {width:21px}`; + .BE-badge.BE-badge:last-of-type { + margin-right: 5px !important; + } + .BE-badge.BE-badge-Staff {width:17px !important; min-width:17px !important;} + .BE-badge.BE-badge-Partner {width:22px !important; min-width:22px !important;} + .BE-badge.BE-badge-HypeSquad {width:17px !important; min-width:17px !important;} + .BE-badge.BE-badge-BugHunter {width:17px !important; min-width:17px !important;} + .BE-badge.BE-badge-HypeSquadBravery {width:17px !important; min-width:17px !important;} + .BE-badge.BE-badge-HypeSquadBrilliance {width:17px !important; min-width:17px !important;} + .BE-badge.BE-badge-HypeSquadBalance {width:17px !important; min-width:17px !important;} + .BE-badge.BE-badge-EarlySupporter {width:24px !important; min-width:24px !important;} + .BE-badge.BE-badge-Nitro {width:21px !important; min-width:21px !important;} + .BE-badge.BE-badge-settings {width:30px !important; min-width:30px !important;}`; - this.loading = false; - - this.updateBadges = false; - - this.badges = { - 1: {name:"Staff", implemented:true, white:"url(https://discordapp.com/assets/7cfd90c8062139e4804a1fa59f564731.svg)", color:"url(https://discordapp.com/assets/4358ad1fb423b346324516453750f569.svg)"}, - 2: {name:"Partner", implemented:true, white:"url(https://discordapp.com/assets/a0e288a458c48dfcf548dadc277e42e6.svg)", color:"url(https://discordapp.com/assets/33fedf082addb91d88abc272b4b18daa.svg)"}, - 4: {name:"HypeSquad", implemented:true, white:"url(https://discordapp.com/assets/0aae6033ad41cdda515a62cf72075afa.svg)", color:"url(https://discordapp.com/assets/17ebd99540a6e983bade13c3afff7946.svg)"}, - 8: {name:"BugHunter", implemented:true, white:"url(https://discordapp.com/assets/df26f079738a4dcd07cbce6eb3c957f1.svg)", color:"url(https://discordapp.com/assets/f61b8981e92feead854f52e5a1ba14f0.svg)"}, - 16: {name:"MFASMS", implemented:false, white:"", color:""}, - 32: {name:"PROMODISMISSED", implemented:false, white:"", color:""}, - 256: {name:"Nitro", implemented:true, white:"url(https://discordapp.com/assets/379d2b3171722ef8be494231234da5d1.svg)", color:"url(https://discordapp.com/assets/386884eecd36164487505ddfbac35a9d.svg)"} - }; this.requestedusers = {}; this.loadedusers = {}; this.defaults = { settings: { + showInPopout: {value:true, description:"Show Badge in User Popout."}, showInChat: {value:true, description:"Show Badge in Chat Window."}, showInMemberList: {value:true, description:"Show Badge in Member List."}, - showInPopout: {value:true, description:"Show Badge in User Popout."}, - useColoredVersion: {value:true, description:"Use colored version of the Badges."} + useColoredVersion: {value:true, description:"Use colored version of the Badges for Chat and Members."} + }, + badges: { + 1: {value:true, name:"Staff", selector:"profileBadgeStaff"}, + 2: {value:true, name:"Partner", selector:"profileBadgePartner"}, + 4: {value:true, name:"HypeSquad", selector:"profileBadgeHypesquad"}, + 8: {value:true, name:"BugHunter", selector:"profileBadgeBugHunter"}, + 16: {value:false, name:"MFASMS", selector:false}, + 32: {value:false, name:"PROMODISMISSED", selector:false}, + 64: {value:true, name:"HypeSquad Bravery", selector:"profileBadgeHypeSquadOnlineHouse1"}, + 128: {value:true, name:"HypeSquad Brilliance", selector:"profileBadgeHypeSquadOnlineHouse2"}, + 256: {value:true, name:"HypeSquad Balance", selector:"profileBadgeHypeSquadOnlineHouse3"}, + 512: {value:true, name:"Early Supporter", selector:"profileBadgeEarlySupporter"}, + 2048: {value:true, name:"Nitro", selector:"profileBadgePremium"} } }; } @@ -74,84 +84,16 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - this.UserModalUtils = BDFDB.WebModules.findByProperties("fetchMutualFriends","open"); this.APIModule = BDFDB.WebModules.findByProperties("getAPIBaseURL"); this.DiscordConstants = BDFDB.WebModules.findByProperties("Permissions", "ActivityTypes", "StatusTypes"); + this.BadgeClasses = BDFDB.WebModules.findByProperties("profileBadgeStaff","profileBadgePremium"); - var observer = null; + for (let flag in this.defaults.badges) if (!this.defaults.badges[flag].selector) delete this.defaults.badges[flag]; - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.querySelector(BDFDB.dotCN.memberusername) && BDFDB.getData("showInMemberList", this, "settings")) { - this.addBadges(node, "list", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.memberswrap, {name:"userListObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (BDFDB.getData("showInChat", this, "settings")) { - if ($(BDFDB.dotCN.messagegroup).has(BDFDB.dotCN.avatarlargeold).length > 0) { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.messageusernamewrapper)) { - this.addBadges(node, "chat", false); - } - else if (node && node.classList && node.classList.contains(BDFDB.disCN.messagetext)) { - this.addBadges($(BDFDB.dotCN.messagegroup).has(node)[0], "chat", false); - } - } - else { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.messageusernamewrapper)) { - if (node.classList.contains(BDFDB.disCN.messagemarkup)) { - this.addBadges(node, "chat", true); - } - else { - var markups = node.querySelectorAll(BDFDB.dotCN.messagemarkup); - for (var i = 0; i < markups.length; i++) { - this.addBadges(markups[i], "chat", true); - } - } - } - } - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.userpopout) && BDFDB.getData("showInPopout", this, "settings")) { - this.addBadges(node, "popout", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.popouts, {name:"userPopoutObserver",instance:observer}, {childList: true}); - - for (let flag in this.badges) { - if (!this.badges[flag].implemented) delete this.badges[flag]; - } - - this.loadBadges(); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -163,7 +105,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(".BE-badge").forEach(node=>{node.remove();}); + BDFDB.removeEles(".BE-badges"); BDFDB.unloadMessage(this); return true; @@ -172,114 +114,90 @@ module.exports = (Plugin, Api, Vendor) => { return false; } } - - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - BDFDB.addObserver(this, BDFDB.dotCN.memberswrap, {name:"userListObserver"}, {childList:true, subtree:true}); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver"}, {childList:true, subtree:true}); - this.loadBadges(); - } - } + // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; + processNameTag (instance, wrapper) { + if (!wrapper.classList || !instance || !instance.props) return; + else if (BDFDB.containsClass(wrapper, BDFDB.disCN.membernametag) && BDFDB.getData("showInMemberList", this, "settings")) { + this.addBadges(instance.props.user, wrapper, "list"); } - BDFDB.saveAllData(settings, this, "settings"); - this.updateBadges = true; - } - - loadBadges() { - document.querySelectorAll(".BE-badge").forEach(node=>{node.remove();}); - var settings = BDFDB.getAllData(this, "settings"); - if (settings.showInMemberList) { - for (let user of document.querySelectorAll(BDFDB.dotCN.member)) { - this.addBadges(user, "list", false, settings); - } - } - if (settings.showInChat) { - for (let user of document.querySelectorAll(BDFDB.dotCN.messagegroup)) { - var compact = document.querySelector(BDFDB.dotCN.messagegroup + BDFDB.dotCN.messagecompact); - if (!compact) { - this.addBadges(user, "chat", compact, settings); - } - else { - for (let message of document.querySelectorAll(BDFDB.dotCN.messagemarkup)) { - this.addBadges(message, "chat", compact, settings); - } - } - } - } - if (settings.showInPopout) { - for (let user of document.querySelectorAll(BDFDB.dotCN.userpopout)) { - this.addBadges(user.parentElement, "popout", false, settings); - } + else if (BDFDB.containsClass(wrapper, BDFDB.disCN.userpopoutheadertag) && BDFDB.getData("showInPopout", this, "settings")) { + wrapper = BDFDB.containsClass(wrapper, BDFDB.disCN.userpopoutheadertagwithnickname) && wrapper.previousSibling ? wrapper.previousSibling : wrapper; + this.addBadges(instance.props.user, wrapper, "popout"); } } - addBadges (wrapper, type, compact, settings = BDFDB.getAllData(this, "settings")) { - if (!wrapper) return; - - let user = compact ? BDFDB.getKeyInformation({"node":$(BDFDB.dotCN.messagegroup).has(wrapper)[0],"key":"message"}).author : BDFDB.getKeyInformation({"node":wrapper,"key":"user"}); - if (user && !user.bot) { - if (!this.requestedusers[user.id]) { - this.requestedusers[user.id] = [[wrapper,type]] - this.APIModule.get(this.DiscordConstants.Endpoints.USER_PROFILE(user.id)).then(result => { - let usercopy = Object.assign({},result.body.user); - if (result.body.premium_since) usercopy.flags += 256; - this.loadedusers[user.id] = usercopy; - for (let queredobj of this.requestedusers[user.id]) this.addToWrapper(queredobj[0], user.id, queredobj[1], settings); - }); - } - else if (!this.loadedusers[user.id]) { - this.requestedusers[user.id].push([wrapper,type]); - } - else { - this.addToWrapper(wrapper, user.id, type, settings); - } + processMessageUsername (instance, wrapper) { + let message = BDFDB.getReactValue(instance, "props.message"); + if (message) { + let username = wrapper.querySelector(BDFDB.dotCN.messageusername); + if (username && BDFDB.getData("showInChat", this, "settings")) this.addBadges(message.author, wrapper, "chat"); } } - addToWrapper (wrapper, id, type, settings) { - if (wrapper.querySelector(".BE-badge")) return; - let memberwrap = wrapper.querySelector(BDFDB.dotCNC.memberusername + BDFDB.dotCNC.messageusernamewrapper + BDFDB.dotCN.nametag); - if (memberwrap) for (let flag in this.badges) { - if ((this.loadedusers[id].flags | flag) == this.loadedusers[id].flags) { - let badge = document.createElement("div"); - badge.className = "BE-badge BE-badge-" + this.badges[flag].name + " BE-badge-" + type; - badge.style.backgroundImage = settings.useColoredVersion ? this.badges[flag].color : this.badges[flag].white; - memberwrap.appendChild(badge); - $(badge) - .on("mouseenter." + this.name, (e) => { - BDFDB.createTooltip(this.badges[flag].name, e.currentTarget, {"type":"top"}); - }); - } + addBadges (info, wrapper, type) { + if (!info || info.bot || !wrapper) return; + if (!this.requestedusers[info.id]) { + this.requestedusers[info.id] = [[wrapper,type]]; + this.APIModule.get(this.DiscordConstants.Endpoints.USER_PROFILE(info.id)).then(result => { + let usercopy = Object.assign({},result.body.user); + if (result.body.premium_since) usercopy.flags += 2048; + this.loadedusers[info.id] = usercopy; + for (let queredobj of this.requestedusers[info.id]) this.addToWrapper(info, queredobj[0], queredobj[1]); + }); + } + else if (!this.loadedusers[info.id]) { + this.requestedusers[info.id].push([wrapper,type]); + } + else { + this.addToWrapper(info, wrapper, type); } } + addToWrapper (info, wrapper, type) { + BDFDB.removeEles(wrapper.querySelectorAll(".BE-badges")); + let badges = BDFDB.getAllData(this, "badges"); + let settings = BDFDB.getAllData(this, "settings"); + let header = BDFDB.getParentEle(BDFDB.dotCN.userpopoutheader, wrapper); + let badgewrapper = BDFDB.htmlToElement(``); + for (let flag in this.defaults.badges) { + if ((this.loadedusers[info.id].flags | flag) == this.loadedusers[info.id].flags && badges[flag]) { + let badge = BDFDB.htmlToElement(`
`); + badgewrapper.appendChild(badge); + badge.addEventListener("mouseenter", () => {BDFDB.createTooltip(this.defaults.badges[flag].name, badge, {"type":type == "list" ? "left" : "top"});}); + } + } + if (badgewrapper.firstChild) wrapper.insertBefore(badgewrapper, wrapper.querySelector(".owner-tag,.TRE-tag,svg[name=MobileDevice]")); + } + getSettingsPanel () { + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var settings = BDFDB.getAllData(this, "settings"); - var settingshtml = `
`; + var badges = BDFDB.getAllData(this, "badges"); + var settingshtml = `
${this.name}
`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; + } + settingshtml += `

Display Badges:

`; + for (let flag in badges) { + settingshtml += `

${this.defaults.badges[flag].name}

`; } - settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + settingshtml += `
`; - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); + let settingspanel = BDFDB.htmlToElement(settingshtml); + + BDFDB.initElements(settingspanel, this); return settingspanel; } onSettingsClosed () { - if (this.updateBadges) { - this.loadBadges(); - this.updateBadges = false; + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + BDFDB.WebModules.forceAllUpdates(this); } } } diff --git a/PluginsV2/BetterFriendCount/index.js b/PluginsV2/BetterFriendCount/index.js index ca74d8c2ad..0e986f41ec 100644 --- a/PluginsV2/BetterFriendCount/index.js +++ b/PluginsV2/BetterFriendCount/index.js @@ -3,10 +3,19 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { + this.patchModules = { + "TabBar":"componentDidMount", + "NameTag":["componentWillMount","componentWillUnmount"] + }; + this.css = ` - ${BDFDB.idCNS.friends+BDFDB.dotCNS.friendstabbaritem+BDFDB.dotCN.badge}:not(.betterfriendcount-badge) { + ${BDFDB.dotCNS.friends + BDFDB.dotCNS.settingstabbar + BDFDB.dotCN.badge}:not(.betterfriendcount-badge), + ${BDFDB.dotCNS.friends + BDFDB.dotCNS.settingstabbar + BDFDB.dotCN.badgewrapper}:not(.betterfriendcount-badge) { display: none !important; } + ${BDFDB.dotCNS.friends + BDFDB.dotCNS.settingstabbar + BDFDB.dotCN.badgewrapper}.betterfriendcount-badge { + margin-left: 5px !important; + } `; this.relationshipTypes = {}; @@ -32,48 +41,15 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.friendscolumn)) { - this.addCountNumbers(); - } - }); - } - if (change.removedNodes) { - change.removedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.friendscolumn)) { - this.addCountNumbers(); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.idCN.friends, {name:"friendListObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - this.addCountNumbers(); - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.friendsonline, {name:"friendCountObserver",instance:observer}, {childList:true, subtree:true, characterData:true}); - this.FriendUtils = BDFDB.WebModules.findByProperties("getFriendIDs", "getRelationships"); - this.UserMetaStore = BDFDB.WebModules.findByProperties("getStatuses", "getOnlineFriendCount"); - var RelationshipTypes = BDFDB.WebModules.findByProperties("RelationshipTypes").RelationshipTypes; - for (let type in RelationshipTypes) { - this.relationshipTypes[RelationshipTypes[type]] = type; - } - this.addCountNumbers(); + this.UserMetaStore = BDFDB.WebModules.findByProperties("getStatus", "getOnlineFriendCount"); + let RelationshipTypes = BDFDB.WebModules.findByProperties("RelationshipTypes").RelationshipTypes; + for (let type in RelationshipTypes) this.relationshipTypes[RelationshipTypes[type]] = type; + + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -85,7 +61,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(".betterfriendcount-badge").forEach(counter => {counter.remove();}); + BDFDB.removeEles(".betterfriendcount-badge"); BDFDB.unloadMessage(this); return true; @@ -94,30 +70,33 @@ module.exports = (Plugin, Api, Vendor) => { return false; } } - - onSwitch () { - this.addCountNumbers(); - - BDFDB.addObserver(this, BDFDB.idCN.friends, {name:"friendListObserver"}, {childList:true, subtree:true}); - } + // begin of own functions - addCountNumbers () { - var friendstabbar = document.querySelector(BDFDB.idCNS.friends + BDFDB.dotCN.friendstabbar); - if (!friendstabbar) return; - friendstabbar.querySelectorAll(".betterfriendcount-badge").forEach(counter => {counter.remove();}); + processTabBar (instance, wrapper) { + if (instance.props && instance.props.children && instance.props.children[0].key == "ADD_FRIEND") this.addCountNumbers(wrapper); + } - var relationships = this.FriendUtils.getRelationships(), relationshipCount = {}; - for (let type in this.relationshipTypes) {relationshipCount[this.relationshipTypes[type]] = 0;} - for (let id in relationships) {relationshipCount[this.relationshipTypes[relationships[id]]]++;} + processNameTag (instance, wrapper) { + if (wrapper.parentElement && BDFDB.containsClass(wrapper.parentElement, BDFDB.disCN.friendscolumn)) this.addCountNumbers(); + } - var tabitems = friendstabbar.querySelectorAll(BDFDB.dotCN.friendstabbaritem); - $(`
${relationshipCount.FRIEND}
`).appendTo(tabitems[1]); - $(`
${this.UserMetaStore.getOnlineFriendCount()}
`).appendTo(tabitems[2]); - $(`
${relationshipCount.PENDING_INCOMING}
`).appendTo(tabitems[3]); - $(`
${relationshipCount.PENDING_OUTGOING}
`).appendTo(tabitems[3]); - $(`
${relationshipCount.BLOCKED}
`).appendTo(tabitems[4]); + addCountNumbers (wrapper = document.querySelector(BDFDB.dotCNS.friends + BDFDB.dotCN.settingstabbar)) { + if (!wrapper) return; + let tabitems = wrapper.querySelectorAll(BDFDB.dotCN.settingsitem); + if (!tabitems || tabitems.length < 5) return; + BDFDB.removeEles(".betterfriendcount-badge"); + + let relationships = this.FriendUtils.getRelationships(), relationshipCount = {}; + for (let type in this.relationshipTypes) relationshipCount[this.relationshipTypes[type]] = 0; + for (let id in relationships) relationshipCount[this.relationshipTypes[relationships[id]]]++; + let badgeclass = BDFDB.disCN.badgewrapper; + tabitems[1].appendChild(BDFDB.htmlToElement(`
${relationshipCount.FRIEND}
`)); + tabitems[2].appendChild(BDFDB.htmlToElement(`
${this.UserMetaStore.getOnlineFriendCount()}
`)); + tabitems[3].appendChild(BDFDB.htmlToElement(`
${relationshipCount.PENDING_INCOMING}
`)); + tabitems[3].appendChild(BDFDB.htmlToElement(`
${relationshipCount.PENDING_OUTGOING}
`)); + tabitems[4].appendChild(BDFDB.htmlToElement(`
${relationshipCount.BLOCKED}
`)); } } }; diff --git a/PluginsV2/BetterNsfwTag/index.js b/PluginsV2/BetterNsfwTag/index.js index 2691a6d74d..9420eca5b5 100644 --- a/PluginsV2/BetterNsfwTag/index.js +++ b/PluginsV2/BetterNsfwTag/index.js @@ -3,25 +3,9 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { - this.css = ` - .nsfw-tag { - position: relative; - overflow: hidden; - padding: 1px 2px 1px 2px; - margin-left: 5px; - height: 13px; - border-radius: 3px; - text-transform: uppercase; - font-size: 12px; - font-weight: 500; - line-height: 14px; - white-space: nowrap; - color: rgb(240, 71, 71); - background-color: rgba(240, 71, 71, 0.0980392); - border: 1px solid rgba(240, 71, 71, 0.498039); - }`; - - this.tagMarkup = `NSFW`; + this.patchModules = { + "ChannelItem":"componentDidMount" + }; } onStart () { @@ -44,29 +28,10 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.classList && node.classList.contains(BDFDB.disCN.channelcontainerdefault)) { - this.checkChannel(node); - } - if (node && node.className && node.className.length > 0 && node.className.indexOf("container-") > -1) { - this.checkContainerForNsfwChannel(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.channels, {name:"channelListObserver",instance:observer}, {childList: true, subtree: true}); - - this.checkAllContainers(); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -78,7 +43,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - $(".nsfw-tag").remove(); + BDFDB.removeEles(".NSFW-tag"); BDFDB.unloadMessage(this); return true; @@ -88,33 +53,13 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - this.checkAllContainers(); - } - } - // begin of own functions - checkAllContainers () { - document.querySelectorAll(BDFDB.dotCNS.channels + "[class*=container-]").forEach(container => { - this.checkContainerForNsfwChannel(container); - }); - } - - checkContainerForNsfwChannel (container) { - container.querySelectorAll(BDFDB.dotCN.channelcontainerdefault).forEach(channel => { - this.checkChannel(channel); - }); - } - - checkChannel (channel) { - let channelData = BDFDB.getKeyInformation({"node":channel,"key":"channel"}); - if (channelData && channelData.nsfw == true) { - if (!channel.querySelector(".nsfw-tag")) { - $(this.tagMarkup).appendTo(channel.querySelector(BDFDB.dotCN.channelname)); - } + processChannelItem (instance, wrapper) { + if (instance.props && instance.props.channel && instance.props.channel.nsfw) { + let channelname = wrapper.querySelector(BDFDB.dotCN.channelname); + if (channelname) channelname.appendChild(BDFDB.htmlToElement(`NSFW`)); } } } diff --git a/PluginsV2/BetterPageSearch/index.js b/PluginsV2/BetterPageSearch/index.js index 298d75bc8d..809e592101 100644 --- a/PluginsV2/BetterPageSearch/index.js +++ b/PluginsV2/BetterPageSearch/index.js @@ -3,6 +3,10 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { + this.patchModules = { + "SearchResults":["componentDidMount","componentDidUpdate"] + }; + this.css = ` .BSP-pagination-button { background: url('data:image/svg+xml; utf8, ') 50%/9px 12px no-repeat; @@ -20,7 +24,6 @@ module.exports = (Plugin, Api, Vendor) => { border: 1px solid hsla(0,0%,100%,.16); } .BSP-pagination-button.BSP-pagination-first { - -webkit-transform: rotate(180deg); margin-right: 10px; transform: rotate(180deg); } @@ -28,11 +31,15 @@ module.exports = (Plugin, Api, Vendor) => { margin-left: 10px; margin-right: 10px; } + .BSP-pagination-button.BSP-pagination-jump { + margin-left: 10px; + transform: rotate(90deg); + } .BSP-pagination-button${BDFDB.dotCN.searchresultspaginationdisabled} { cursor: default; opacity: .3; } - .BSP-pagination-button:not(${BDFDB.dotCN.searchresultspaginationdisabled}):hover { + .BSP-pagination-button${BDFDB.notCN.searchresultspaginationdisabled}:hover { opacity: 1; } `; @@ -66,46 +73,12 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - BDFDB.loadMessage(this); + if (this.started) return true; + BDFDB.loadMessage(this); this.SearchNavigation = BDFDB.WebModules.findByProperties("searchNextPage","searchPreviousPage"); - this.SearchUtils = BDFDB.WebModules.findByProperties("getCurrentSearchId"); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.classList.contains(BDFDB.disCN.searchresultswrap)) { - BDFDB.addObserver(this, node, {name:"searchResultsObserver"}, {childList:true, subtree:true}); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCNS.chat + BDFDB.dotCN.chatcontent, {name:"chatContentObserver",instance:observer}, {childList:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - let pagination = null; - if (node && node.tagName && (pagination = node.querySelector(BDFDB.dotCN.searchresultspagination)) != null) { - this.addNewControls(pagination); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCNS.searchresultswrap, {name:"searchResultsObserver",instance:observer}, {childList:true, subtree:true}); - - let pagination = document.querySelector(BDFDB.dotCNS.searchresultswrap + BDFDB.dotCNS.searchresultspagination); - if (pagination) this.addNewControls(pagination); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -117,7 +90,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(".BSP-pagination, .BSP-pagination-button, .BSP-pagination-jumpinput").forEach(ele => {ele.remove();}); + BDFDB.removeEles(".BSP-pagination",".BSP-pagination-button",".BSP-pagination-jumpinput"); BDFDB.unloadMessage(this); return true; @@ -127,35 +100,21 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - BDFDB.addObserver(this, BDFDB.dotCNS.chat + BDFDB.dotCN.chatcontent, {name:"chatContentObserver"}, {childList:true}); - BDFDB.addObserver(this, BDFDB.dotCNS.searchresultswrap, {name:"searchResultsObserver"}, {childList:true, subtree:true}); - let pagination = document.querySelector(BDFDB.dotCNS.searchresultswrap + BDFDB.dotCNS.searchresultspagination); - if (pagination) this.addNewControls(pagination); - } - // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); + processSearchResults (instance, wrapper) { + if (instance.props && instance.props.searchId) this.addNewControls(wrapper.querySelector(BDFDB.dotCN.searchresultspagination), instance.props.searchId); } - addNewControls (pagination) { - if (!pagination || document.querySelector(".BSP-pagination, .BSP-pagination-button, .BSP-pagination-jumpinput")) return; - let searchResults = document.querySelector(BDFDB.dotCN.searchresults); - let searchID = this.SearchUtils.getCurrentSearchId(); - if (!searchResults || !searchID) return; + addNewControls (pagination, searchId) { + if (!pagination || !searchId || document.querySelector(".BSP-pagination, .BSP-pagination-button, .BSP-pagination-jumpinput")) return; + let searchResultsWrapper = BDFDB.getParentEle(BDFDB.dotCN.searchresultswrapper, pagination); + if (!searchResultsWrapper) return; let currentpage, maxpage; for (let word of pagination.textContent.split(" ")) { let number = parseInt(word.replace(/\./g,"")); - if (!isNaN(number) && !currentpage) { - currentpage = number; - } + if (!isNaN(number) && !currentpage) currentpage = number; else if (!isNaN(number)) { maxpage = number; break; @@ -169,102 +128,91 @@ module.exports = (Plugin, Api, Vendor) => { if (currentpage == 201) BDFDB.showToast("Discord doesn't allow you to go further than page 201.",{type:"error"}); maxpage = 201; } - if (currentpage == maxpage && maxpage == 201) pagination.querySelector(BDFDB.dotCN.searchresultspaginationnext).classList.add(BDFDB.disCN.searchresultspaginationdisabled); + if (currentpage == maxpage && maxpage == 201) BDFDB.addClass(pagination.querySelector(BDFDB.dotCN.searchresultspaginationnext), BDFDB.disCN.searchresultspaginationdisabled); let settings = BDFDB.getAllData(this, "settings"); + for (let btn of pagination.querySelectorAll(BDFDB.dotCNC.searchresultspaginationprevious + BDFDB.dotCN.searchresultspaginationnext)) BDFDB.addClass(btn, "pagination-button"); if (settings.addFirstLast) { - let BSPpaginatonFirst = document.createElement("div"); - BSPpaginatonFirst.className = "BSP-pagination-button BSP-pagination-first"; - if (currentpage == 1) BSPpaginatonFirst.classList.add(BDFDB.disCN.searchresultspaginationdisabled); - pagination.insertBefore(BSPpaginatonFirst, pagination.firstElementChild); - let BSPpaginatonLast = document.createElement("div"); - BSPpaginatonLast.className = "BSP-pagination-button BSP-pagination-last"; - if (currentpage == maxpage) BSPpaginatonLast.classList.add(BDFDB.disCN.searchresultspaginationdisabled); - pagination.appendChild(BSPpaginatonLast); + pagination.insertBefore(BDFDB.htmlToElement(`
`), pagination.firstElementChild); + pagination.appendChild(BDFDB.htmlToElement(`
`)); } if (settings.addJumpTo) { - let jumpInput = - $(`
- - - - - -
`)[0]; - pagination.appendChild(jumpInput); + pagination.appendChild(BDFDB.htmlToElement(`
`)); + pagination.appendChild(BDFDB.htmlToElement(`
`)); } BDFDB.initElements(pagination, this); if (settings.cloneToTheTop) { let BSPpaginaton = pagination.cloneNode(true); - BSPpaginaton.classList.add("BSP-pagination"); - searchResults.parentElement.insertBefore(BSPpaginaton, searchResults); + BDFDB.addClass(BSPpaginaton, "BSP-pagination"); + searchResultsWrapper.insertBefore(BSPpaginaton, searchResultsWrapper.firstElementChild); BDFDB.initElements(BSPpaginaton, this); } - $(searchResults.parentElement) - .off("click." + this.name).off("keyup." + this.name) - .on("click." + this.name, BDFDB.dotCN.searchresultspaginationprevious + BDFDB.dotCN.searchresultspaginationdisabled, (e) => { - e.preventDefault(); - e.stopPropagation(); - }) - .on("click." + this.name, BDFDB.dotCN.searchresultspaginationnext + BDFDB.dotCN.searchresultspaginationdisabled, (e) => { - e.preventDefault(); - e.stopPropagation(); - }) - .on("click." + this.name, ".BSP-pagination " + BDFDB.dotCN.searchresultspaginationprevious + ":not(" + BDFDB.dotCN.searchresultspaginationdisabled + ")", () => { - this.SearchNavigation.searchPreviousPage(searchID); - }) - .on("click." + this.name, ".BSP-pagination " + BDFDB.dotCN.searchresultspaginationnext + ":not(" + BDFDB.dotCN.searchresultspaginationdisabled + ")", () => { - this.SearchNavigation.searchNextPage(searchID); - }) - .on("click." + this.name, ".BSP-pagination-first:not(" + BDFDB.dotCN.searchresultspaginationdisabled + ")", () => { - for (let i = 0; currentpage - 1 - i > 0; i++) { - this.SearchNavigation.searchPreviousPage(searchID); + var doJump = (input) => { + let value = input.value; + if (value < 1 || value > maxpage) { + input.value = currentpage; + if (maxpage == 201 && value > maxpage) BDFDB.showToast("Discord doesn't allow you to go further than page 201.",{type:"error"}); + } + else if (value < currentpage) { + for (; currentpage - value > 0; value++) { + this.SearchNavigation.searchPreviousPage(searchId); } - }) - .on("click." + this.name, ".BSP-pagination-last:not(" + BDFDB.dotCN.searchresultspaginationdisabled + ")", () => { - for (let i = 0; maxpage - currentpage - i > 0; i++) { - this.SearchNavigation.searchNextPage(searchID); + } + else if (value > currentpage) { + for (; value - currentpage > 0; value--) { + this.SearchNavigation.searchNextPage(searchId); } - }) - .on("keyup." + this.name, ".BSP-pagination-jumpinput " + BDFDB.dotCN.inputmini, (e) => { - if (e.which == 13) { - let value = e.target.value; - if (value < 1 || value > maxpage) { - e.target.value = currentpage; - if (maxpage == 201 && value > maxpage) BDFDB.showToast("Discord doesn't allow you to go further than page 201.",{type:"error"}); - } - else if (value < currentpage) { - for (; currentpage - value > 0; value++) { - this.SearchNavigation.searchPreviousPage(searchID); - } - } - else if (value > currentpage) { - for (; value - currentpage > 0; value--) { - this.SearchNavigation.searchNextPage(searchID); - } - } - } - }); + } + }; + BDFDB.addEventListener(this, searchResultsWrapper, "click", BDFDB.dotCN.searchresultspaginationdisabled, e => { + e.preventDefault(); + e.stopPropagation(); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "click", `.BSP-pagination ${BDFDB.dotCN.searchresultspaginationprevious + BDFDB.notCN.searchresultspaginationdisabled}`, () => { + this.SearchNavigation.searchPreviousPage(searchId); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "click", `.BSP-pagination ${BDFDB.dotCN.searchresultspaginationnext + BDFDB.notCN.searchresultspaginationdisabled}`, () => { + this.SearchNavigation.searchNextPage(searchId); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "click", `.BSP-pagination-first${BDFDB.notCN.searchresultspaginationdisabled}`, () => { + for (let i = 0; currentpage - 1 - i > 0; i++) this.SearchNavigation.searchPreviousPage(searchId); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "click", `.BSP-pagination-last${BDFDB.notCN.searchresultspaginationdisabled}`, () => { + for (let i = 0; maxpage - currentpage - i > 0; i++) this.SearchNavigation.searchNextPage(searchId); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "click", `.BSP-pagination-jump${BDFDB.notCN.searchresultspaginationdisabled}`, e => { + doJump(e.currentTarget.parentElement.querySelector(`.BSP-pagination-jumpinput ${BDFDB.dotCN.inputmini}`)); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "keydown", `.BSP-pagination-jumpinput ${BDFDB.dotCN.inputmini}`, e => { + let label = e.currentTarget.getAttribute("aria-label"); + if (label) BDFDB.createTooltip(label, e.currentTarget, {type:"top"}); + }); + BDFDB.addEventListener(this, searchResultsWrapper, "mouseenter", `.pagination-button${BDFDB.notCN.searchresultspaginationdisabled}`, e => { + let label = e.currentTarget.getAttribute("aria-label"); + if (label) BDFDB.createTooltip(label, e.currentTarget, {type:"top"}); + }); } getSettingsPanel () { + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var settings = BDFDB.getAllData(this, "settings"); - var settingshtml = `
`; + var settingshtml = `
${this.name}
`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; } - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); + BDFDB.initElements(settingspanel, this); return settingspanel; } onSettingsClosed () { - document.querySelectorAll(".BSP-pagination, .BSP-pagination-button, .BSP-pagination-jumpinput").forEach(ele => {ele.remove();}); - let pagination = document.querySelector(BDFDB.dotCNS.searchresultswrap + BDFDB.dotCNS.searchresultspagination); - if (pagination) this.addNewControls(pagination); + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + BDFDB.removeEles(".BSP-pagination",".BSP-pagination-button",".BSP-pagination-jumpinput"); + BDFDB.WebModules.forceAllUpdates(this); + } } } }; diff --git a/PluginsV2/CharCounter/index.js b/PluginsV2/CharCounter/index.js index f1927cd91f..a21f59c4f5 100644 --- a/PluginsV2/CharCounter/index.js +++ b/PluginsV2/CharCounter/index.js @@ -3,20 +3,44 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { - this.selecting = false; - - this.counterMarkup = `
`; + this.patchModules = { + "ChannelTextArea":"componentDidMount", + "Note":"componentDidMount", + "Modal":"componentDidMount" + }; + this.maxLenghts = { + normal: 2000, + edit: 2000, + form: 2000, + nickname: 32, + popout: 256, + profile: 256 + } + this.css = ` + ${BDFDB.dotCN.themelight} #charcounter { + color: #747f8d; + opacity: .7; + } + ${BDFDB.dotCN.themedark} #charcounter { + color: #ccc; + opacity: .5; + } + ${BDFDB.dotCNS.typing + BDFDB.dotCN.cooldownwrapper} { + margin-right: 64px; + } + .charcounter-added { + position: relative !important; + } #charcounter { display: block; position: absolute; - opacity: .5; z-index: 1000; pointer-events: none; } #charcounter.normal { - right: 0; + right: 0; bottom: -1.3em; } #charcounter.edit { @@ -24,8 +48,25 @@ module.exports = (Plugin, Api, Vendor) => { bottom: -1.3em; } #charcounter.form { - right: 0; + right: 0; bottom: -1.0em; + } + #charcounter.nickname { + right: 0 !important; + top: 0 !important; + } + #charcounter.popout { + right: 3px !important; + bottom: 1px !important; + font-size: 10px !important; + } + #charcounter.profile { + right: -5px !important; + bottom: 3px !important; + font-size: 12px !important; + } + ${BDFDB.dotCN.usernote} textarea:not(:focus) + #charcounter { + display: none; }`; } @@ -49,26 +90,10 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.textareainner + ":not(" + BDFDB.dotCN.textareainnerdisabled + ")")) { - this.appendCounter(node.querySelector("textarea")); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"textareaObserver",instance:observer}, {childList: true, subtree: true}); - - document.querySelectorAll("textarea").forEach(textarea => {this.appendCounter(textarea);}); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -81,8 +106,8 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - $("#charcounter").remove(); - $(".charcounter-added").removeClass("charcounter-added"); + BDFDB.removeEles(".charcounter"); + BDFDB.removeClasses("charcounter-added"); BDFDB.unloadMessage(this); return true; @@ -92,53 +117,52 @@ module.exports = (Plugin, Api, Vendor) => { } } + // begin of own functions - appendCounter (textarea) { - if (!textarea) return; - var textareaWrap = textarea.parentElement; - if (textareaWrap && !textareaWrap.querySelector("#charcounter")) { - var textareaInstance = BDFDB.getOwnerInstance({"node":textarea, "props":["handlePaste","saveCurrentText"], "up":true}); - if (textareaInstance && textareaInstance.props && textareaInstance.props.type) { - var counter = $(this.counterMarkup); - counter.addClass(textareaInstance.props.type).appendTo(textareaWrap); + processChannelTextArea (instance, wrapper) { + if (instance.props && instance.props.type && this.maxLenghts[instance.props.type]) this.appendCounter(wrapper.querySelector("textarea"), instance.props.type); + } - var updateCounter = () => { - var selection = textarea.selectionEnd - textarea.selectionStart == 0 ? "" : " (" + (textarea.selectionEnd - textarea.selectionStart) + ")"; - counter.text(BDFDB.getParsedLength(textarea.value) + "/2000" + selection); - } + processNote (instance, wrapper) { + this.appendCounter(wrapper.firstElementChild, BDFDB.containsClass(wrapper, BDFDB.disCN.usernotepopout) ? "popout" : (BDFDB.containsClass(wrapper, BDFDB.disCN.usernoteprofile) ? "profile" : null)); + } - textareaWrap.parentElement.classList.add("charcounter-added"); - $(textarea) - .off("keydown." + this.name + " click." + this.name) - .on("keydown." + this.name + " click." + this.name, e => { - setTimeout(() => { - updateCounter(); - },10); - }) - .off("mousedown." + this.name) - .on("mousedown." + this.name, e => { - this.selecting = true; - }); - $(document) - .off("mouseup." + this.name) - .on("mouseup." + this.name, e => { - if (this.selecting) { - this.selecting = false; - } - }) - .off("mousemove." + this.name) - .on("mousemove." + this.name, e => { - if (this.selecting) { - setTimeout(() => { - updateCounter(); - },10); - } - }); - - updateCounter(); - } + processModal (instance, wrapper) { + if (instance.props && instance.props.tag == "form") { + let reset = wrapper.querySelector(BDFDB.dotCN.reset); + if (reset && BDFDB.getInnerText(reset.firstElementChild) == BDFDB.LanguageStrings.RESET_NICKNAME) this.appendCounter(wrapper.querySelector(BDFDB.dotCN.inputdefault), "nickname"); } } + + appendCounter (input, type) { + if (!input || !type) return; + BDFDB.removeEles(input.parentElement.querySelectorAll("#charcounter")); + var counter = BDFDB.htmlToElement(`
`); + input.parentElement.appendChild(counter); + + var updateCounter = () => {counter.innerText = input.value.length + "/" + (this.maxLenghts[type] || 2000) + (input.selectionEnd - input.selectionStart == 0 ? "" : " (" + (input.selectionEnd - input.selectionStart) + ")");}; + + BDFDB.addClass(input.parentElement.parentElement, "charcounter-added"); + if (type == "nickname") input.setAttribute("maxlength", 32); + BDFDB.addEventListener(this, input, "keydown click", e => { + clearTimeout(input.charcountertimeout); + input.charcountertimeout = setTimeout(() => {updateCounter();},100); + }); + BDFDB.addEventListener(this, input, "mousedown", e => { + BDFDB.addEventListener(this, document, "mouseup", () => { + BDFDB.removeEventListener(this, document); + if (input.selectionEnd - input.selectionStart) setImmediate(() => {BDFDB.addEventListener(this, document, "click", () => { + input.selectionStart = 0; + input.selectionEnd = 0; + updateCounter(); + BDFDB.removeEventListener(this, document); + });}); + }); + BDFDB.addEventListener(this, document, "mousemove", () => {setTimeout(() => {updateCounter();},10);}); + }); + + updateCounter(); + } } }; diff --git a/PluginsV2/ChatAliases/index.js b/PluginsV2/ChatAliases/index.js index e3b242f0bd..4b3a1000fc 100644 --- a/PluginsV2/ChatAliases/index.js +++ b/PluginsV2/ChatAliases/index.js @@ -3,7 +3,11 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { - this.configstypes = ["case","exact","autoc","regex","file"]; + this.patchModules = { + "ChannelTextArea":"componentDidMount" + }; + + this.configs = ["case","exact","autoc","regex","file"]; this.defaults = { settings: { @@ -32,41 +36,20 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); this.UploadModule = BDFDB.WebModules.findByProperties("instantBatchUpload"); this.CurrentUserPerms = BDFDB.WebModules.findByProperties("getChannelPermissions", "can"); this.Permissions = BDFDB.WebModules.findByProperties("Permissions", "ActivityTypes").Permissions; - var observer = null; + this.aliases = BDFDB.loadAllData(this, "words"); - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.textareainner + ":not(" + BDFDB.dotCN.textareainnerdisabled + ")")) { - this.bindEventToTextArea(node.querySelector("textarea")); - } - }); - } - } - ); + BDFDB.addEventListener(document, "click", e => { + if (!e.target.tagName === "TEXTAREA") BDFDB.removeEles(".autocompleteAliases", ".autocompleteAliasesRow"); }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"textareaObserver",instance:observer}, {childList: true, subtree:true}); - // PATCH OLD DATA REMOVE SOON - let aliases = BDFDB.loadAllData(this, "words"); - for (let alias in aliases) { - aliases[alias].autoc = aliases[alias].autoc == undefined ? !aliases[alias].regex : aliases[alias].autoc; - } - BDFDB.saveAllData(aliases, this, "words"); - - document.querySelectorAll("textarea" + BDFDB.dotCN.textarea).forEach(textarea => {this.bindEventToTextArea(textarea);}); - - $(document).off("click." + this.name).on("click." + this.name, (e) => { - if (!e.target.tagName === "TEXTAREA") $(".autocompleteAliases, .autocompleteAliasesRow").remove(); - }); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -78,7 +61,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - $(".autocompleteAliases, .autocompleteAliasesRow").remove(); + BDFDB.removeEles(".autocompleteAliases", ".autocompleteAliasesRow"); BDFDB.unloadMessage(this); return true; @@ -91,20 +74,9 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - - document.querySelectorAll("textarea" + BDFDB.dotCN.textarea).forEach(textarea => {this.bindEventToTextArea(textarea);}); - } - updateContainer (settingspanel, ele) { var update = false, wordvalue = null, replacevalue = null; var action = ele.getAttribute("action"); - var words = BDFDB.loadAllData(this, "words"); if (action == "add") { var wordinput = settingspanel.querySelector("#input-wordvalue"); @@ -124,7 +96,7 @@ module.exports = (Plugin, Api, Vendor) => { type: fileselection.files[0].type }); } - words[wordvalue] = { + this.aliases[wordvalue] = { replace: replacevalue, filedata: filedata, case: false, @@ -141,29 +113,28 @@ module.exports = (Plugin, Api, Vendor) => { else if (action == "remove") { wordvalue = ele.getAttribute("word"); if (wordvalue) { - delete words[wordvalue]; + delete this.aliases[wordvalue]; update = true; } } else if (action == "removeall") { if (confirm("Are you sure you want to remove all added Words from your list?")) { - words = {}; + this.aliases = {}; update = true; } } if (update) { - BDFDB.saveAllData(words, this, "words"); - words = BDFDB.loadAllData(this, "words"); + BDFDB.saveAllData(this.aliases, this, "words"); var containerhtml = ``; - for (let word in words) { - containerhtml += `
`; - for (let config of this.configstypes) { - containerhtml += `
`; + for (let word in this.aliases) { + containerhtml += `
`; + for (let config of this.configs) { + containerhtml += `
`; } containerhtml += `
`; } - $(settingspanel).find(".alias-list").html(containerhtml); + settingspanel.querySelector(".alias-list").innerHTML = containerhtml; BDFDB.initElements(settingspanel, this); } } @@ -172,9 +143,8 @@ module.exports = (Plugin, Api, Vendor) => { clearTimeout(ele.updateTimeout); ele.updateTimeout = setTimeout(() => { var card = ele.parentElement.parentElement; - var words = BDFDB.loadAllData(this, "words"); var oldwordvalue = ele.getAttribute("word"); - if (oldwordvalue && words[oldwordvalue]) { + if (oldwordvalue && this.aliases[oldwordvalue]) { var wordinput = card.querySelector(".word-name"); var replaceinput = card.querySelector(".replace-name"); var removebutton = card.querySelector(".remove-word"); @@ -185,46 +155,43 @@ module.exports = (Plugin, Api, Vendor) => { replaceinput.setAttribute("word", newwordvalue); replaceinput.setAttribute("value", newreplacevalue); removebutton.setAttribute("word", newwordvalue); - words[newwordvalue] = words[oldwordvalue]; - words[newwordvalue].replace = newreplacevalue; - if (newwordvalue != oldwordvalue) delete words[oldwordvalue]; - BDFDB.saveAllData(words, this, "words"); + this.aliases[newwordvalue] = this.aliases[oldwordvalue]; + this.aliases[newwordvalue].replace = newreplacevalue; + if (newwordvalue != oldwordvalue) delete this.aliases[oldwordvalue]; + BDFDB.saveAllData(this.aliases, this, "words"); } },500); } updateConfig (ele) { - var words = BDFDB.loadAllData(this, "words"); var wordvalue = ele.getAttribute("word"); var config = ele.getAttribute("config"); - if (wordvalue && words[wordvalue] && config) { - words[wordvalue][config] = ele.checked; - BDFDB.saveAllData(words, this, "words"); + if (wordvalue && this.aliases[wordvalue] && config) { + this.aliases[wordvalue][config] = ele.checked; + BDFDB.saveAllData(this.aliases, this, "words"); } } - toggleInfo (settingspanel, ele) { - ele.classList.toggle(BDFDB.disCN.categorywrappercollapsed); - ele.classList.toggle(BDFDB.disCN.categorywrapperdefault); + toggleInfo (ele) { + BDFDB.toggleClass(ele, BDFDB.disCN.categorywrappercollapsed); + BDFDB.toggleClass(ele, BDFDB.disCN.categorywrapperdefault); var svg = ele.querySelector(BDFDB.dotCN.categoryicontransition); - svg.classList.toggle(BDFDB.disCN.closed); - svg.classList.toggle(BDFDB.disCN.categoryiconcollapsed); - svg.classList.toggle(BDFDB.disCN.categoryicondefault); + BDFDB.toggleClass(svg, BDFDB.disCN.directionright); + BDFDB.toggleClass(svg, BDFDB.disCN.categoryiconcollapsed); + BDFDB.toggleClass(svg, BDFDB.disCN.categoryicondefault); - var visible = $(settingspanel).find(".info-container").is(":visible"); - $(settingspanel).find(".info-container").toggle(!visible); - BDFDB.saveData("hideInfo", visible, this, "hideInfo"); + BDFDB.toggleEles(ele.nextElementSibling); + BDFDB.saveData("hideInfo", BDFDB.isEleHidden(ele.nextElementSibling), this, "hideInfo"); } - bindEventToTextArea (textarea) { - if (!textarea) return; - var channelObj = BDFDB.getSelectedChannel(); - var channel = channelObj ? channelObj.data : null; - if (!channel) return; - var settings = BDFDB.getAllData(this, "settings"); - $(textarea) - .off("input." + this.name) - .on("input." + this.name, () => { + processChannelTextArea (instance, wrapper) { + if (instance.props && instance.props.type) { + var textarea = wrapper.querySelector("textarea"); + if (!textarea) return; + var channel = BDFDB.getSelectedChannel(); + if (!channel) return; + var settings = BDFDB.getAllData(this, "settings"); + BDFDB.addEventListener(this, textarea, "input", () => { if (this.format) { this.format = false; textarea.focus(); @@ -240,61 +207,48 @@ module.exports = (Plugin, Api, Vendor) => { } } } - }) - .off("keydown." + this.name) - .on("keydown." + this.name, e => { + }); + BDFDB.addEventListener(this, textarea, "keydown", e => { let autocompletemenu = textarea.parentElement.querySelector(BDFDB.dotCN.autocomplete); - if ((e.which == 9 || e.which == 13) && autocompletemenu) { - if (autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected).parentElement.classList.contains("autocompleteAliasesRow")) { - e.preventDefault(); - e.stopPropagation(); + if (autocompletemenu && (e.which == 9 || e.which == 13)) { + if (BDFDB.containsClass(autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected).parentElement, "autocompleteAliasesRow")) { + e.originalEvent.preventDefault(); + e.originalEvent.stopPropagation(); this.swapWordWithAlias(textarea); } } - else if ((e.which == 38 || e.which == 40) && autocompletemenu) { + else if (autocompletemenu && (e.which == 38 || e.which == 40)) { let autocompleteitems = autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselectable + ":not(.autocompleteAliasesSelector)"); let selected = autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected); - if (selected.classList.contains("autocompleteAliasesSelector") || autocompleteitems[e.which == 38 ? 0 : (autocompleteitems.length-1)] == selected) { - e.preventDefault(); - e.stopPropagation(); + if (BDFDB.containsClass(selected, "autocompleteAliasesSelector") || autocompleteitems[e.which == 38 ? 0 : (autocompleteitems.length-1)] == selected) { + e.originalEvent.preventDefault(); + e.originalEvent.stopPropagation(); let next = this.getNextSelection(autocompletemenu, null, e.which == 38 ? false : true); - selected.classList.remove(BDFDB.disCN.autocompleteselected); - next.classList.add(BDFDB.disCN.autocompleteselected); - if (!next.classList.contains("autocompleteAliasesSelector")) { - // if next element is a default discord autocomplete item, trigger the keypress again so the item is internally selected - var press = new KeyboardEvent("keypress", e); - Object.defineProperty(press, "keyCode", {value: e.which}); - Object.defineProperty(press, "which", {value: e.which}); - textarea.dispatchEvent(press); - } + BDFDB.removeClass(selected, BDFDB.disCN.autocompleteselected); + BDFDB.addClass(selected, BDFDB.disCN.autocompleteselector); + BDFDB.addClass(next, BDFDB.disCN.autocompleteselected); } } else if (textarea.value && !e.shiftKey && e.which == 13 && !autocompletemenu && textarea.value.indexOf("s/") != 0) { this.format = true; - $(textarea).trigger("input"); + textarea.dispatchEvent(new Event("input")); } - else if (!e.ctrlKey && settings.addAutoComplete && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) { - clearTimeout(textarea.chataliastimeout); - textarea.chataliastimeout = setTimeout(() => {this.addAutoCompleteMenu(textarea);},100); + else if (!e.ctrlKey && e.which != 16 && settings.addAutoComplete && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) { + clearTimeout(textarea.ChatAliasAutocompleteTimeout); + textarea.ChatAliasAutocompleteTimeout = setTimeout(() => {this.addAutoCompleteMenu(textarea);},100); } - if (!e.ctrlKey && e.which != 38 && e.which != 40) { - if (!(e.which == 39 && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length)) { - $(".autocompleteAliases, .autocompleteAliasesRow").remove(); - } - } - }) - .off("click." + this.name) - .on("click." + this.name, e => { - if (settings.addAutoComplete && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) { - setImmediate(() => {this.addAutoCompleteMenu(textarea);}); - } + if (!e.ctrlKey && e.which != 38 && e.which != 40 && !(e.which == 39 && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length)) BDFDB.removeEles(".autocompleteAliases", ".autocompleteAliasesRow"); }); + BDFDB.addEventListener(this, textarea, "click", e => { + if (settings.addAutoComplete && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) setImmediate(() => {this.addAutoCompleteMenu(textarea);}); + }); + } } addAutoCompleteMenu (textarea) { if (textarea.parentElement.querySelector(".autocompleteAliasesRow")) return; - let words = textarea.value.split(" "); + let words = textarea.value.split(/\s/); let lastword = words[words.length-1].trim(); if (words.length == 1 && BDFDB.isPluginEnabled("WriteUpperCase")) { let first = lastword.charAt(0); @@ -306,48 +260,47 @@ module.exports = (Plugin, Api, Vendor) => { } } if (lastword) { - let aliases = BDFDB.loadAllData(this, "words"), matchedaliases = {}; - for (let alias in aliases) { - let aliasdata = aliases[alias]; + let matchedaliases = {}; + for (let word in this.aliases) { + let aliasdata = this.aliases[word]; if (!aliasdata.regex && aliasdata.autoc) { if (aliasdata.exact) { - if (aliasdata.case && alias.indexOf(lastword) == 0) matchedaliases[alias] = aliasdata; - else if (!aliasdata.case && alias.toLowerCase().indexOf(lastword.toLowerCase()) == 0) matchedaliases[alias] = aliasdata; + if (aliasdata.case && word.indexOf(lastword) == 0) matchedaliases[word] = aliasdata; + else if (!aliasdata.case && word.toLowerCase().indexOf(lastword.toLowerCase()) == 0) matchedaliases[word] = aliasdata; } else { - if (aliasdata.case && alias.indexOf(lastword) > -1) matchedaliases[alias] = aliasdata; - else if (!aliasdata.case && alias.toLowerCase().indexOf(lastword.toLowerCase()) > -1) matchedaliases[alias] = aliasdata; + if (aliasdata.case && word.indexOf(lastword) > -1) matchedaliases[word] = aliasdata; + else if (!aliasdata.case && word.toLowerCase().indexOf(lastword.toLowerCase()) > -1) matchedaliases[word] = aliasdata; } } } if (!BDFDB.isObjectEmpty(matchedaliases)) { let autocompletemenu = textarea.parentElement.querySelector(BDFDB.dotCNS.autocomplete + BDFDB.dotCN.autocompleteinner), amount = 15; if (!autocompletemenu) { - autocompletemenu = $(`
`)[0]; + autocompletemenu = BDFDB.htmlToElement(`
`); textarea.parentElement.appendChild(autocompletemenu); autocompletemenu = autocompletemenu.firstElementChild; } else { amount -= autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselectable).length; } + let autocompleterowheader = BDFDB.htmlToElement(`
Aliases: ${BDFDB.encodeToHTML(lastword)}
`); + autocompletemenu.appendChild(autocompleterowheader); + BDFDB.addEventListener(this, autocompletemenu, "mouseenter", BDFDB.dotCN.autocompleteselectable, e => { + var selected = autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselected); + BDFDB.removeClass(selected, BDFDB.disCN.autocompleteselected); + BDFDB.addClass(selected, BDFDB.disCN.autocompleteselector); + BDFDB.addClass(e.currentTarget, BDFDB.disCN.autocompleteselected); + }); - $(autocompletemenu) - .append(`
Aliases: ${BDFDB.encodeToHTML(lastword)}
`) - .off("mouseenter." + this.name).on("mouseenter." + this.name, BDFDB.dotCN.autocompleteselectable, (e) => { - autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselected).forEach(selected => {selected.classList.remove(BDFDB.disCN.autocompleteselected);}); - e.currentTarget.classList.add(BDFDB.disCN.autocompleteselected); - }); - - for (let alias in matchedaliases) { + for (let word in matchedaliases) { if (amount-- < 1) break; - $(`
${BDFDB.encodeToHTML(alias)}
${BDFDB.encodeToHTML(matchedaliases[alias].replace)}
`) - .appendTo(autocompletemenu) - .off("click." + this.name).on("click." + this.name, BDFDB.dotCN.autocompleteselectable, (e) => { - this.swapWordWithAlias(textarea); - }); + let autocompleterow = BDFDB.htmlToElement(`
${BDFDB.encodeToHTML(word)}
${BDFDB.encodeToHTML(matchedaliases[word].replace)}
`); + autocompleterow.querySelector(BDFDB.dotCN.autocompleteselectable).addEventListener("click", () => {this.swapWordWithAlias(textarea);}); + autocompletemenu.appendChild(autocompleterow); } if (!autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected)) { - autocompletemenu.querySelector(".autocompleteAliasesRow " + BDFDB.dotCN.autocompleteselectable).classList.add(BDFDB.disCN.autocompleteselected); + BDFDB.addClass(autocompletemenu.querySelector(".autocompleteAliasesRow " + BDFDB.dotCN.autocompleteselectable), BDFDB.disCN.autocompleteselected); } } } @@ -370,7 +323,7 @@ module.exports = (Plugin, Api, Vendor) => { let aliasword = textarea.parentElement.querySelector(".autocompleteAliasesRow " + BDFDB.dotCN.autocompleteselected + " .aliasword").innerText; let lastword = textarea.parentElement.querySelector(".autocompleteAliasesRow .lastword").innerText; if (aliasword && lastword) { - $(".autocompleteAliases, .autocompleteAliasesRow").remove(); + BDFDB.removeEles(".autocompleteAliases", ".autocompleteAliasesRow"); textarea.focus(); textarea.selectionStart = textarea.value.length - lastword.length; textarea.selectionEnd = textarea.value.length; @@ -381,23 +334,25 @@ module.exports = (Plugin, Api, Vendor) => { } formatText (text) { - var newText = [], files = [], wordAliases = {}, multiAliases = {}, aliases = BDFDB.loadAllData(this, "words"); - for (let alias in aliases) { - if (!aliases[alias].regex && alias.indexOf(" ") == -1) wordAliases[alias] = aliases[alias]; - else multiAliases[alias] = aliases[alias]; + text = text.replace(/([\n\t\r])/g, " $1 "); + var newText = [], files = [], wordAliases = {}, multiAliases = {}; + for (let word in this.aliases) { + if (!this.aliases[word].regex && word.indexOf(" ") == -1) wordAliases[word] = this.aliases[word]; + else multiAliases[word] = this.aliases[word]; } for (let word of text.trim().split(" ")) { newText.push(this.useAliases(word, wordAliases, files, true)); } newText = newText.length == 1 ? newText[0] : newText.join(" "); + newText = newText.replace(/ ([\n\t\r]) /g, "$1"); newText = this.useAliases(newText, multiAliases, files, false); return {text:newText, files}; } useAliases (string, aliases, files, singleword) { - for (let alias in aliases) { - let aliasdata = aliases[alias]; - let escpAlias = aliasdata.regex ? alias : BDFDB.regEscape(alias); + for (let word in aliases) { + let aliasdata = aliases[word]; + let escpAlias = aliasdata.regex ? word : BDFDB.regEscape(word); let result = true, replaced = false, tempstring1 = string, tempstring2 = ""; let regstring = aliasdata.exact ? "^" + escpAlias + "$" : escpAlias; while (result != null) { @@ -405,7 +360,7 @@ module.exports = (Plugin, Api, Vendor) => { if (result) { replaced = true; let replace = aliasdata.file ? "" : BDFDB.insertNRST(aliasdata.replace); - if (result.length > 1) for (var i = 1; i < result.length; i++) replace = replace.replace(new RegExp("\\\\" + i, "g"), result[i]); + if (result.length > 1) for (var i = 1; i < result.length; i++) replace = replace.replace(new RegExp("\\\\" + i + "|\\$" + i, "g"), result[i]); tempstring2 += tempstring1.slice(0, result.index + result[0].length).replace(result[0], replace); tempstring1 = tempstring1.slice(result.index + result[0].length); if (aliasdata.file && typeof aliasdata.filedata == "string") { @@ -414,9 +369,7 @@ module.exports = (Plugin, Api, Vendor) => { } if (aliasdata.regex && regstring.indexOf("^") == 0) result = null; } - if (!result) { - tempstring2 += tempstring1; - } + if (!result) tempstring2 += tempstring1; } if (replaced) { string = tempstring2; @@ -426,55 +379,50 @@ module.exports = (Plugin, Api, Vendor) => { return string; } - replaceWord (string, regex) { - let result = regex.exec(string), rest = ""; - if (result) { - rest = string.slice(a.indexOf(b)+b.length); - } - } - getSettingsPanel () { - var settings = BDFDB.getAllData(this, "settings"); - var words = BDFDB.loadAllData(this, "words"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + var settings = BDFDB.getAllData(this, "settings"); + var settingshtml = `
${this.name}
`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; } settingshtml += `

Replace:

With:

`; - settingshtml += `

List of Chataliases:

`; - for (let config of this.configstypes) { + settingshtml += `

List of Chataliases:

`; + for (let config of this.configs) { settingshtml += `
${config.toUpperCase()}
`; } settingshtml += `
`; - for (let word in words) { - settingshtml += `
`; - for (let config of this.configstypes) { - settingshtml += `
`; - console.log(); + for (let word in this.aliases) { + settingshtml += `
`; + for (let config of this.configs) { + settingshtml += `
`; } settingshtml += `
`; } settingshtml += `
`; settingshtml += `

Remove all added words.

`; var infoHidden = BDFDB.loadData("hideInfo", this, "hideInfo"); - settingshtml += `
Information
`; - settingshtml += `
Case: Will replace words while comparing lowercase/uppercase. apple => apple, not APPLE or AppLe
Not Case: Will replace words while ignoring lowercase/uppercase. apple => apple, APPLE and AppLe
Exact: Will replace words that are exactly the replaceword. apple to pear => applepie stays applepie
Not Exact: Will replace words anywhere they appear. apple to pear => applepieapple to pearpiepear
Autoc: Will appear in the Autocomplete Menu (if enabled).
Regex: Will treat the entered wordvalue as a regular expression. Help
File: If the replacevalue is a filepath it will try to upload the file located at the filepath.
`; + settingshtml += `
Information
`; + settingshtml += `
Case: Will replace words while comparing lowercase/uppercase. apple => apple, not APPLE or AppLe
Not Case: Will replace words while ignoring lowercase/uppercase. apple => apple, APPLE and AppLe
Exact: Will replace words that are exactly the replaceword. apple to pear => applepie stays applepie
Not Exact: Will replace words anywhere they appear. apple to pear => applepieapple to pearpiepear
Autoc: Will appear in the Autocomplete Menu (if enabled).
Regex: Will treat the entered wordvalue as a regular expression. Help
File: If the replacevalue is a filepath it will try to upload the file located at the filepath.
`; settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) - .on("keypress", ".wordInputs", (e) => {if (e.which == 13) this.updateContainer(settingspanel, e.currentTarget);}) - .on("keyup", BDFDB.dotCN.gamenameinput, (e) => {this.updateWord(e.currentTarget);}) - .on("click", ".btn-addword, .remove-word, .remove-all", (e) => {this.updateContainer(settingspanel, e.currentTarget);}) - .on("click", BDFDB.dotCN.checkboxinput, (e) => {this.updateConfig(e.currentTarget);}) - .on("click", ".toggle-info", (e) => {this.toggleInfo(settingspanel, e.currentTarget);}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "keypress", ".wordInputs", e => {if (e.which == 13) this.updateContainer(settingspanel, e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "keyup", BDFDB.dotCN.gamenameinput, e => {this.updateWord(e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", ".btn-addword, .remove-word, .remove-all", e => {this.updateContainer(settingspanel, e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.checkboxinput, e => {this.updateConfig(e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", ".toggle-info", e => {this.toggleInfo(e.currentTarget);}); return settingspanel; } onSettingsClosed () { - document.querySelectorAll("textarea" + BDFDB.dotCN.textarea).forEach(textarea => {this.bindEventToTextArea(textarea);}); + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + BDFDB.WebModules.forceAllUpdates(this); + } } } }; diff --git a/PluginsV2/ChatFilter/index.js b/PluginsV2/ChatFilter/index.js index 4b0190ad2a..95deb4c0ea 100644 --- a/PluginsV2/ChatFilter/index.js +++ b/PluginsV2/ChatFilter/index.js @@ -3,18 +3,17 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { - this.configstypes = ["case","exact"]; + this.patchModules = { + "Message":["componentDidMount","componentDidUpdate"] + }; + + this.configs = ["empty","case","exact"]; this.css = ` - ${BDFDB.dotCNS.messagegroup + BDFDB.dotCNS.messagecomment + BDFDB.dotCN.messageaccessory}.blocked:not(.revealed), - ${BDFDB.dotCNS.messagegroup + BDFDB.dotCNS.messagecomment + BDFDB.dotCN.messagemarkup}.blocked:not(.revealed) { + ${BDFDB.dotCNS.messagegroup + BDFDB.dotCN.messageaccessory}.blocked:not(.revealed), + ${BDFDB.dotCNS.messagegroup + BDFDB.dotCN.messagemarkup}.blocked:not(.revealed) { font-weight: bold; font-style: italic; - } - - ${BDFDB.dotCNS.messagegroup + BDFDB.dotCNS.messagecomment + BDFDB.dotCN.messageaccessory}.censored:not(.revealed), - ${BDFDB.dotCNS.messagegroup + BDFDB.dotCNS.messagecomment + BDFDB.dotCN.messagemarkup}:not(.revealed) { - }`; this.defaults = { @@ -49,45 +48,10 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.type == "characterData") { - this.hideMessage(change.target.parentElement); - } - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if ($(node).attr("class") == BDFDB.disCN.message) this.hideMessage($(node).find(BDFDB.dotCN.messagemarkup)[0]); - }); - } - } - ); - }); - BDFDB.addObserver(this, null, {name:"messageChangeObserver",instance:observer,multi:true}, {childList:true, characterData:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.message)) { - BDFDB.addObserver(this, node, {name:"messageChangeObserver",multi:true}, {childList:true, characterData:true, subtree:true}); - node.querySelectorAll(BDFDB.dotCNC.messagemarkup + BDFDB.dotCN.messageaccessory).forEach(message => { - this.hideMessage(message); - }); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver",instance:observer}, {childList:true}); - - this.hideAllMessages(); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -99,9 +63,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(`${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored, ${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored`).forEach(message => { - this.resetMessage(message); - }); + document.querySelectorAll(`${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored, ${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored`).forEach(message => {this.resetMessage(message);}); BDFDB.unloadMessage(this); return true; @@ -111,20 +73,28 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - this.hideAllMessages(); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver"}, {childList:true, subtree:true}); - } - } - // begin of own functions updateContainer (settingspanel, ele) { - var update = false, wordvalue = null, replacevalue = null; - var action = ele.getAttribute("action"), rtype = ele.getAttribute("rtype"); - var words = BDFDB.loadData(rtype, this, "words") || {}; + var wordvalue = null, replacevalue = null, action = ele.getAttribute("action"), rtype = ele.getAttribute("rtype"), words = BDFDB.loadData(rtype, this, "words") || {}; + + var update = () => { + BDFDB.saveData(rtype, words, this, "words"); + + var containerhtml = ``; + for (let word in words) { + containerhtml += `
${BDFDB.encodeToHTML(word)} (${BDFDB.encodeToHTML(words[word].replace)})
` + for (let config of this.configs) { + containerhtml += `
`; + } + containerhtml += `
`; + } + containerhtml += `
`; + settingspanel.querySelector("." + rtype + "-list").innerHTML = containerhtml; + BDFDB.initElements(settingspanel, this); + this.SettingsUpdated = true; + }; if (action == "add") { var wordinput = settingspanel.querySelector("#input-" + rtype + "-wordvalue"); @@ -136,43 +106,28 @@ module.exports = (Plugin, Api, Vendor) => { replacevalue = replacevalue.trim(); words[wordvalue] = { replace: replacevalue, + empty: false, case: false, exact: true, - regex: false, + regex: false }; wordinput.value = null; replaceinput.value = null; - update = true; + update(); } } else if (action == "remove") { wordvalue = ele.getAttribute("word"); if (wordvalue) { delete words[wordvalue]; - update = true; + update(); } } else if (action == "removeall") { - if (confirm("Are you sure you want to remove all added Words from your list?")) { + BDFDB.openConfirmModal(this, "Are you sure you want to remove all added Words from your list?", () => { words = {}; - update = true; - } - } - if (update) { - BDFDB.saveData(rtype, words, this, "words"); - words = BDFDB.loadData(rtype, this, "words"); - - var containerhtml = ``; - for (let word in words) { - containerhtml += `
${BDFDB.encodeToHTML(word)} (${BDFDB.encodeToHTML(words[word].replace)})
` - for (let config of this.configstypes) { - containerhtml += `
`; - } - containerhtml += `
`; - } - containerhtml += `
`; - $(settingspanel).find("." + rtype + "-list").html(containerhtml); - BDFDB.initElements(settingspanel, this); + update(); + }); } } @@ -185,17 +140,6 @@ module.exports = (Plugin, Api, Vendor) => { } } - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - let key = input.getAttribute("value"); - let rtype = input.getAttribute("rtype"); - if (!settings[key]) settings[key] = {}; - settings[key][rtype] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - updateConfig (ele) { var wordvalue = ele.getAttribute("word"); var config = ele.getAttribute("config"); @@ -207,34 +151,25 @@ module.exports = (Plugin, Api, Vendor) => { } } - toggleInfo (settingspanel, ele) { - ele.classList.toggle(BDFDB.disCN.categorywrappercollapsed); - ele.classList.toggle(BDFDB.disCN.categorywrapperdefault); + toggleInfo (ele) { + BDFDB.toggleClass(ele, BDFDB.disCN.categorywrappercollapsed); + BDFDB.toggleClass(ele, BDFDB.disCN.categorywrapperdefault); var svg = ele.querySelector(BDFDB.dotCN.categoryicontransition); - svg.classList.toggle(BDFDB.disCN.closed); - svg.classList.toggle(BDFDB.disCN.categoryiconcollapsed); - svg.classList.toggle(BDFDB.disCN.categoryicondefault); + BDFDB.toggleClass(svg, BDFDB.disCN.directionright); + BDFDB.toggleClass(svg, BDFDB.disCN.categoryiconcollapsed); + BDFDB.toggleClass(svg, BDFDB.disCN.categoryicondefault); - var visible = $(settingspanel).find(".info-container").is(":visible"); - $(settingspanel).find(".info-container").toggle(!visible); - BDFDB.saveData("hideInfo", visible, this, "hideInfo"); + BDFDB.toggleEles(ele.nextElementSibling); + BDFDB.saveData("hideInfo", BDFDB.isEleHidden(ele.nextElementSibling), this, "hideInfo"); } - hideAllMessages () { - document.querySelectorAll(`${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored, ${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored`).forEach(message => { - this.resetMessage(message); - }); - document.querySelectorAll(BDFDB.dotCN.messagegroup).forEach(messageContainer => { - BDFDB.addObserver(this, messageContainer, {name:"messageChangeObserver",multi:true}, {childList:true, characterData:true, subtree:true}); - messageContainer.querySelectorAll(BDFDB.dotCNC.messagemarkup + BDFDB.dotCN.messageaccessory).forEach(message => { - this.hideMessage(message); - }); - }); + processMessage (instance, wrapper) { + wrapper.querySelectorAll(`${BDFDB.dotCNC.messagemarkup + BDFDB.dotCN.messageaccessory}`).forEach(message => {this.hideMessage(message);}); } hideMessage (message) { - if (!$(message).hasClass("blocked") && !$(message).hasClass("censored")) { - var orightml = $(message).html(); + if (message.tagName && !BDFDB.containsClass(message, "blocked", "censored", false)) { + var orightml = message.innerHTML; var newhtml = ""; if (orightml) { @@ -257,43 +192,43 @@ module.exports = (Plugin, Api, Vendor) => { var blockedWords = BDFDB.loadData("blocked", this, "words"); var blocked = false; for (let bWord in blockedWords) { - var blockedReplace = blockedWords[bWord].replace || replaces.blocked; + var blockedReplace = blockedWords[bWord].empty ? "" : (blockedWords[bWord].replace || replaces.blocked); var reg = this.createReg(bWord, blockedWords[bWord]); strings.forEach(string => { - let emojiname = this.getEmojiName(string); - if (emojiname && reg.test(emojiname)) blocked = true; + if (this.testForEmoji(string, reg)) blocked = true; else if (string.indexOf(' 0 ? string.split('src="')[1] : null; url = url ? url.split('"')[0] : null; if (reg.test(url)) blocked = true; } else if (string.indexOf("<") != 0) { - string.split(" ").forEach((word) => { - if (reg.test(word)) blocked = true; + string.replace(/\n/g, " \n ").split(" ").forEach((word) => { + let wordWithoutSpecial = word.replace(/[\?\\!\\.\"]/g, ""); + if (word && reg.test(word) || wordWithoutSpecial && reg.test(wordWithoutSpecial)) blocked = true; }); } }); if (blocked) break; } if (blocked) { - if (settings.hideMessage.blocked) $(message).hide(); + if (settings.hideMessage.blocked) BDFDB.toggleEles(message, false); newhtml = BDFDB.encodeToHTML(blockedReplace); - $(message) - .html(newhtml) - .addClass("blocked") - .data("newhtmlChatFilter",newhtml) - .data("orightmlChatFilter",orightml); + message.innerHTML = newhtml; + BDFDB.addClass(message, "blocked"); + message.ChatFilterOriginalHTML = orightml; + message.ChatFilterNewHTML = newhtml; this.addClickListener(message, settings.showMessageOnClick.blocked); } else { var censoredWords = BDFDB.loadData("censored", this, "words"); + var censored = false; for (let cWord in censoredWords) { - var censoredReplace = censoredWords[cWord].replace || replaces.censored; + var censoredReplace = censoredWords[cWord].empty ? "" : (censoredWords[cWord].replace || replaces.censored); var reg = this.createReg(cWord, censoredWords[cWord]); strings.forEach((string,i) => { - let emojiname = this.getEmojiName(string); - if (emojiname && reg.test(emojiname)) { + if (this.testForEmoji(string, reg)) { + censored = true; strings[i] = BDFDB.encodeToHTML(censoredReplace); if (strings[i+1] && strings[i+1].indexOf(" { var url = string.split('src="').length > 0 ? string.split('src="')[1] : null; url = url ? url.split('"')[0] : null; if (reg.test(url)) { + censored = true; strings = [BDFDB.encodeToHTML(censoredReplace)]; } } else if (string.indexOf("<") != 0) { var newstring = []; - string.split(" ").forEach((word) => { - newstring.push(reg.test(word) ? BDFDB.encodeToHTML(censoredReplace) : word); + string.replace(/\n/g, " \n ").split(" ").forEach((word) => { + let wordWithoutSpecial = word.replace(/[\?\\!\\.\"]/g, ""); + if (word && reg.test(word) || wordWithoutSpecial && reg.test(wordWithoutSpecial)) { + censored = true; + newstring.push(BDFDB.encodeToHTML(censoredReplace)); + } + else { + newstring.push(word); + } }); - strings[i] = newstring.join(" "); + strings[i] = newstring.join(" ").replace(/ \n /g, "\n"); } }); } - newhtml = strings.join(""); - - if (newhtml != orightml) { - $(message) - .html(newhtml) - .addClass("censored") - .data("newhtmlChatFilter",newhtml) - .data("orightmlChatFilter",orightml); + if (censored) { + newhtml = strings.join(""); + message.innerHTML = newhtml; + BDFDB.addClass(message, "censored"); + message.ChatFilterOriginalHTML = orightml; + message.ChatFilterNewHTML = newhtml; this.addClickListener(message, settings.showMessageOnClick.censored); } @@ -338,57 +279,57 @@ module.exports = (Plugin, Api, Vendor) => { return new RegExp(BDFDB.encodeToHTML(config.exact ? "^" + BDFDB.regEscape(word) + "$" : BDFDB.regEscape(word)), config.case ? "" : "i"); } - getEmojiName (string) { + testForEmoji (string, reg) { if (string.indexOf(" -1)) { - var emojiname = string.split('alt="').length > 0 ? string.split('alt="')[1] : null; - emojiname = emojiname ? emojiname.split('" src')[0] : null; - return emojiname = emojiname ? emojiname.replace(new RegExp(":", 'g'), "") : null; + var emojiname = string.split('alt="').length > 0 ? string.split('alt="')[1].split('"')[0] : null; + return emojiname = !emojiname ? false : (reg.test(emojiname) || reg.test(emojiname.replace(/:/g, ""))); } + return false; } resetMessage (message) { - $(message) - .html($(message).data("orightmlChatFilter")) - .off("click." + this.name) - .removeClass("blocked") - .removeClass("censored") - .removeClass("revealed"); + message.innerHTML = message.ChatFilterOriginalHTML; + BDFDB.removeClass(message, "blocked", "censored", "revealed"); + BDFDB.toggleEles(message, true); + delete message.ChatFilterOriginalHTML; + delete message.ChatFilterNewHTML; + message.removeEventListener("click", message.clickChatFilterListener); } - addClickListener (message, add) { - $(message) - .off("click." + this.name); - if (add) { - var orightml = $(message).data("orightmlChatFilter"); - var newhtml = $(message).data("newhtmlChatFilter"); - $(message) - .on("click." + this.name, () => { - if ($(message).hasClass("revealed")) { - $(message) - .html(newhtml) - .removeClass("revealed"); - } - else { - $(message) - .html(orightml) - .addClass("revealed"); - } - }); - + addClickListener (message, addListener) { + message.removeEventListener("click", message.clickChatFilterListener); + if (addListener) { + message.clickChatFilterListener = () => { + if (BDFDB.containsClass(message, "revealed")) { + BDFDB.removeClass(message, "revealed"); + message.innerHTML = message.ChatFilterNewHTML; + } + else { + BDFDB.addClass(message, "revealed"); + message.innerHTML = message.ChatFilterOriginalHTML; + } + }; + message.addEventListener("click", message.clickChatFilterListener); } } + getSettingsPanel () { + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var replaces = BDFDB.getAllData(this, "replaces"); var settings = BDFDB.getAllData(this, "settings"); - var settingshtml = `
`; + var settingshtml = `
${this.name}
`; for (let rtype in replaces) { var words = BDFDB.loadData(rtype, this, "words"); settingshtml += `

${this.defaults.replaces[rtype].title}

With:

`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + if (this.defaults.settings[key].enabled[rtype]) settingshtml += `

${this.defaults.settings[key].description}

`; } settingshtml += `

${this.defaults.replaces[rtype].description}

`; - settingshtml += `

List of ${rtype} Words:

CASE
EXACT
`; + settingshtml += `

List of ${rtype} Words:

`; + for (let config of this.configs) { + settingshtml += `
${config.toUpperCase()}
`; + } + settingshtml += `
`; for (let word in words) { settingshtml += `
${BDFDB.encodeToHTML(word)} (${BDFDB.encodeToHTML(words[word].replace)})
` for (let config of this.configs) { @@ -401,30 +342,29 @@ module.exports = (Plugin, Api, Vendor) => { settingshtml += `
`; } var infoHidden = BDFDB.loadData("hideInfo", this, "hideInfo"); - settingshtml += `
Information
`; - settingshtml += `
Case: Will block/censor words while comparing lowercase/uppercase. apple => apple, not APPLE or AppLe
Not Case: Will block/censor words while ignoring lowercase/uppercase. apple => apple, APPLE and AppLe
Exact: Will block/censor words that are exactly the selected word. apple => apple, not applepie or pineapple
Not Exact: Will block/censor all words containing the selected word. apple => apple, applepie and pineapple
`; + settingshtml += `
Information
`; + settingshtml += `
Case: Will block/censor words while comparing lowercase/uppercase. apple => apple, not APPLE or AppLe
Not Case: Will block/censor words while ignoring lowercase/uppercase. apple => apple, APPLE and AppLe
Exact: Will block/censor words that are exactly the selected word. apple => apple, not applepie or pineapple
Not Exact: Will block/censor all words containing the selected word. apple => apple, applepie and pineapple
Empty: Ignores the default and set replace word and removes the word/message instead.
`; settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) - .on("keypress", ".wordInputs", (e) => {if (e.which == 13) this.updateContainer(settingspanel, e.currentTarget);}) - .on("keyup", ".defaultInputs", (e) => {this.saveReplace(e.currentTarget);}) - .on("click", ".btn-addword, .remove-word, .remove-all", (e) => {this.updateContainer(settingspanel, e.currentTarget);}) - .on("click", BDFDB.dotCN.checkboxinput, (e) => {this.updateConfig(e.currentTarget);}) - .on("click", ".toggle-info", (e) => {this.toggleInfo(settingspanel, e.currentTarget);}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "keypress", ".wordInputs", e => {if (e.which == 13) this.updateContainer(settingspanel, e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "keyup", ".defaultInputs", e => {this.saveReplace(e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", ".btn-addword, .remove-word, .remove-all", e => {this.updateContainer(settingspanel, e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.checkboxinput, e => {this.updateConfig(e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", ".toggle-info", e => {this.toggleInfo(e.currentTarget);}); - for (let key in settings) { - for (let rtype in this.defaults.settings[key].enabled) { - if (!this.defaults.settings[key].enabled[rtype]) $(settingspanel).find(`${BDFDB.dotCN.flex}[value='${key}'][rtype='${rtype}']`).hide(); - } - } return settingspanel; } onSettingsClosed () { - this.hideAllMessages(); + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + document.querySelectorAll(`${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored, ${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored`).forEach(message => {this.resetMessage(message);}); + BDFDB.WebModules.forceAllUpdates(this); + } } } }; diff --git a/PluginsV2/CompleteTimestamps/index.js b/PluginsV2/CompleteTimestamps/index.js index bfaab80cea..f599272cb8 100644 --- a/PluginsV2/CompleteTimestamps/index.js +++ b/PluginsV2/CompleteTimestamps/index.js @@ -3,12 +3,12 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { + this.patchModules = { + "MessageGroup":["componentDidMount","componentDidUpdate"] + }; + this.languages; - this.updateTimestamps = false; - - this.compactWidth = null; - this.defaults = { settings: { showInChat: {value:true, description:"Replace Chat Timestamp with Complete Timestamp:"}, @@ -49,64 +49,37 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; + this.languages = Object.assign({"own":{name:"Own",id:"own",integrated:false,dic:false}},BDFDB.languages); - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.querySelector(BDFDB.dotCN.messagetext)) { - node.querySelectorAll(BDFDB.dotCN.messagetext).forEach(message => {this.changeTimestamp(message);}); - } - else if (node.classList && node.classList.contains(BDFDB.disCN.messagetext)) { - this.changeTimestamp(node); - } - }); - } - } - ); + BDFDB.addEventListener(this, document, "mouseenter", BDFDB.dotCNS.message + BDFDB.dotCN.messagecontent, e => { + if (BDFDB.getData("showOnHover", this, "settings")) { + let message = e.currentTarget; + let messagegroup = BDFDB.getParentEle(BDFDB.dotCN.messagegroup, message); + if (!messagegroup || !messagegroup.tagName) return; + let info = this.getMessageData(message, messagegroup); + if (!info || !info.timestamp || !info.timestamp._i) return; + let choice = BDFDB.getData("creationDateLang", this, "choices"); + BDFDB.createTooltip(this.getTimestamp(this.languages[choice].id, info.timestamp._i), message, {type:"left",selector:"completetimestamp-tooltip"}); + } + }); + BDFDB.addEventListener(this, document, "mouseenter", BDFDB.dotCNS.message + BDFDB.dotCN.messageedited, e => { + if (BDFDB.getData("changeForEdit", this, "settings")) { + let marker = e.currentTarget; + let time = marker.getAttribute("datetime"); + if (!time) return; + let choice = BDFDB.getData("creationDateLang", this, "choices"); + let customTooltipCSS = ` + body ${BDFDB.dotCN.tooltip}:not(.completetimestampedit-tooltip) { + display: none !important; + }`; + BDFDB.createTooltip(this.getTimestamp(this.languages[choice].id, time), marker, {type:"top",selector:"completetimestampedit-tooltip",css:customTooltipCSS}); + } }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"messageObserver",instance:observer}, {childList: true, subtree: true}); - this.languages = Object.assign({}, - {"own": {name:"Own", id:"own", integrated:false, dic:false}}, - BDFDB.languages - ); - - this.setMaxWidth(); - - $(document) - .on("mouseenter." + this.name, BDFDB.dotCNS.message + BDFDB.dotCNC.messagetext + BDFDB.dotCNS.message + BDFDB.dotCN.messageaccessory, (e) => { - if (BDFDB.getData("showOnHover", this, "settings")) { - var message = e.currentTarget; - var messagegroup = this.getMessageGroup(message); - if (!messagegroup || !messagegroup.tagName) return; - var info = this.getMessageData(message, messagegroup); - if (!info || !info.timestamp || !info.timestamp._i) return - var choice = BDFDB.getData("creationDateLang", this, "choices"); - BDFDB.createTooltip(this.getTimestamp(this.languages[choice].id, info.timestamp._i), message, {type:"left",selector:"completetimestamp-tooltip"}); - } - }) - .on("mouseenter." + this.name, BDFDB.dotCNS.message + BDFDB.dotCN.messageedited, (e) => { - if (BDFDB.getData("changeForEdit", this, "settings")) { - var marker = e.currentTarget; - var messagegroup = this.getMessageGroup(marker); - if (!messagegroup || !messagegroup.tagName) return; - var info = this.getMessageData(marker, messagegroup); - if (!info || !info.editedTimestamp || !info.editedTimestamp._i) return - var choice = BDFDB.getData("creationDateLang", this, "choices"); - var customTooltipCSS = ` - body ${BDFDB.dotCN.tooltip}:not(.completetimestampedit-tooltip) { - display: none !important; - }`; - BDFDB.createTooltip(this.getTimestamp(this.languages[choice].id, info.editedTimestamp._i), marker, {type:"top",selector:"completetimestampedit-tooltip",css:customTooltipCSS}); - } - }); - - document.querySelectorAll(BDFDB.dotCN.messagetext).forEach(message => {this.changeTimestamp(message);}); + BDFDB.WebModules.forceAllUpdates(); return true; } @@ -119,7 +92,10 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(".complete-timestamp").forEach(timestamp => {timestamp.classList.remove("complete-timestamp");}); + BDFDB.removeEles(".complete-timestamp-divider"); + BDFDB.removeClasses("complete-timestamp"); + + BDFDB.removeLocalStyle(this.name + "CompactCorrection"); BDFDB.unloadMessage(this); return true; @@ -132,18 +108,9 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - this.updateSettingsPanel(settingspanel); - } - saveInputs (settingspanel) { - var formats = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.input)) { + let formats = {}; + for (let input of settingspanel.querySelectorAll(BDFDB.dotCN.input)) { formats[input.getAttribute("option")] = input.value; } BDFDB.saveAllData(formats, this, "formats"); @@ -151,117 +118,116 @@ module.exports = (Plugin, Api, Vendor) => { } updateSettingsPanel (settingspanel) { - var choices = BDFDB.getAllData(this, "choices"); + let choices = BDFDB.getAllData(this, "choices"); for (let key in choices) { settingspanel.querySelector(`${BDFDB.dotCN.select}[option='${key}'] .languageTimestamp`).innerText = this.getTimestamp(this.languages[choices[key]].id); } - this.updateTimestamps = true; + this.SettingsUpdated = true; } - toggleInfo (settingspanel, ele) { - ele.classList.toggle(BDFDB.disCN.categorywrappercollapsed); - ele.classList.toggle(BDFDB.disCN.categorywrapperdefault); + toggleInfo (ele) { + BDFDB.toggleClass(ele, BDFDB.disCN.categorywrappercollapsed); + BDFDB.toggleClass(ele, BDFDB.disCN.categorywrapperdefault); var svg = ele.querySelector(BDFDB.dotCN.categoryicontransition); - svg.classList.toggle(BDFDB.disCN.closed); - svg.classList.toggle(BDFDB.disCN.categoryiconcollapsed); - svg.classList.toggle(BDFDB.disCN.categoryicondefault); + BDFDB.toggleClass(svg, BDFDB.disCN.directionright); + BDFDB.toggleClass(svg, BDFDB.disCN.categoryiconcollapsed); + BDFDB.toggleClass(svg, BDFDB.disCN.categoryicondefault); - var visible = $(settingspanel).find(".info-container").is(":visible"); - $(settingspanel).find(".info-container").toggle(!visible); - BDFDB.saveData("hideInfo", visible, this, "hideInfo"); + BDFDB.toggleEles(ele.nextElementSibling); + BDFDB.saveData("hideInfo", BDFDB.isEleHidden(ele.nextElementSibling), this, "hideInfo"); } openDropdownMenu (e) { - var selectControl = e.currentTarget; - var selectWrap = selectControl.parentElement; + let selectControl = e.currentTarget; + let selectWrap = selectControl.parentElement; + let plugincard = BDFDB.getParentEle("li", selectWrap); - if (selectWrap.classList.contains(BDFDB.disCN.selectisopen)) return; + if (!plugincard || BDFDB.containsClass(selectWrap, BDFDB.disCN.selectisopen)) return; - selectWrap.classList.add(BDFDB.disCN.selectisopen); - $("li").has(selectWrap).css("overflow", "visible"); + BDFDB.addClass(selectWrap, BDFDB.disCN.selectisopen); + plugincard.style.setProperty("overflow", "visible", "important"); - var selectMenu = this.createDropdownMenu(selectWrap.getAttribute("value")); + let selectMenu = this.createDropdownMenu(selectWrap.getAttribute("value")); selectWrap.appendChild(selectMenu); - $(selectMenu).on("mousedown." + this.name, BDFDB.dotCN.selectoption, (e2) => { - var language = e2.currentTarget.getAttribute("value"); + BDFDB.addChildEventListener(selectMenu, "mousedown", BDFDB.dotCN.selectoption, e2 => { + let language = e2.currentTarget.getAttribute("value"); selectWrap.setAttribute("value", language); selectControl.querySelector(".languageName").innerText = this.languages[language].name; selectControl.querySelector(".languageTimestamp").innerText = this.getTimestamp(this.languages[language].id); BDFDB.saveData(selectWrap.getAttribute("option"), language, this, "choices"); }); - $(document).on("mousedown.select" + this.name, (e2) => { - if (e2.target.parentElement == selectMenu) return; - $(document).off("mousedown.select" + this.name); - selectMenu.remove(); - $("li").has(selectWrap).css("overflow", "auto"); - setTimeout(() => {selectWrap.classList.remove(BDFDB.disCN.selectisopen);},100); - }); + + var removeMenu = e2 => { + if (e2.target.parentElement != selectMenu) { + document.removeEventListener("mousedown", removeMenu); + selectMenu.remove(); + plugincard.style.removeProperty("overflow"); + setTimeout(() => {BDFDB.removeClass(selectWrap, BDFDB.disCN.selectisopen);},100); + } + }; + + document.addEventListener("mousedown", removeMenu); } createDropdownMenu (choice) { - var menuhtml = `
`; - for (var key in this.languages) { - var isSelected = key == choice ? ` ${BDFDB.disCN.selectselected}` : ``; + let menuhtml = `
`; + for (let key in this.languages) { + let isSelected = key == choice ? ` ${BDFDB.disCN.selectselected}` : ``; menuhtml += `
${this.languages[key].name}
${this.getTimestamp(this.languages[key].id)}
` } menuhtml += `
`; - return $(menuhtml)[0]; + return BDFDB.htmlToElement(menuhtml); } - changeTimestamp (message) { - if (!message || !message.tagName || !BDFDB.getData("showInChat", this, "settings")) return; - var messagegroup = this.getMessageGroup(message); - if (!messagegroup || !messagegroup.tagName) return; - var compact = messagegroup.classList.contains(BDFDB.disCN.messagecompact); - var timestamp = compact ? message.querySelector(BDFDB.dotCN.messagetimestamp) : messagegroup.querySelector(BDFDB.dotCN.messagetimestamp); - if (!timestamp || !timestamp.tagName || timestamp.classList.contains("complete-timestamp")) return; - var info = this.getMessageData(message, messagegroup); - if (!info || !info.timestamp || !info.timestamp._i) return; - var choice = BDFDB.getData("creationDateLang", this, "choices"); - timestamp.classList.add("complete-timestamp"); - BDFDB.setInnerText(timestamp, this.getTimestamp(this.languages[choice].id, info.timestamp._i)); - if (compact && this.compactWidth) { - var markup = message.querySelector(BDFDB.dotCN.messagemarkup); - if (markup) { - var newpadding = 100 + (this.compactWidth - 65); - markup.style.paddingLeft = newpadding + "px"; - markup.style.textIndent = "-" + newpadding + "px"; - timestamp.style.width = this.compactWidth + "px"; - } + processMessageGroup (instance, wrapper) { + for (let stamp of wrapper.querySelectorAll("time[datetime]")) this.changeTimestamp(stamp); + } + + changeTimestamp (stamp) { + if (!stamp.className || stamp.className.toLowerCase().indexOf("timestamp") == -1 || BDFDB.containsClass(stamp, "complete-timestamp")) return; + let time = stamp.getAttribute("datetime"); + if (time) { + this.setMaxWidth(); + BDFDB.addClass(stamp, "complete-timestamp"); + let stampdivider = document.createElement("span"); + stampdivider.className = "complete-timestamp-divider arabic-fix"; + stampdivider.style.setProperty("display", "inline", "important"); + stampdivider.style.setProperty("height", "0px", "important"); + stampdivider.style.setProperty("width", "0px", "important"); + stampdivider.style.setProperty("font-size", "0px", "important"); + stampdivider.innerText = "ARABIC FIX"; + stamp.parentElement.insertBefore(stampdivider, stamp); + BDFDB.setInnerText(stamp, this.getTimestamp(this.languages[BDFDB.getData("creationDateLang", this, "choices")].id, time)); } } - getMessageGroup (message) { - var messagegroup = null; - while (messagegroup == null || message.parentElement) { - message = message.parentElement; - if (message.classList && message.classList.contains(BDFDB.disCN.messagegroup)) messagegroup = message; - } - return messagegroup; + getMessageData (div, messagegroup) { + let pos = Array.from(messagegroup.querySelectorAll("." + div.className.replace(/ /g, "."))).indexOf(div); + let instance = BDFDB.getReactInstance(messagegroup); + if (!instance) return; + let info = instance.return.stateNode.props.messages; + return info && pos > -1 ? info[pos] : null; } - getMessageData (message, messagegroup) { - var pos = $(messagegroup).find(BDFDB.dotCN.message).index($(messagegroup).find(BDFDB.dotCN.message).has(message)[0]); - var info = BDFDB.getKeyInformation({"node":message,"key":"messages","up":true,"time":1000}); - if (info && pos > -1) info = info[pos]; - return info; - } - - getTimestamp (languageid, time = new Date()) { - var settings = BDFDB.getAllData(this, "settings"), timestring = ""; + getTimestamp (languageid, time) { + let timeobj = time ? time : new Date(); + if (typeof time == "string") timeobj = new Date(time); + if (timeobj.toString() == "Invalid Date") timeobj = new Date(parseInt(time)); + if (timeobj.toString() == "Invalid Date") return; + let settings = BDFDB.getAllData(this, "settings"), timestring = ""; if (languageid != "own") { - var timestamp = []; - if (settings.displayDate) timestamp.push(time.toLocaleDateString(languageid)); - if (settings.displayTime) timestamp.push(settings.cutSeconds ? this.cutOffSeconds(time.toLocaleTimeString(languageid)) : time.toLocaleTimeString(languageid)); + let timestamp = []; + if (settings.displayDate) timestamp.push(timeobj.toLocaleDateString(languageid)); + if (settings.displayTime) timestamp.push(settings.cutSeconds ? this.cutOffSeconds(timeobj.toLocaleTimeString(languageid)) : timeobj.toLocaleTimeString(languageid)); if (settings.otherOrder) timestamp.reverse(); timestring = timestamp.length > 1 ? timestamp.join(", ") : (timestamp.length > 0 ? timestamp[0] : ""); if (timestring && settings.forceZeros) timestring = this.addLeadingZeros(timestring); } else { - var ownformat = BDFDB.getData("ownFormat", this, "formats"); + let ownformat = BDFDB.getData("ownFormat", this, "formats"); languageid = BDFDB.getDiscordLanguage().id; - var hour = time.getHours(), minute = time.getMinutes(), second = time.getSeconds(), msecond = time.getMilliseconds(), day = time.getDate(), month = time.getMonth()+1, timemode = ""; + let hour = timeobj.getHours(), minute = timeobj.getMinutes(), second = timeobj.getSeconds(), msecond = timeobj.getMilliseconds(), day = timeobj.getDate(), month = timeobj.getMonth()+1, timemode = ""; if (ownformat.indexOf("$timemode") > -1) { timemode = hour >= 12 ? "PM" : "AM"; hour = hour % 12; @@ -273,13 +239,13 @@ module.exports = (Plugin, Api, Vendor) => { .replace("$second", second < 10 ? "0" + second : second) .replace("$msecond", msecond) .replace("$timemode", timemode) - .replace("$weekdayL", time.toLocaleDateString(languageid,{weekday: "long"})) - .replace("$weekdayS", time.toLocaleDateString(languageid,{weekday: "short"})) - .replace("$monthnameL", time.toLocaleDateString(languageid,{month: "long"})) - .replace("$monthnameS", time.toLocaleDateString(languageid,{month: "short"})) + .replace("$weekdayL", timeobj.toLocaleDateString(languageid,{weekday: "long"})) + .replace("$weekdayS", timeobj.toLocaleDateString(languageid,{weekday: "short"})) + .replace("$monthnameL", timeobj.toLocaleDateString(languageid,{month: "long"})) + .replace("$monthnameS", timeobj.toLocaleDateString(languageid,{month: "short"})) .replace("$day", settings.forceZeros && day < 10 ? "0" + day : day) .replace("$month", settings.forceZeros && month < 10 ? "0" + month : month) - .replace("$year", time.getFullYear()); + .replace("$year", timeobj.getFullYear()); } return timestring; } @@ -289,9 +255,9 @@ module.exports = (Plugin, Api, Vendor) => { } addLeadingZeros (timestring) { - var chararray = timestring.split(""); - var numreg = /[0-9]/; - for (var i = 0; i < chararray.length; i++) { + let chararray = timestring.split(""); + let numreg = /[0-9]/; + for (let i = 0; i < chararray.length; i++) { if (!numreg.test(chararray[i-1]) && numreg.test(chararray[i]) && !numreg.test(chararray[i+1])) chararray[i] = "0" + chararray[i]; } @@ -299,51 +265,71 @@ module.exports = (Plugin, Api, Vendor) => { } setMaxWidth () { - var wrapper = $(`
`); - var timestamp = wrapper.find(BDFDB.dotCN.messagetimestamp); - var choice = BDFDB.getData("creationDateLang", this, "choices"); - $(wrapper).appendTo(document.body); - this.compactWidth = timestamp.css("width", "auto").text(this.getTimestamp(this.languages[choice].id, new Date(253402124399995))).outerWidth(); - wrapper.remove(); + if (this.currentMode != BDFDB.getDiscordMode()) { + this.currentMode = BDFDB.getDiscordMode(); + let timestamp = document.querySelector(BDFDB.dotCN.messagetimestampcompact); + if (timestamp) { + let choice = BDFDB.getData("creationDateLang", this, "choices"); + let testtimestamp = BDFDB.htmlToElement(``); + document.body.appendChild(testtimestamp); + let width = BDFDB.getRects(testtimestamp).width + 5; + testtimestamp.remove(); + BDFDB.appendLocalStyle(this.name + "CompactCorrection", ` + ${BDFDB.dotCN.messagetimestampcompact} { + width: ${width}px !important; + } + ${BDFDB.dotCN.messagetimestampcompactismentioned} { + width: ${width + 2}px !important; + } + ${BDFDB.dotCN.messagemarkupiscompact} { + margin-left: ${width}px !important; + text-indent: -${width}px !important; + } + ${BDFDB.dotCN.messageaccessorycompact} { + padding-left: ${width}px !important; + } + `); + } + else BDFDB.removeLocalStyle(this.name + "CompactCorrection"); + } } getSettingsPanel () { - var settings = BDFDB.getAllData(this, "settings"); - var choices = BDFDB.getAllData(this, "choices"); - var formats = BDFDB.getAllData(this, "formats"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + let settings = BDFDB.getAllData(this, "settings"); + let choices = BDFDB.getAllData(this, "choices"); + let formats = BDFDB.getAllData(this, "formats"); + let settingshtml = `
${this.name}
`; + for (let key in settings) { + settingshtml += `

${this.defaults.settings[key].description}

`; + } for (let key in choices) { settingshtml += `

${this.defaults.choices[key].description}

${this.languages[choices[key]].name}
${this.getTimestamp(this.languages[choices[key]].id)}
`; } for (let key in formats) { settingshtml += `

${this.defaults.formats[key].description}

`; } - for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; - } - var infoHidden = BDFDB.loadData("hideInfo", this, "hideInfo"); - settingshtml += `
Information
`; + let infoHidden = BDFDB.loadData("hideInfo", this, "hideInfo"); + settingshtml += `
Information
`; settingshtml += `
`; settingshtml += `
$hour will be replaced with the current hour
$minute will be replaced with the current minutes
$second will be replaced with the current seconds
$msecond will be replaced with the current milliseconds
$timemode will change $hour to a 12h format and will be replaced with AM/PM
$year will be replaced with the current year
$month will be replaced with the current month
$day will be replaced with the current day
$monthnameL will be replaced with the monthname in long format based on the Discord Language
$monthnameS will be replaced with the monthname in short format based on the Discord Language
$weekdayL will be replaced with the weekday in long format based on the Discord Language
$weekdayS will be replaced with the weekday in short format based on the Discord Language
`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); + BDFDB.initElements(settingspanel, this); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) - .on("keyup", BDFDB.dotCN.input, () => {this.saveInputs(settingspanel);}) - .on("click", BDFDB.dotCN.selectcontrol, (e) => {this.openDropdownMenu(e);}) - .on("click", ".toggle-info", (e) => {this.toggleInfo(settingspanel, e.currentTarget);}); + BDFDB.addEventListener(this, settingspanel, "click", ".settings-switch", () => {this.updateSettingsPanel(settingspanel);}); + BDFDB.addEventListener(this, settingspanel, "keyup", BDFDB.dotCN.input, () => {this.saveInputs(settingspanel);}); + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.selectcontrol, e => {this.openDropdownMenu(e);}); + BDFDB.addEventListener(this, settingspanel, "click", ".toggle-info", e => {this.toggleInfo(e.currentTarget);}); return settingspanel; } onSettingsClosed () { - if (this.updateTimestamps) { - this.setMaxWidth(); - document.querySelectorAll(".complete-timestamp").forEach(timestamp => {timestamp.classList.remove("complete-timestamp");}); - document.querySelectorAll(BDFDB.dotCN.messagetext).forEach(message => {this.changeTimestamp(message);}); - this.updateTimestamps = false; + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + BDFDB.WebModules.forceAllUpdates(this); } } } diff --git a/PluginsV2/CreationDate/index.js b/PluginsV2/CreationDate/index.js index b81078b127..02a355f7d9 100644 --- a/PluginsV2/CreationDate/index.js +++ b/PluginsV2/CreationDate/index.js @@ -5,22 +5,31 @@ module.exports = (Plugin, Api, Vendor) => { initConstructor () { this.labels = {}; + this.patchModules = { + "UserPopout":"componentDidMount", + "UserProfile":"componentDidMount" + }; + this.languages; - this.creationDateMarkup = `
`; - this.css = ` + ${BDFDB.dotCNS.userpopout + BDFDB.dotCN.nametag} { + margin-bottom: 4px; + } + ${BDFDB.dotCN.userprofile} .creationDate { + margin-right: 20px; + } ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userpopoutheadernormal} .creationDate { color: #b9bbbe; } - ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userpopoutheader}:not(${BDFDB.dotCN.userpopoutheadernormal}) .creationDate, + ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userpopoutheader + BDFDB.notCN.userpopoutheadernormal} .creationDate, ${BDFDB.dotCNS.themedark + BDFDB.dotCN.userpopoutheader} .creationDate { color: hsla(0,0%,100%,.6); } ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userprofiletopsectionnormal} .creationDate { color: hsla(216,4%,74%,.6); } - ${BDFDB.dotCN.themelight} [class*='topSection']:not(${BDFDB.dotCN.userprofiletopsectionnormal}) .creationDate, + ${BDFDB.dotCN.themelight} [class*='topSection']${BDFDB.notCN.userprofiletopsectionnormal} .creationDate, ${BDFDB.dotCN.themedark} [class*='topSection'] .creationDate { color: hsla(0,0%,100%,.6); }`; @@ -59,42 +68,13 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.userpopout)) { - if (BDFDB.getData("addInUserPopout", this, "settings")) this.addCreationDate(node.querySelector(BDFDB.dotCN.userpopoutheadertext)); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.popouts, {name:"userPopoutObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.userprofile)) { - if (BDFDB.getData("addInUserProfil", this, "settings")) this.addCreationDate(node.querySelector(BDFDB.dotCN.userprofileheaderinfo)); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.app + " ~ [class^='theme-']:not([class*='popouts'])", {name:"userProfilModalObserver",instance:observer}, {childList: true}); - this.languages = Object.assign({},BDFDB.languages); + BDFDB.WebModules.forceAllUpdates(this); + return true; } else { @@ -106,6 +86,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + BDFDB.removeEles(".creationDate"); BDFDB.unloadMessage(this); return true; } @@ -117,105 +98,114 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - openDropdownMenu (e) { - var selectControl = e.currentTarget; - var selectWrap = selectControl.parentElement; + let selectControl = e.currentTarget; + let selectWrap = selectControl.parentElement; + let plugincard = BDFDB.getParentEle("li", selectWrap); - if (selectWrap.classList.contains(BDFDB.disCN.selectisopen)) return; + if (!plugincard || BDFDB.containsClass(selectWrap, BDFDB.disCN.selectisopen)) return; - selectWrap.classList.add(BDFDB.disCN.selectisopen); - $("li").has(selectWrap).css("overflow", "visible"); + BDFDB.addClass(selectWrap, BDFDB.disCN.selectisopen); + plugincard.style.setProperty("overflow", "visible", "important"); - var type = selectWrap.getAttribute("type"); - var selectMenu = this.createDropdownMenu(selectWrap.getAttribute("value"), type); + let type = selectWrap.getAttribute("type"); + let selectMenu = this.createDropdownMenu(selectWrap.getAttribute("value")); selectWrap.appendChild(selectMenu); - $(selectMenu).on("mousedown." + this.name, BDFDB.dotCN.selectoption, (e2) => { - var language = e2.currentTarget.getAttribute("value"); + BDFDB.addChildEventListener(selectMenu, "mousedown", BDFDB.dotCN.selectoption, e2 => { + let language = e2.currentTarget.getAttribute("value"); selectWrap.setAttribute("value", language); selectControl.querySelector(".languageName").innerText = this.languages[language].name; selectControl.querySelector(".languageTimestamp").innerText = this.getCreationTime(language); BDFDB.saveData(type, language, this, "choices"); }); - $(document).on("mousedown.select" + this.name, (e2) => { - if (e2.target.parentElement == selectMenu) return; - $(document).off("mousedown.select" + this.name); - selectMenu.remove(); - $("li").has(selectWrap).css("overflow", "auto"); - setTimeout(() => {selectWrap.classList.remove(BDFDB.disCN.selectisopen);},100); - }); + + var removeMenu = e2 => { + if (e2.target.parentElement != selectMenu) { + document.removeEventListener("mousedown", removeMenu); + selectMenu.remove(); + plugincard.style.removeProperty("overflow"); + setTimeout(() => {BDFDB.removeClass(selectWrap, BDFDB.disCN.selectisopen);},100); + } + }; + + document.addEventListener("mousedown", removeMenu); } - createDropdownMenu (choice, type) { - var menuhtml = `
`; - for (var key in this.languages) { - var isSelected = key == choice ? ` ${BDFDB.disCN.selectselected}` : ``; + createDropdownMenu (choice) { + let menuhtml = `
`; + for (let key in this.languages) { + let isSelected = key == choice ? ` ${BDFDB.disCN.selectselected}` : ``; menuhtml += `
${this.languages[key].name}
${this.getCreationTime(this.languages[key].id)}
` } menuhtml += `
`; - return $(menuhtml)[0]; + return BDFDB.htmlToElement(menuhtml); } - addCreationDate (container) { - if (!container) return; - var info = BDFDB.getKeyInformation({"node":container,"key":"user"}); - if (info) { - var creationDate = $(this.creationDateMarkup); - var choice = BDFDB.getData("creationDateLang", this, "choices"); - creationDate.text(this.labels.createdat_text + " " + this.getCreationTime(this.languages[choice].id, info.createdAt)); - var nametag = container.querySelector(BDFDB.dotCN.nametag); - container.insertBefore(creationDate[0], nametag ? nametag.nextSibling : null); + processUserPopout (instance, wrapper) { + if (instance.props && instance.props.user && BDFDB.getData("addInUserPopout", this, "settings")) { + this.addCreationDate(instance.props.user, wrapper.querySelector(BDFDB.dotCN.userpopoutheadertext), wrapper.parentElement); + } + } + + processUserProfile (instance, wrapper) { + if (instance.props && instance.props.user && BDFDB.getData("addInUserProfil", this, "settings")) { + this.addCreationDate(instance.props.user, wrapper.querySelector(BDFDB.dotCN.userprofileheaderinfo), null); + } + } + + addCreationDate (info, container, popout) { + if (!info || !container || container.querySelector(".creationDate")) return; + let choice = BDFDB.getData("creationDateLang", this, "choices"); + let nametag = container.querySelector(BDFDB.dotCN.nametag); + let joinedAtDate = container.querySelector(".joinedAtDate"); + container.insertBefore(BDFDB.htmlToElement(`
${this.labels.createdat_text + " " + this.getCreationTime(this.languages[choice].id, info.createdAt)}
`), joinedAtDate ? joinedAtDate.nextSibling : (nametag ? nametag.nextSibling : null)); + BDFDB.initElements(container.parentElement, this); + if (popout && popout.style.transform.indexOf("translateY(-1") == -1) { + let arect = BDFDB.getRects(document.querySelector(BDFDB.dotCN.appmount)); + let prect = BDFDB.getRects(popout); + popout.style.setProperty("top", (prect.y + prect.height > arect.height ? (arect.height - prect.height) : prect.y) + "px"); } } getCreationTime (languageid, timestamp = new Date()) { - var settings = BDFDB.getAllData(this, "settings"); - var timestring = settings.addCreationTime ? timestamp.toLocaleString(languageid) : timestamp.toLocaleDateString(languageid); + let settings = BDFDB.getAllData(this, "settings"); + let timestring = settings.addCreationTime ? timestamp.toLocaleString(languageid) : timestamp.toLocaleDateString(languageid); if (timestring && settings.forceZeros) timestring = this.addLeadingZeros(timestring); return timestring; } addLeadingZeros (timestring) { - var chararray = timestring.split(""); - var numreg = /[0-9]/; - for (var i = 0; i < chararray.length; i++) { + let chararray = timestring.split(""); + let numreg = /[0-9]/; + for (let i = 0; i < chararray.length; i++) { if (!numreg.test(chararray[i-1]) && numreg.test(chararray[i]) && !numreg.test(chararray[i+1])) chararray[i] = "0" + chararray[i]; } - return chararray.join(""); } getSettingsPanel () { - var settings = BDFDB.getAllData(this, "settings"); - var choices = BDFDB.getAllData(this, "choices"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + let settings = BDFDB.getAllData(this, "settings"); + let choices = BDFDB.getAllData(this, "choices"); + let settingshtml = `
${this.name}
`; + for (let key in settings) { + settingshtml += `

${this.defaults.settings[key].description}

`; + } for (let key in choices) { settingshtml += `

${this.defaults.choices[key].description}

${this.languages[choices[key]].name}
${this.getCreationTime(this.languages[choices[key]].id)}
`; } - for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; - } - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => { - this.updateSettings(settingspanel); - var choices = BDFDB.getAllData(this, "choices"); - for (let key in choices) { - settingspanel.querySelector(`${BDFDB.dotCN.select}[type='${key}'] .languageTimestamp`).innerText = this.getCreationTime(this.languages[choices[key]].id); - } - }) - .on("click", BDFDB.dotCN.selectcontrol, (e) => {this.openDropdownMenu(e);}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "click", ".settings-switch", () => { + let choices = BDFDB.getAllData(this, "choices"); + for (let key in choices) settingspanel.querySelector(`${BDFDB.dotCN.select}[type='${key}'] .languageTimestamp`).innerText = this.getCreationTime(this.languages[choices[key]].id); + }); + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.selectcontrol, e => {this.openDropdownMenu(e);}); return settingspanel; } diff --git a/PluginsV2/DisplayServersAsChannels/index.js b/PluginsV2/DisplayServersAsChannels/index.js index b37925042c..544b26403e 100644 --- a/PluginsV2/DisplayServersAsChannels/index.js +++ b/PluginsV2/DisplayServersAsChannels/index.js @@ -13,106 +13,152 @@ module.exports = (Plugin, Api, Vendor) => { `; this.css = ` - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled, - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.scrollerwrapold}, - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guilds} { + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildswrapper}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildsscrollerwrap}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guilds} { width: 160px; } body.DSAC-styled .bd-settings-button, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.scrollerwrapold}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guilds} { + .DSAC-styled ${BDFDB.dotCN.guildswrapper}, + .DSAC-styled ${BDFDB.dotCN.guildsscrollerwrap}, + .DSAC-styled ${BDFDB.dotCN.guilds} { width: 240px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guilds}::-webkit-scrollbar-track-piece { + .DSAC-styled ${BDFDB.dotCN.guilds}::-webkit-scrollbar-track-piece { background-color: rgb(27, 29, 32); border-color: rgb(32, 34, 37); } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guilds}::-webkit-scrollbar-thumb { + .DSAC-styled ${BDFDB.dotCN.guilds}::-webkit-scrollbar-thumb { background-color: rgb(17, 19, 22); border-color: rgb(32, 34, 37); } - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guild} { + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild} { margin-left: 55px; } - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.friendsonline}, - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled #bd-pub-li { + .bd-minimal .DSAC-styled ${BDFDB.dotCN.friendsonline} { margin-left: 40px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} a, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} a, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCNS.guildinner + BDFDB.dotCN.guildicon}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner} a, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCNS.guildinner + BDFDB.dotCN.guildicon}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { + height: 20px; + } + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCNS.guildinner + BDFDB.dotCN.guildicon}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCNS.guildinner + BDFDB.dotCN.guildicon} { + line-height: 20px; + } + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} a, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCNS.guildinner + BDFDB.dotCN.guildicon}, + .DSAC-styled ${BDFDB.dotCN.guild}.copy, + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner}, + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner} a, + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCNS.guildinner + BDFDB.dotCN.guildicon}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { margin-left: 0px; height: 32px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guild}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.friendsonline} { + .DSAC-styled ${BDFDB.dotCN.guildseparator} { + margin-left: 0px; + } + .DSAC-styled ${BDFDB.dotCN.guild}, + .DSAC-styled ${BDFDB.dotCN.friendsonline} { margin-left: 80px; } - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator}, - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { + .DSAC-styled ${BDFDB.dotCN.guild}.folder.open ${BDFDB.dotCN.guildicon} { + text-decoration: underline; + } + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { width: 130px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { + .DSAC-styled ${BDFDB.dotCN.guildseparator}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, + .DSAC-styled ${BDFDB.dotCN.guild}.copy, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { width: 215px; box-sizing: border-box; opacity: 0.4; padding-left: 5px; border-radius: 3px; - display: flex !important; align-items: center; justify-content: flex-start; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildunread} { + .DSAC-styled ${BDFDB.dotCN.guildseparator}:not([style*="display: none"]), + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}:not([style*="display: none"]), + .DSAC-styled ${BDFDB.dotCN.guild}.copy:not([style*="display: none"]), + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror}:not([style*="display: none"]) { + display: flex; + } + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildunread}.copy. + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildunread} { opacity: 0.7; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}:not(${BDFDB.dotCN.guildselected}):hover { + .DSAC-styled ${BDFDB.dotCN.guild}.copy:not(${BDFDB.dotCN.guildselected}):hover, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.notCN.guildselected}:hover { opacity: 0.9; background-color: rgba(79,84,92,.3); } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildselected} { + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildselected}.copy, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildselected} { opacity: 1; background-color: rgba(79,84,92,.6); } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild} > div[draggable] { + .DSAC-styled ${BDFDB.dotCN.guild}.copy > div[draggable], + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild} > div[draggable] { flex: 1 1 auto; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio} > div[draggable], - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo} > div[draggable] { + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio}.copy > div[draggable], + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo}.copy > div[draggable], + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio} > div[draggable], + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo} > div[draggable] { padding-right: 20px; margin-right: 5px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio} > div[draggable] { + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio}.copy > div[draggable], + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio} > div[draggable] { background: url(/assets/382ca83d9dc390c4be715248bb4864f4.svg) right no-repeat !important; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo} > div[draggable] { + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo}.copy > div[draggable], + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo} > div[draggable] { background: url(/assets/c46f51f425c824899b6138ea2b61b41d.svg) right no-repeat !important; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.badge} { + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.badge}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.badge} { position: static; - margin-right: 5px; + margin: 0 3px; } - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} { + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} { width: unset; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} { + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} { background: transparent !important; border-radius: 0px !important; position: relative; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildaudio + BDFDB.dotCN.guildinner}:after, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildvideo + BDFDB.dotCN.guildinner}:after { + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildaudio}.copy ${BDFDB.dotCN.guildinner}:after, + .DSAC-styled ${BDFDB.dotCN.guild + BDFDB.dotCN.guildvideo}.copy ${BDFDB.dotCN.guildinner}:after, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildaudio + BDFDB.dotCN.guildinner}:after, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildvideo + BDFDB.dotCN.guildinner}:after { display: none !important; } - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} a { + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildicon}, + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildicon} { font-size: 14px !important; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} a { + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildicon}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildicon} { background: transparent !important; font-size: 16px !important; line-height: 32px; @@ -123,28 +169,24 @@ module.exports = (Plugin, Api, Vendor) => { right: 0; width: unset; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} .DSAC-verification-badge { + .DSAC-styled ${BDFDB.dotCN.guild}.copy ${BDFDB.dotCN.guildinner} .DSAC-verification-badge, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} .DSAC-verification-badge { position: absolute; left: 0; - top: 4px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildinner} .DSAC-verification-badge + a { - left: 25px; - } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { - border-radius: 3px; + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror} { margin-left: -5px; - line-height: 32px; + line-height: 28px; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror}, - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildsadd} { + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCNS.guild + BDFDB.dotCN.guildserror}, + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCN.guildsadd} { display: block !important; } - .bd-minimal ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildsadd + BDFDB.dotCN.guildsaddinner} { - top: 0; + .bd-minimal .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildsadd + BDFDB.dotCN.guildsaddinner} { + top: -0.2em; } - ${BDFDB.dotCN.guildswrapper}.DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildsadd + BDFDB.dotCN.guildsaddinner} { - top: -5px; + .DSAC-styled ${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild + BDFDB.dotCNS.guildsadd + BDFDB.dotCN.guildsaddinner} { + top: -6px; }`; } @@ -168,6 +210,7 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); var observer = null; @@ -180,23 +223,32 @@ module.exports = (Plugin, Api, Vendor) => { if (change.attributeName == "draggable" && change.oldValue && change.oldValue == "false") addedNodes = [change.target.parentElement]; if (addedNodes) { addedNodes.forEach((node) => { - if (node && node.classList && node.classList.contains(BDFDB.disCN.guild) && !node.querySelector(BDFDB.dotCN.guildserror)) { - var id = BDFDB.getIdOfServer(node); - if (id) this.changeServer(BDFDB.getDivOfServer(id)); + if (node && BDFDB.containsClass(node, BDFDB.disCN.guild) && !node.querySelector(BDFDB.dotCN.guildserror)) { + if (BDFDB.containsClass(node, "folder")) this.changeServer(this.getFolderObject(node)); + else this.changeServer(BDFDB.getServerData(node)); } }); } } ); }); - BDFDB.addObserver(this, BDFDB.dotCN.guilds, {name:"serverListObserver",instance:observer}, {childList: true, subtree:true, attributes:true, attributeFilte: ["class", "draggable"], attributeOldValue: true}); + BDFDB.addObserver(this, BDFDB.dotCN.guilds, {name:"serverListObserver",instance:observer}, {childList: true, subtree:true, attributes:true, attributeFilter: ["class", "draggable"], attributeOldValue: true}); - BDFDB.readServerList().forEach(serverObj => { - this.changeServer(serverObj); - }); + BDFDB.readServerList().forEach(info => {this.changeServer(info);}); + document.querySelectorAll(BDFDB.dotCN.guild + ".folder").forEach(folderdiv => {this.changeServer(this.getFolderObject(folderdiv));}); - document.body.classList.add("DSAC-styled"); - $(BDFDB.dotCN.guildswrapper).addClass("DSAC-styled"); + var appcontainer = document.querySelector(BDFDB.dotCN.appcontainer); + if (appcontainer) { + BDFDB.addEventListener(this, appcontainer, "mouseenter", `${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, ${BDFDB.dotCN.guild}.copy`, e => { + if (e.currentTarget.tagName && e.currentTarget.querySelector(BDFDB.dotCN.guildserror)) return; + BDFDB.appendLocalStyle("HideAllToolTips" + this.name, `${BDFDB.dotCN.tooltip} {display: none !important;}`); + }); + BDFDB.addEventListener(this, appcontainer, "mouseleave", `${BDFDB.dotCN.guildseparator} ~ ${BDFDB.dotCN.guild}, ${BDFDB.dotCN.guild}.copy`, e => { + if (e.currentTarget.tagName && e.currentTarget.querySelector(BDFDB.dotCN.guildserror)) return; + BDFDB.removeLocalStyle("HideAllToolTips" + this.name); + }); + } + BDFDB.addClass([document.body, appcontainer], "DSAC-styled"); return true; } @@ -208,10 +260,9 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - BDFDB.readServerList().forEach(serverObj => { - this.resetServer(serverObj); - }); - $(".DSAC-styled").removeClass("DSAC-styled"); + BDFDB.readServerList().forEach(info => {this.resetServer(info);}); + document.querySelectorAll(BDFDB.dotCN.guild + ".folder").forEach(folderdiv => {this.resetServer(this.getFolderObject(folderdiv));}); + BDFDB.removeClasses("DSAC-styled"); BDFDB.unloadMessage(this); return true; @@ -224,31 +275,29 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - changeServer (serverObj) { - if (!serverObj) return; - var avatar = serverObj.div.querySelector("a"); + changeServer (info) { + if (!info || !info.div) return; + var avatar = info.div.querySelector(BDFDB.dotCN.guildicon); if (avatar) { avatar.DSAColdName = avatar.textContent; - avatar.textContent = serverObj.name; - if (serverObj.features.has("VERIFIED")) $(this.verificationBadgeMarkup).insertBefore(avatar); - $(serverObj.div) - .off("." + this.name) - .on("mouseenter." + this.name, () => { - BDFDB.appendLocalStyle("HideAllToolTips" + this.name, `${BDFDB.dotCN.tooltip} {display: none !important;}`); - }) - .on("mouseleave." + this.name, () => { - BDFDB.removeLocalStyle("HideAllToolTips" + this.name); - }); + avatar.innerHTML = `
${BDFDB.encodeToHTML(info.name || info.folderName || "")}
`; + BDFDB.initElements(avatar, this); + if (info.features && info.features.has("VERIFIED")) avatar.parentElement.insertBefore(BDFDB.htmlToElement(this.verificationBadgeMarkup), avatar); } } - resetServer (serverObj) { - if (!serverObj) return; - var avatar = serverObj.div.querySelector("a"); + resetServer (info) { + if (!info || !info.div) return; + var avatar = info.div.querySelector(BDFDB.dotCN.guildicon); if (avatar) { - avatar.textContent = avatar.DSAColdName; - $(serverObj.div).off("." + this.name).find(".DSAC-verification-badge").remove(); + avatar.innerHTML = BDFDB.encodeToHTML(avatar.DSAColdName); + BDFDB.removeEles(info.div.querySelector(".DSAC-verification-badge")); } } + + getFolderObject (folderdiv) { + var data = BDFDB.loadData(folderdiv.id, "ServerFolders", "folders"); + return data ? Object.assign({div:folderdiv}, data) : null; + } } }; diff --git a/PluginsV2/EditChannels/index.js b/PluginsV2/EditChannels/index.js index 125f480778..b479dd4655 100644 --- a/PluginsV2/EditChannels/index.js +++ b/PluginsV2/EditChannels/index.js @@ -5,6 +5,15 @@ module.exports = (Plugin, Api, Vendor) => { initConstructor () { this.labels = {}; + this.patchModules = { + "ChannelTextArea":"componentDidMount", + "AuditLog":"componentDidMount", + "ChannelCategoryItem":"componentDidMount", + "ChannelItem":"componentDidMount", + "HeaderBar":["componentDidMount","componentDidUpdate"], + "Clickable":"componentDidMount" + }; + this.channelContextEntryMarkup = `
@@ -28,7 +37,7 @@ module.exports = (Plugin, Api, Vendor) => {
`; this.channelSettingsModalMarkup = - ` + `
@@ -38,12 +47,16 @@ module.exports = (Plugin, Api, Vendor) => {

REPLACE_modal_header_text

- - - - - - +
@@ -60,9 +73,7 @@ module.exports = (Plugin, Api, Vendor) => {

REPLACE_modal_colorpicker1_text

-
-
-
+
@@ -76,9 +87,16 @@ module.exports = (Plugin, Api, Vendor) => {
`; + this.css = ` + ${BDFDB.dotCN.channelheadertitletext}[custom-editchannelsheader] ${BDFDB.dotCN.channelheaderchannelicon} { + opacity: 0.6; + } + `; + this.defaults = { settings: { - changeInChannelHeader: {value:true, description:"Change in Channel Header."} + changeChannelIcon: {value:true, description:"Change color of Channel Icon."}, + changeUnreadIndicator: {value:true, description:"Change color of Unread Indicator."} } }; } @@ -103,54 +121,16 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; + this.UserUtils = BDFDB.WebModules.findByProperties("getUsers","getUser"); + this.ChannelUtils = BDFDB.WebModules.findByProperties("getChannels","getChannel"); + this.CurrentChannelUtils = BDFDB.WebModules.findByProperties("getChannels","getDefaultChannel"); + this.LastGuildStore = BDFDB.WebModules.findByProperties("getLastSelectedGuildId"); + this.LastChannelStore = BDFDB.WebModules.findByProperties("getLastSelectedChannelId"); - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.attributeName == "class" && $(change.target).attr("class").indexOf("wrapper") > -1 && $("[custom-editchannels]").has(change.target)[0]) { - let info = BDFDB.getKeyInformation({"node":change.target, "key":"channel"}); - if (info) this.loadChannel(BDFDB.getDivOfChannel(info.id)); - } - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.classList && (node.classList.contains(BDFDB.disCN.channelcontainerdefault) || node.classList.contains(BDFDB.disCN.categorycontainerdefault))) { - let info = BDFDB.getKeyInformation({"node":node, "key":"channel"}); - if (info) this.loadChannel(BDFDB.getDivOfChannel(info.id)); - } - if (node && node.className && node.className.length > 0 && node.className.indexOf("container-") > -1) { - for (let channel of node.querySelectorAll(BDFDB.dotCNC.channelcontainerdefault + BDFDB.dotCN.categorycontainerdefault)) { - let info = BDFDB.getKeyInformation({"node":channel, "key":"channel"}); - if (info) this.loadChannel(BDFDB.getDivOfChannel(info.id)); - } - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.channels, {name:"channelListObserver",instance:observer}, {childList: true, attributes:true, subtree: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu)) { - this.onContextMenu(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"channelContextObserver",instance:observer}, {childList: true}); - - this.loadAllChannels(); - - this.changeChannelHeader(); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -162,7 +142,12 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - this.resetAllChannels(); + let data = BDFDB.loadAllData(this, "channels"); + BDFDB.removeAllData(this, "channels"); + BDFDB.WebModules.forceAllUpdates(this); + BDFDB.saveAllData(data, this, "channels"); + + BDFDB.removeEles(".autocompleteEditChannels", ".autocompleteEditChannelsRow"); BDFDB.unloadMessage(this); return true; @@ -172,33 +157,9 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - $(`${BDFDB.dotCN.channelheadertitletext}[custom-editchannelsheader]`).find(BDFDB.dotCN.channelheaderchannelname + BDFDB.dotCN.channelheaderprivate).css("color", "").css("background-color", "").parent().removeAttr("custom-editchannelsheader"); - this.loadAllChannels(); - setImmediate(() => {this.changeChannelHeader();}); //setImmediate so EditChannels sets the color after EditUsers set it back to white - } - } - // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - - resetAll () { - if (confirm("Are you sure you want to reset all channels?")) { - BDFDB.removeAllData(this, "channels"); - - this.resetAllChannels(); - } - } - changeLanguageStrings () { this.channelContextEntryMarkup = this.channelContextEntryMarkup.replace("REPLACE_context_localchannelsettings_text", this.labels.context_localchannelsettings_text); @@ -211,206 +172,411 @@ module.exports = (Plugin, Api, Vendor) => { this.channelSettingsModalMarkup = this.channelSettingsModalMarkup.replace("REPLACE_btn_save_text", this.labels.btn_save_text); } - onContextMenu (context) { - if (!context || !context.tagName || !context.parentElement || context.querySelector(".localchannelsettings-item")) return; - var info = BDFDB.getKeyInformation({"node":context, "key":"channel"}); - if (info && BDFDB.getKeyInformation({"node":context, "key":"displayName", "value":"ChannelDeleteGroup"})) { - $(context).append(this.channelContextEntryMarkup) - .on("mouseenter", ".localchannelsettings-item", (e) => { - this.createContextSubMenu(info, e, context); + onChannelContextMenu (instance, menu) { + if (instance.props && instance.props.channel && !menu.querySelector(".localchannelsettings-item")) { + let channelContextEntry = BDFDB.htmlToElement(this.channelContextEntryMarkup); + menu.appendChild(channelContextEntry); + let settingsitem = channelContextEntry.querySelector(".localchannelsettings-item"); + settingsitem.addEventListener("mouseenter", () => { + let channelContextSubMenu = BDFDB.htmlToElement(this.channelContextSubMenuMarkup); + let channelitem = channelContextSubMenu.querySelector(".channelsettings-item"); + channelitem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + this.showChannelSettings(instance.props.channel); }); - - BDFDB.updateContextPosition(context); - } - } - - createContextSubMenu (info, e, context) { - var channelContextSubMenu = $(this.channelContextSubMenuMarkup); - - channelContextSubMenu - .on("click", ".channelsettings-item", () => { - $(context).hide(); - this.showChannelSettings(info); + if (BDFDB.loadData(instance.props.channel.id, this, "channels")) { + let resetitem = channelContextSubMenu.querySelector(".resetsettings-item"); + BDFDB.removeClass(resetitem, BDFDB.disCN.contextmenuitemdisabled); + resetitem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + BDFDB.removeData(instance.props.channel.id, this, "channels"); + BDFDB.WebModules.forceAllUpdates(this); + }); + } + BDFDB.appendSubMenu(settingsitem, channelContextSubMenu); }); - - if (BDFDB.loadData(info.id, this, "channels")) { - channelContextSubMenu - .find(".resetsettings-item") - .removeClass(BDFDB.disCN.contextmenuitemdisabled) - .on("click", () => { - $(context).hide(); - this.removeChannelData(info); - }); } - - BDFDB.appendSubMenu(e.currentTarget, channelContextSubMenu); } showChannelSettings (info) { - var channelObj = BDFDB.getDivOfChannel(info.id); + var {name,color} = BDFDB.loadData(info.id, this, "channels") || {} - var data = BDFDB.loadData(info.id, this, "channels"); + let channelSettingsModal = BDFDB.htmlToElement(this.channelSettingsModalMarkup); + let channelnameinput = channelSettingsModal.querySelector("#input-channelname"); - var name = data ? data.name : null; - var color = data ? data.color : null; + channelSettingsModal.querySelector(BDFDB.dotCN.modalguildname).innerText = info.name; + channelnameinput.value = name || ""; + channelnameinput.setAttribute("placeholder", info.name); + BDFDB.setColorSwatches(channelSettingsModal, color); - var channelSettingsModal = $(this.channelSettingsModalMarkup); - channelSettingsModal.find(BDFDB.dotCN.modalguildname).text(info.name); - channelSettingsModal.find("#input-channelname").val(name); - channelSettingsModal.find("#input-channelname").attr("placeholder", info.name); - BDFDB.setColorSwatches(color, channelSettingsModal.find(".swatches1"), "swatch1"); BDFDB.appendModal(channelSettingsModal); - channelSettingsModal - .on("click", ".btn-save", (event) => { - event.preventDefault(); - name = null; - if (channelSettingsModal.find("#input-channelname").val()) { - if (channelSettingsModal.find("#input-channelname").val().trim().length > 0) { - name = channelSettingsModal.find("#input-channelname").val().trim(); + BDFDB.addChildEventListener(channelSettingsModal, "click", ".btn-save", e => { + e.preventDefault(); + + name = channelnameinput.value.trim(); + name = name ? name : null; + + color = BDFDB.getSwatchColor(channelSettingsModal, 1); + if (color) { + if (color[0] < 30 && color[1] < 30 && color[2] < 30) color = BDFDB.colorCHANGE(color, 30); + else if (color[0] > 225 && color[1] > 225 && color[2] > 225) color = BDFDB.colorCHANGE(color, -30); + } + + if (name == null && color == null) { + BDFDB.removeData(info.id, this, "channels"); + } + else { + BDFDB.saveData(info.id, {name,color}, this, "channels"); + } + BDFDB.WebModules.forceAllUpdates(this); + }); + channelnameinput.focus(); + } + + processChannelTextArea (instance, wrapper) { + let channel = BDFDB.getReactValue(instance, "props.channel"); + if (channel) { + var textarea = wrapper.querySelector("textarea"); + if (!textarea) return; + if (channel.type == 0 && instance.props.type == "normal") { + let data = BDFDB.loadData(channel.id, this, "channels") || {}; + wrapper.querySelector("textarea").setAttribute("placeholder", BDFDB.LanguageStrings.TEXTAREA_PLACEHOLDER.replace("{{channel}}", "#" + (data.name || channel.name))); + } + BDFDB.addEventListener(this, textarea, "keydown", e => { + let autocompletemenu = textarea.parentElement.querySelector(BDFDB.dotCN.autocomplete); + if (autocompletemenu && (e.which == 9 || e.which == 13)) { + if (BDFDB.containsClass(autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected).parentElement, "autocompleteEditChannelsRow")) { + e.originalEvent.preventDefault(); + e.originalEvent.stopPropagation(); + this.swapWordWithMention(textarea); } } - - color = BDFDB.getSwatchColor("swatch1"); - if (color) { - if (color[0] < 30 && color[1] < 30 && color[2] < 30) BDFDB.colorCHANGE(color, 30); - else if (color[0] > 225 && color[1] > 225 && color[2] > 225) BDFDB.colorCHANGE(color, -30); + else if (autocompletemenu && (e.which == 38 || e.which == 40)) { + let autocompleteitems = autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselectable + ":not(.autocompleteEditChannelsSelector)"); + let selected = autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected); + if (BDFDB.containsClass(selected, "autocompleteEditChannelsSelector") || autocompleteitems[e.which == 38 ? 0 : (autocompleteitems.length-1)] == selected) { + e.originalEvent.preventDefault(); + e.originalEvent.stopPropagation(); + let next = this.getNextSelection(autocompletemenu, null, e.which == 38 ? false : true); + BDFDB.removeClass(selected, BDFDB.disCN.autocompleteselected); + BDFDB.addClass(selected, BDFDB.disCN.autocompleteselector); + BDFDB.addClass(next, BDFDB.disCN.autocompleteselected); + } + } + else if (textarea.value && !e.shiftKey && e.which == 13 && !autocompletemenu && textarea.value.indexOf("s/") != 0) { + this.format = true; + textarea.dispatchEvent(new Event("input")); + } + else if (!e.ctrlKey && e.which != 16 && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) { + clearTimeout(textarea.EditChannelsAutocompleteTimeout); + textarea.EditChannelsAutocompleteTimeout = setTimeout(() => {this.addAutoCompleteMenu(textarea, channel);},100); } - if (name == null && color == null) { - this.removeChannelData(info.id); - } - else { - BDFDB.saveData(info.id, {name,color}, this, "channels"); - this.loadChannel(channelObj); - this.changeChannelHeader(); - } + if (!e.ctrlKey && e.which != 38 && e.which != 40 && !(e.which == 39 && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length)) BDFDB.removeEles(".autocompleteEditChannels", ".autocompleteEditChannelsRow"); + }); + BDFDB.addEventListener(this, textarea, "click", e => { + if (textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) setImmediate(() => {this.addAutoCompleteMenu(textarea, channel);}); }); - - channelSettingsModal.find("#input-channelname").focus(); - } - - removeChannelData (info) { - this.resetChannel(BDFDB.getDivOfChannel(info.id)); - - BDFDB.removeData(info.id, this, "channels"); - - this.changeChannelHeader(); - } - - resetChannel (channelObj) { - if (!channelObj || !channelObj.div) return; - - var channel = channelObj.div.querySelector(BDFDB.dotCNC.channelname + BDFDB.dotCN.categorycolortransition); - - $(channelObj.div) - .removeAttr("custom-editchannels"); - $(channel) - .css("color", ""); - - BDFDB.setInnerText(channel, channelObj.name); - } - - loadChannel (channelObj) { - if (!channelObj || !channelObj.div) return; - - var channel = channelObj.div.querySelector(BDFDB.dotCNC.channelname + BDFDB.dotCN.categorycolortransition); - - var data = BDFDB.loadData(channelObj.id, this, "channels"); - if (data) { - var name = data.name ? data.name : channelObj.name; - var color = data.color ? this.chooseColor(channel, data.color) : ""; - - $(channelObj.div) - .attr("custom-editchannels", true); - $(channel) - .css("color", color); - - BDFDB.setInnerText(channel, name); } } - loadAllChannels () { - for (let channelObj of BDFDB.readChannelList()) { - this.loadChannel(channelObj); + processAuditLog (instance, wrapper) { + let channel = BDFDB.getReactValue(instance, "props.log.options.channel"); + if (channel) { + let hooks = wrapper.querySelectorAll(`${BDFDB.dotCN.flexchild} > span${BDFDB.notCN.auditloguserhook}`); + if (hooks.length > 0) this.changeChannel2(channel, hooks[0].firstChild); + } + } + + processChannelCategoryItem (instance, wrapper) { + if (instance.props && instance.props.channel) { + this.changeChannel(instance.props.channel, wrapper.querySelector(BDFDB.dotCN.categorycolortransition)); } } - changeChannelHeader () { - if (BDFDB.getData("changeInChannelHeader", this, "settings")) { - var channelHeader = document.querySelector(BDFDB.dotCNS.channelheadertitle + BDFDB.dotCN.channelheadertitletext); - if (!channelHeader) return; - var channel = channelHeader.querySelector(`${BDFDB.dotCN.channelheaderchannelname}:not(${BDFDB.dotCN.channelheaderprivate})`); - if (!channel) return; - var info = BDFDB.getKeyInformation({"node":channelHeader,"key":"channel"}); - if (info) { - var data = BDFDB.loadData(info.id, this, "channels"); - var name = data && data.name ? data.name : info.name; - var color = data && data.color ? BDFDB.color2RGB(data.color) : ""; - BDFDB.setInnerText(channel, name); - $(channel).css("color", color); + processChannelItem (instance, wrapper) { + if (instance.props && instance.props.channel) { + this.changeChannel(instance.props.channel, wrapper.querySelector(BDFDB.dotCN.channelname)); + } + } - if (data && (data.name || data.color)) { - $(channelHeader).attr("custom-editchannelsheader", true); - } - else { - $(channelHeader).removeAttr("custom-editchannelsheader"); + processHeaderBar (instance, wrapper) { + let channel_id = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.channelId"); + if (channel_id) { + let channelname = wrapper.querySelector(BDFDB.dotCN.channelheaderchannelname); + if (channelname) { + let channel = this.ChannelUtils.getChannel(channel_id); + if (channel) { + if (channel.type == 0) this.changeChannel(channel, wrapper.querySelector(BDFDB.dotCN.channelheaderchannelname)); + else { + if (channel.type == 1) channel = this.UserUtils.getUser(channel.recipients[0]) || channel; + if (channelname.EditChannelsChangeObserver && typeof channelname.EditChannelsChangeObserver.disconnect == "function") channelname.EditChannelsChangeObserver.disconnect(); + channelname.style.removeProperty("color"); + channelname.style.removeProperty("background"); + BDFDB.setInnerText(channelname, channel.name || channel.username); + } } } } } - resetAllChannels () { - document.querySelectorAll("[custom-editchannels]").forEach(channelDiv => { - var info = BDFDB.getKeyInformation({"node":channelDiv, "key":"channel"}); - if (info) this.resetChannel({div:channelDiv,info}); + processClickable (instance, wrapper) { + if (!instance.props || !instance.props.className) return; + else if (instance.props.tag == "span" && instance.props.className.indexOf(BDFDB.disCN.mentionwrapper) > -1 && instance.props.className.indexOf(BDFDB.disCN.mention) == -1) { + let children = BDFDB.getReactValue(instance, "_reactInternalFiber.memoizedProps.children"); + if (children && typeof children[0] == "string") { + let channelname = children[0].slice(1); + let categoryname = BDFDB.getReactValue(instance, "_reactInternalFiber.return.return.type.displayName") == "Tooltip" ? BDFDB.getReactValue(instance, "_reactInternalFiber.return.return.memoizedProps.text") : null; + for (let channel of this.CurrentChannelUtils.getChannels(this.LastGuildStore.getGuildId())[0]) { + if (channelname == channel.channel.name) { + let category = categoryname ? this.ChannelUtils.getChannel(channel.channel.parent_id) : null; + if (!category || category && categoryname == category.name) { + this.changeMention(channel.channel, wrapper, category || {}); + break; + } + } + } + } + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.quickswitchresult) > -1) { + let result = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.result"); + if (result && result.type.indexOf("_CHANNEL") != -1) { + this.changeChannel(result.record, wrapper.querySelector(BDFDB.dotCN.quickswitchresultmatch)); + if (result.record.parent_id) { + this.changeChannel(this.ChannelUtils.getChannel(result.record.parent_id), wrapper.querySelector(BDFDB.dotCN.quickswitchresultnote)); + } + } + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.autocompleterow) > -1) { + let channel = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.channel"); + if (channel) { + this.changeChannel(channel, wrapper.querySelector(BDFDB.dotCN.marginleft4)); + let category = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.category"); + if (category) this.changeChannel(category, wrapper.querySelector(BDFDB.dotCN.autocompletedescription)); + } + } + else if (instance.props.tag == "span" && instance.props.className.indexOf(BDFDB.disCN.messagespopoutchannelname) > -1) { + let channel = BDFDB.getReactValue(instance, "_reactInternalFiber.return.sibling.child.child.memoizedProps.channel"); + if (channel) this.changeChannel2(channel, wrapper); + } + } + + changeChannel (info, channelname) { + if (!info || !channelname || !channelname.parentElement) return; + if (channelname.EditChannelsChangeObserver && typeof channelname.EditChannelsChangeObserver.disconnect == "function") channelname.EditChannelsChangeObserver.disconnect(); + let data = BDFDB.loadData(info.id, this, "channels") || {}; + let settings = BDFDB.getAllData(this, "settings"); + let color = this.chooseColor(channelname, data.color); + channelname.style.setProperty("color", color, "important"); + BDFDB.setInnerText(channelname, data.name || info.name); + let iconparent = BDFDB.containsClass(channelname, BDFDB.disCN.quickswitchresultmatch) ? channelname.parentElement.parentElement : channelname.parentElement; + if (!BDFDB.containsClass(channelname, BDFDB.disCN.autocompletedescription)) { + iconparent.querySelectorAll('svg [stroke]:not([stroke="none"]').forEach(icon => { + if (!icon.getAttribute("oldstroke")) icon.setAttribute("oldstroke", icon.getAttribute("stroke")); + icon.setAttribute("stroke", color && settings.changeChannelIcon ? color : icon.getAttribute("oldstroke"), "important"); + icon.style.setProperty("stroke", color && settings.changeChannelIcon ? color : icon.getAttribute("oldstroke"), "important"); + }); + iconparent.querySelectorAll('svg [fill]:not([fill="none"]').forEach(icon => { + if (!icon.getAttribute("oldfill")) icon.setAttribute("oldfill", icon.getAttribute("fill")); + icon.setAttribute("fill", color && settings.changeChannelIcon ? color : icon.getAttribute("oldfill"), "important"); + icon.style.setProperty("fill", color && settings.changeChannelIcon ? color : icon.getAttribute("oldfill"), "important"); + }); + let unread = iconparent.parentElement.querySelector(BDFDB.dotCN.channelunread); + if (unread) unread.style.setProperty("background-color", color && settings.changeUnreadIndicator ? color : null, "important"); + } + if (color) { + channelname.EditChannelsChangeObserver = new MutationObserver((changes, _) => { + changes.forEach( + (change, i) => { + if (change.type == "childList" && change.addedNodes.length && change.target.tagName && (change.target.tagName == "SVG" || change.target.querySelector("svg")) || change.type == "attributes" && change.attributeName == "class" && change.target.className.length && change.target.className.indexOf("name") > -1 || change.type == "attributes" && change.attributeName == "style" && BDFDB.containsClass(change.target, BDFDB.disCN.channelheaderchannelname)) { + channelname.EditChannelsChangeObserver.disconnect(); + this.changeChannel(info, channelname); + } + } + ); + }); + channelname.EditChannelsChangeObserver.observe(iconparent, {attributes:true, childList:true, subtree:true}); + } + } + + changeChannel2 (info, channelname) { + if (!info || !channelname || !channelname.parentElement) return; + if (channelname.EditChannelsChangeObserver && typeof channelname.EditChannelsChangeObserver.disconnect == "function") channelname.EditChannelsChangeObserver.disconnect(); + let data = BDFDB.loadData(info.id, this, "channels") || {}; + let color = this.chooseColor(channelname, data.color); + channelname.style.setProperty("color", color, "important"); + BDFDB.setInnerText(channelname, "#" + (data.name || info.name)); + if (color) { + channelname.EditChannelsChangeObserver = new MutationObserver((changes, _) => { + changes.forEach( + (change, i) => { + if (change.type == "childList" && change.addedNodes.length && change.target.tagName && (change.target.tagName == "SVG" || change.target.querySelector("svg")) || change.type == "attributes" && change.attributeName == "class" && change.target.className.length && change.target.className.indexOf("name") > -1) { + channelname.EditChannelsChangeObserver.disconnect(); + this.changeChannel2(info, channelname); + } + } + ); + }); + channelname.EditChannelsChangeObserver.observe(channelname.parentElement, {attributes:true, childList:true, subtree:true}); + } + } + + changeMention (info, mention, categoryinfo) { + if (!info || !mention || !mention.parentElement) return; + if (mention.EditChannelsChangeObserver && typeof mention.EditChannelsChangeObserver.disconnect == "function") mention.EditChannelsChangeObserver.disconnect(); + mention.removeEventListener("mouseover", mention.mouseoverListenerEditChannels); + mention.removeEventListener("mouseout", mention.mouseoutListenerEditChannels); + let data = BDFDB.loadData(info.id, this, "channels") || {}; + let color = BDFDB.colorCONVERT(data.color, "RGBCOMP"); + BDFDB.setInnerText(mention, "#" + (data.name || info.name)); + if (mention.EditChannelsHovered) colorHover(); + else colorDefault(); + mention.mouseoverListenerEditChannels = () => { + mention.EditChannelsHovered = true; + colorHover(); + let categorydata = BDFDB.loadData(categoryinfo.id, this, "channels") || {}; + if (categorydata.name) BDFDB.createTooltip(categorydata.name, mention, {type:"top",selector:"EditChannels-tooltip",css:`body ${BDFDB.dotCN.tooltip}:not(.EditChannels-tooltip) {display: none !important;}`}); + }; + mention.mouseoutListenerEditChannels = () => { + delete mention.EditChannelsHovered; + colorDefault(); + }; + mention.addEventListener("mouseover", mention.mouseoverListenerEditChannels); + mention.addEventListener("mouseout", mention.mouseoutListenerEditChannels); + mention.EditChannelsChangeObserver = new MutationObserver((changes, _) => { + mention.EditChannelsChangeObserver.disconnect(); + this.changeMention(info, mention, categoryinfo); }); - - var channelHeader = document.querySelector("[custom-editchannelsheader]"); - if (channelHeader) { - var info = BDFDB.getKeyInformation({"node":channelHeader, "key":"channel"}); - if (info) { - var channel = channelHeader.querySelector(BDFDB.dotCN.channelheaderchannelname); - BDFDB.setInnerText(channel, info.name); - $(channel).css("color", ""); - $(channelHeader).removeAttr("custom-editchannelsheader"); - } + mention.EditChannelsChangeObserver.observe(mention, {attributes:true}); + function colorDefault() { + mention.style.setProperty("color", color ? "rgb(" + color[0] + "," + color[1] + "," + color[2] + ")" : null, "important"); + mention.style.setProperty("background", color ? "rgba(" + color[0] + "," + color[1] + "," + color[2] + ",.1)" : null, "important"); + } + function colorHover() { + mention.style.setProperty("color", color ? "#FFFFFF" : null, "important"); + mention.style.setProperty("background", color ? "rgba(" + color[0] + "," + color[1] + "," + color[2] + ",.7)" : null, "important"); } } - chooseColor (channel, color) { - if (color && channel && channel.className) { - if (channel.className.indexOf("nameMuted") > -1 || channel.className.indexOf("nameLocked") > -1) { - color = BDFDB.colorCHANGE(color, -50); - } - if (channel.className.indexOf("nameDefault") > -1) { - color = color; - } - if (channel.className.indexOf("nameSelected") > -1 || channel.className.indexOf("nameHovered") > -1 || channel.className.indexOf("nameUnread") > -1) { - color = BDFDB.colorCHANGE(color, 50); - } - return BDFDB.color2RGB(color); + chooseColor (channelname, color) { + if (color && channelname) { + let classname = channelname.className ? channelname.className.toLowerCase() : ""; + if (classname.indexOf("muted") > -1 || classname.indexOf("locked") > -1) color = BDFDB.colorCHANGE(color, -0.5); + else if (classname.indexOf("selected") > -1 || classname.indexOf("hovered") > -1 || classname.indexOf("unread") > -1) color = BDFDB.colorCHANGE(color, 0.5); + return BDFDB.colorCONVERT(color, "RGB"); } return null; } + addAutoCompleteMenu (textarea, channel) { + if (textarea.parentElement.querySelector(".autocompleteEditChannelsRow")) return; + let words = textarea.value.split(/\s/); + let lastword = words[words.length-1].trim(); + if (lastword && lastword.length > 1 && lastword[0] == "#") { + let channels = BDFDB.loadAllData(this, "channels"); + if (!channels) return; + let channelarray = []; + for (let id in channels) if (channels[id].name) { + let channel = this.ChannelUtils.getChannel(id); + let category = channel && channel.parent_id ? this.ChannelUtils.getChannel(channel.parent_id) : null; + let catdata = (category ? channels[category.id] : null) || {}; + if (channel && channel.type == 0) channelarray.push(Object.assign({lowercasename:channels[id].name.toLowerCase(),lowercasecatname:(catdata && catdata.name ? catdata.name.toLowerCase() : null),channel,category,catdata},channels[id])); + } + channelarray = BDFDB.sortArrayByKey(channelarray.filter(n => n.lowercasename.indexOf(lastword.toLowerCase().slice(1)) != -1 || (n.lowercasecatname && n.lowercasecatname.indexOf(lastword.toLowerCase().slice(1)) != -1)), "lowercasename"); + if (channelarray.length) { + let settings = BDFDB.getAllData(this, "settings"); + let autocompletemenu = textarea.parentElement.querySelector(BDFDB.dotCNS.autocomplete + BDFDB.dotCN.autocompleteinner), amount = 15; + if (!autocompletemenu) { + autocompletemenu = BDFDB.htmlToElement(`
${BDFDB.LanguageStrings.TEXT_CHANNELS_MATCHING.replace("{{prefix}}", BDFDB.encodeToHTML(lastword))}
`); + textarea.parentElement.appendChild(autocompletemenu); + autocompletemenu = autocompletemenu.firstElementChild; + } + else { + amount -= autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselectable).length; + } + + BDFDB.addEventListener(this, autocompletemenu, "mouseenter", BDFDB.dotCN.autocompleteselectable, e => { + var selected = autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselected); + BDFDB.removeClass(selected, BDFDB.disCN.autocompleteselected); + BDFDB.addClass(selected, BDFDB.disCN.autocompleteselector); + BDFDB.addClass(e.currentTarget, BDFDB.disCN.autocompleteselected); + }); + + for (let data of channelarray) { + if (amount-- < 1) break; + let color = BDFDB.colorCONVERT(data.color, "RGB"); + let catcolor = BDFDB.colorCONVERT(data.catdata.color, "RGB"); + let autocompleterow = BDFDB.htmlToElement(`
${BDFDB.encodeToHTML(data.name || data.channel.name)}
${data.category ? '
' + BDFDB.encodeToHTML(data.catdata.name || data.category.name) + '
' : ''}
`); + autocompleterow.querySelector(BDFDB.dotCN.autocompleteselectable).addEventListener("click", () => {this.swapWordWithMention(textarea);}); + autocompletemenu.appendChild(autocompleterow); + } + if (!autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected)) { + BDFDB.addClass(autocompletemenu.querySelector(".autocompleteEditChannelsRow " + BDFDB.dotCN.autocompleteselectable), BDFDB.disCN.autocompleteselected); + } + } + } + } + + getNextSelection (menu, selected, forward) { + selected = selected ? selected : menu.querySelector(BDFDB.dotCN.autocompleteselected).parentElement; + let next, sibling = forward ? selected.nextElementSibling : selected.previousElementSibling; + if (sibling) { + next = sibling.querySelector(BDFDB.dotCN.autocompleteselectable); + } + else { + let items = menu.querySelectorAll(BDFDB.dotCN.autocompleteselectable); + next = forward ? items[0] : items[items.length-1]; + } + return next ? next : this.getNextSelection(menu, sibling, forward); + } + + swapWordWithMention (textarea) { + let selected = textarea.parentElement.querySelector(".autocompleteEditChannelsRow " + BDFDB.dotCN.autocompleteselected); + let channelid = selected ? selected.getAttribute("channelid") : null; + let words = textarea.value.split(/\s/); + let lastword = words[words.length-1].trim(); + if (channelid && lastword) { + BDFDB.removeEles(".autocompleteEditChannels", ".autocompleteEditChannelsRow"); + textarea.focus(); + textarea.selectionStart = textarea.value.length - lastword.length; + textarea.selectionEnd = textarea.value.length; + document.execCommand("insertText", false, `<#${channelid}> `); + textarea.selectionStart = textarea.value.length; + textarea.selectionEnd = textarea.value.length; + } + } + getSettingsPanel () { + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var settings = BDFDB.getAllData(this, "settings"); - var settingshtml = `
`; + var settingshtml = `
${this.name}
`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; } settingshtml += `

Reset all Channels.

`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) - .on("click", ".reset-button", () => {this.resetAll();}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "click", ".reset-button", () => { + BDFDB.openConfirmModal(this, "Are you sure you want to reset all channels?", () => { + BDFDB.removeAllData(this, "channels"); + BDFDB.WebModules.forceAllUpdates(this); + }); + }); return settingspanel; } + onSettingsClosed () { + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + BDFDB.WebModules.forceAllUpdates(this); + } + } + setLabelsByLanguage () { switch (BDFDB.getDiscordLanguage().id) { case "hr": //croatian diff --git a/PluginsV2/EditServers/index.js b/PluginsV2/EditServers/index.js index 051b0c7cbf..ce9aa371c0 100644 --- a/PluginsV2/EditServers/index.js +++ b/PluginsV2/EditServers/index.js @@ -5,7 +5,11 @@ module.exports = (Plugin, Api, Vendor) => { initConstructor () { this.labels = {}; - this.serverDragged = false; + this.patchModules = { + "GuildIcon":"componentDidMount", + "GuildHeader":["componentDidMount","componentDidUpdate"], + "Clickable":"componentDidMount" + }; this.serverContextEntryMarkup = `
@@ -30,27 +34,33 @@ module.exports = (Plugin, Api, Vendor) => {
`; this.serverSettingsModalMarkup = - ` + `
-
+

REPLACE_modal_header_text

- - - - - - +
-
-
REPLACE_modal_tabheader1_text
-
REPLACE_modal_tabheader2_text
-
REPLACE_modal_tabheader3_text
+
+
+
REPLACE_modal_tabheader1_text
+
REPLACE_modal_tabheader2_text
+
REPLACE_modal_tabheader3_text
+
@@ -84,29 +94,21 @@ module.exports = (Plugin, Api, Vendor) => {

REPLACE_modal_colorpicker1_text

-
-
-
+

REPLACE_modal_colorpicker2_text

-
-
-
+

REPLACE_modal_colorpicker3_text

-
-
-
+

REPLACE_modal_colorpicker4_text

-
-
-
+
@@ -141,47 +143,12 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; + this.GuildUtils = BDFDB.WebModules.findByProperties("getGuilds","getGuild"); - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu)) { - this.onContextMenu(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"serverContextObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - var addedNodes = change.addedNodes; - if (change.attributeName == "class" && change.oldValue && change.oldValue.indexOf(BDFDB.disCN.guildplaceholder) > -1) addedNodes = [change.target]; - if (change.attributeName == "draggable" && change.oldValue && change.oldValue == "false") addedNodes = [change.target.parentElement]; - if (addedNodes) { - addedNodes.forEach((node) => { - if (node && node.classList && node.classList.contains(BDFDB.disCN.guild) && !node.querySelector(BDFDB.dotCN.guildserror)) { - var id = BDFDB.getIdOfServer(node); - if (id) this.loadServer(BDFDB.getDivOfServer(id)); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.guilds, {name:"serverListObserver",instance:observer}, {childList: true, subtree:true, attributes:true, attributeFilte: ["class", "draggable"], attributeOldValue: true}); - - setTimeout(() => { - this.loadAllServers(); - },3000); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -193,7 +160,10 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll("[custom-editservers]").forEach(serverDiv => {this.resetServer(BDFDB.getIdOfServer(serverDiv));}); + let data = BDFDB.loadAllData(this, "servers"); + BDFDB.removeAllData(this, "servers"); + BDFDB.WebModules.forceAllUpdates(this); + BDFDB.saveAllData(data, this, "servers"); BDFDB.unloadMessage(this); return true; @@ -206,14 +176,6 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - resetAll () { - if (confirm("Are you sure you want to reset all servers?")) { - BDFDB.removeAllData(this, "servers"); - - document.querySelectorAll("[custom-editservers]").forEach(serverDiv => {this.resetServer(BDFDB.getIdOfServer(serverDiv));}); - } - } - changeLanguageStrings () { this.serverContextEntryMarkup = this.serverContextEntryMarkup.replace("REPLACE_context_localserversettings_text", this.labels.context_localserversettings_text); @@ -235,256 +197,268 @@ module.exports = (Plugin, Api, Vendor) => { this.serverSettingsModalMarkup = this.serverSettingsModalMarkup.replace("REPLACE_btn_save_text", this.labels.btn_save_text); } - onContextMenu (context) { - if (!context || !context.tagName || !context.parentElement || context.querySelector(".localserversettings-item")) return; - var info = BDFDB.getKeyInformation({"node":context, "key":"guild"}); - if (info && BDFDB.getKeyInformation({"node":context, "key":"displayName", "value":"GuildLeaveGroup"})) { - $(context).append(this.serverContextEntryMarkup) - .on("mouseenter", ".localserversettings-item", (e) => { - this.createContextSubMenu(info, e, context); + onGuildContextMenu (instance, menu) { + if (instance.props && instance.props.target && instance.props.guild && !menu.querySelector(".localserversettings-item")) { + let serverContextEntry = BDFDB.htmlToElement(this.serverContextEntryMarkup); + menu.appendChild(serverContextEntry); + let settingsitem = serverContextEntry.querySelector(".localserversettings-item"); + settingsitem.addEventListener("mouseenter", () => { + let serverContextSubMenu = BDFDB.htmlToElement(this.serverContextSubMenuMarkup); + let serveritem = serverContextSubMenu.querySelector(".serversettings-item"); + serveritem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + this.showServerSettings(instance.props.guild); }); - - BDFDB.updateContextPosition(context); - } - } - - createContextSubMenu (info, e, context) { - var id = info.id; - - var serverContextSubMenu = $(this.serverContextSubMenuMarkup); - - serverContextSubMenu - .on("click", ".serversettings-item", () => { - $(context).hide(); - this.showServerSettings(info); + if (BDFDB.loadData(instance.props.guild.id, this, "servers")) { + let resetitem = serverContextSubMenu.querySelector(".resetsettings-item"); + BDFDB.removeClass(resetitem, BDFDB.disCN.contextmenuitemdisabled); + resetitem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + BDFDB.removeData(instance.props.guild.id, this, "servers"); + BDFDB.WebModules.forceAllUpdates(this); + }); + } + BDFDB.appendSubMenu(settingsitem, serverContextSubMenu); }); - - if (BDFDB.loadData(id, this, "servers")) { - serverContextSubMenu - .find(".resetsettings-item") - .removeClass(BDFDB.disCN.contextmenuitemdisabled) - .on("click", () => { - $(context).hide(); - this.removeServerData(info.id); - }); } - - BDFDB.appendSubMenu(e.currentTarget, serverContextSubMenu); } showServerSettings (info) { - var data = BDFDB.loadData(info.id, this, "servers"); + var {name,shortName,url,removeIcon,color1,color2,color3,color4} = BDFDB.loadData(info.id, this, "servers") || {}; - var name = data ? data.name : null; - var shortName = data ? data.shortName : null; - var url = data ? data.url : null; - var removeIcon = data ? data.removeIcon : false; - var color1 = data ? data.color1 : null; - var color2 = data ? data.color2 : null; - var color3 = data ? data.color3 : null; - var color4 = data ? data.color4 : null; + let serverSettingsModal = BDFDB.htmlToElement(this.serverSettingsModalMarkup); + let servernameinput = serverSettingsModal.querySelector("#input-servername"); + let servershortnameinput = serverSettingsModal.querySelector("#input-servershortname"); + let serverurlinput = serverSettingsModal.querySelector("#input-serverurl"); + let removeiconinput = serverSettingsModal.querySelector("#input-removeicon"); + + serverSettingsModal.querySelector(BDFDB.dotCN.modalguildname).innerText = info.name; + servernameinput.value = name || ""; + servernameinput.setAttribute("placeholder", info.name); + servershortnameinput.value = shortName || (info.icon ? "" : info.acronym); + servershortnameinput.setAttribute("placeholder", info.acronym); + serverurlinput.value = url || ""; + serverurlinput.setAttribute("placeholder", BDFDB.getGuildIcon(info.id) || ""); + BDFDB.toggleClass(serverurlinput, "valid", serverurlinput.value.length > 0); + serverurlinput.disabled = removeIcon; + removeiconinput.checked = removeIcon; + BDFDB.setColorSwatches(serverSettingsModal, color1); + BDFDB.setColorSwatches(serverSettingsModal, color2); + BDFDB.setColorSwatches(serverSettingsModal, color3); + BDFDB.setColorSwatches(serverSettingsModal, color4); - var serverSettingsModal = $(this.serverSettingsModalMarkup); - serverSettingsModal.find(BDFDB.dotCN.modalguildname).text(info.name); - serverSettingsModal.find("#input-servername").val(name); - serverSettingsModal.find("#input-servername").attr("placeholder", info.name); - serverSettingsModal.find("#input-servershortname").val(shortName ? shortName : (info.icon ? "" : info.acronym)); - serverSettingsModal.find("#input-servershortname").attr("placeholder", info.acronym); - serverSettingsModal.find("#input-serverurl").val(url); - serverSettingsModal.find("#input-serverurl").attr("placeholder", info.icon ? "https://cdn.discordapp.com/icons/" + info.id + "/" + info.icon + ".png" : null); - serverSettingsModal.find("#input-serverurl").addClass(url ? "valid" : ""); - serverSettingsModal.find("#input-serverurl").prop("disabled", removeIcon); - serverSettingsModal.find("#input-removeicon").prop("checked", removeIcon); - BDFDB.setColorSwatches(color1, serverSettingsModal.find(".swatches1"), "swatch1"); - BDFDB.setColorSwatches(color2, serverSettingsModal.find(".swatches2"), "swatch2"); - BDFDB.setColorSwatches(color3, serverSettingsModal.find(".swatches3"), "swatch3"); - BDFDB.setColorSwatches(color4, serverSettingsModal.find(".swatches4"), "swatch4"); BDFDB.appendModal(serverSettingsModal); - serverSettingsModal - .on("click", "#input-removeicon", (event) => { - serverSettingsModal.find("#input-serverurl").prop("disabled", event.target.checked); - }) - .on("change keyup paste", "#input-serverurl", (event) => { - this.checkUrl(serverSettingsModal, event); - }) - .on("mouseenter", "#input-serverurl", (event) => { - $(event.target).addClass("hovering"); - this.createNoticeTooltip(event); - }) - .on("mouseleave", "#input-serverurl", (event) => { - $(BDFDB.dotCN.tooltips).find(".notice-tooltip").remove(); - $(event.target).removeClass("hovering"); - }) - .on("click", ".btn-save", (event) => { - event.preventDefault(); - name = null; - if (serverSettingsModal.find("#input-servername").val()) { - if (serverSettingsModal.find("#input-servername").val().trim().length > 0) { - name = serverSettingsModal.find("#input-servername").val().trim(); - } - } + removeiconinput.addEventListener("click", () => { + serverurlinput.disabled = removeiconinput.checked; + }); + serverurlinput.addEventListener("input", () => { + this.checkUrl(serverurlinput); + }); + serverurlinput.addEventListener("mouseenter", () => { + BDFDB.addClass(serverurlinput, "hovering"); + this.createNoticeTooltip(serverurlinput); + }); + serverurlinput.addEventListener("mouseleave", () => { + BDFDB.removeClass(serverurlinput, "hovering"); + BDFDB.removeEles(BDFDB.dotCNS.tooltips + ".notice-tooltip"); + }); + BDFDB.addChildEventListener(serverSettingsModal, "click", ".btn-save", e => { + e.preventDefault(); - shortName = null; - if (serverSettingsModal.find("#input-servershortname").val()) { - if (serverSettingsModal.find("#input-servershortname").val().trim().length > 0) { - shortName = serverSettingsModal.find("#input-servershortname").val().trim(); - shortName = shortName == info.acronym ? null : shortName; - } - } + name = servernameinput.value.trim(); + name = name ? name : null; - if (serverSettingsModal.find("#input-serverurl:not('.invalid')").length > 0) { - url = null; - if (!serverSettingsModal.find("#input-removeicon").prop("checked") && serverSettingsModal.find("#input-serverurl").val()) { - if (serverSettingsModal.find("#input-serverurl").val().trim().length > 0) { - url = serverSettingsModal.find("#input-serverurl").val().trim(); - } - } - } + shortName = servershortnameinput.value.trim(); + shortName = shortName && shortName != info.acronym ? shortName : null; - removeIcon = serverSettingsModal.find("#input-removeicon").prop("checked"); + removeIcon = removeiconinput.checked; - color1 = BDFDB.getSwatchColor("swatch1"); - color2 = BDFDB.getSwatchColor("swatch2"); - color3 = BDFDB.getSwatchColor("swatch3"); - color4 = BDFDB.getSwatchColor("swatch4"); + url = !removeIcon && BDFDB.containsClass(serverurlinput, "valid") ? serverurlinput.value.trim() : null; + url = url ? url : null; - if (name == null && shortName == null && url == null && !removeIcon && color1 == null && color2 == null && color3 == null && color4 == null) { - this.removeServerData(info.id); - } - else { - BDFDB.saveData(info.id, {name,shortName,url,removeIcon,color1,color2,color3,color4}, this, "servers"); - this.loadServer(BDFDB.getDivOfServer(info.id)); - } - }); - serverSettingsModal.find("#input-servername").focus(); + color1 = BDFDB.getSwatchColor(serverSettingsModal, 1); + color2 = BDFDB.getSwatchColor(serverSettingsModal, 2); + color3 = BDFDB.getSwatchColor(serverSettingsModal, 3); + color4 = BDFDB.getSwatchColor(serverSettingsModal, 4); + + if (name == null && shortName == null && url == null && !removeIcon && color1 == null && color2 == null && color3 == null && color4 == null) { + BDFDB.removeData(info.id, this, "servers"); + } + else { + BDFDB.saveData(info.id, {name,shortName,url,removeIcon,color1,color2,color3,color4}, this, "servers"); + } + BDFDB.WebModules.forceAllUpdates(this); + }); + servernameinput.focus(); } - checkUrl (modal, e) { - if (!e.target.value) { - $(e.target) - .removeClass("valid") - .removeClass("invalid"); - if ($(e.target).hasClass("hovering")) $(BDFDB.dotCN.tooltips).find(".notice-tooltip").remove(); + checkUrl (input) { + BDFDB.removeEles(BDFDB.dotCNS.tooltips + ".notice-tooltip"); + if (!input.value) { + BDFDB.removeClass(input, "valid"); + BDFDB.removeClass(input, "invalid"); } else { - let request = require("request"); - request(e.target.value, (error, response, result) => { + require("request")(input.value, (error, response, result) => { if (response && response.headers["content-type"] && response.headers["content-type"].indexOf("image") != -1) { - $(e.target) - .removeClass("invalid") - .addClass("valid"); + BDFDB.addClass(input, "valid"); + BDFDB.removeClass(input, "invalid"); } else { - $(e.target) - .removeClass("valid") - .addClass("invalid"); + BDFDB.removeClass(input, "valid"); + BDFDB.addClass(input, "invalid"); } - if ($(e.target).hasClass("hovering")) this.createNoticeTooltip(e); + if (BDFDB.containsClass(input, "hovering")) this.createNoticeTooltip(input); }); } } - createNoticeTooltip (e) { - $(BDFDB.dotCN.tooltips).find(".notice-tooltip").remove(); - - var input = e.target; - var disabled = $(input).prop("disabled"); - var valid = $(input).hasClass("valid"); - var invalid = $(input).hasClass("invalid"); + createNoticeTooltip (input) { + var disabled = input.disabled; + var valid = BDFDB.containsClass(input, "valid"); + var invalid = BDFDB.containsClass(input, "invalid"); if (disabled || valid || invalid) { - var text = disabled ? this.labels.modal_ignoreurl_text : valid ? this.labels.modal_validurl_text : this.labels.modal_invalidurl_text; - var bgColor = disabled ? "#282524" : valid ? "#297828" : "#8C2528"; - var customTooltipCSS = ` - body .notice-tooltip { - background-color: ${bgColor} !important; + BDFDB.createTooltip(disabled ? this.labels.modal_ignoreurl_text : valid ? this.labels.modal_validurl_text : this.labels.modal_invalidurl_text, input, {type:"right",selector:"notice-tooltip",color: disabled ? "black" : invalid ? "red" : "green"}); + } + } + + processGuildIcon (instance, wrapper) { + if (instance.props && instance.props.guild) { + let icon = wrapper.classList && BDFDB.containsClass(wrapper, BDFDB.disCN.avataricon) ? wrapper : wrapper.querySelector(BDFDB.dotCN.avataricon); + if (!icon) return; + this.changeGuildIcon(instance.props.guild, icon); + if (BDFDB.getParentEle(BDFDB.dotCN.guild, icon)) this.changeTooltip(instance.props.guild, wrapper, "right"); + else if (BDFDB.getParentEle(BDFDB.dotCN.friendscolumn, icon)) this.changeTooltip(instance.props.guild, icon.parentElement, "top"); + } + } + + processGuildHeader (instance, wrapper) { + if (instance.props && instance.props.guild) { + this.changeGuildName(instance.props.guild, wrapper.querySelector(BDFDB.dotCN.guildheadername)); + } + } + + processClickable (instance, wrapper) { + if (!wrapper || !instance.props || !instance.props.className) return; + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.userprofilelistrow) > -1) { + let guild = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.guild"); + if (guild && BDFDB.getReactValue(instance, "_reactInternalFiber.return.type.displayName") == "GuildRow") { + this.changeGuildName(guild, wrapper.querySelector(BDFDB.dotCN.userprofilelistname)); + } + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.quickswitchresult) > -1) { + let result = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.result"); + if (result && result.type == "GUILD") { + this.changeGuildName(result.record, wrapper.querySelector(BDFDB.dotCN.quickswitchresultmatch)); + } + else if (result && result.type.indexOf("_CHANNEL") != -1 && result.record && result.record.guild_id) { + this.changeGuildName(this.GuildUtils.getGuild(result.record.guild_id), wrapper.querySelector(BDFDB.dotCN.quickswitchresultmisccontainer)); + } + } + } + + changeGuildName (info, guildname) { + if (!info || !guildname || !guildname.parentElement) return; + if (guildname.EditServersChangeObserver && typeof guildname.EditServersChangeObserver.disconnect == "function") guildname.EditServersChangeObserver.disconnect(); + let data = BDFDB.loadData(info.id, this, "servers") || {}; + if (data.name || data.color2 || guildname.getAttribute("changed-by-editservers")) { + guildname.style.setProperty("color", BDFDB.colorCONVERT(data.color2, "RGB"), "important"); + BDFDB.setInnerText(guildname, data.name || info.name); + if (data.name || data.color2) { + guildname.setAttribute("changed-by-editservers", true); + guildname.EditServersChangeObserver = new MutationObserver((changes, _) => { + guildname.EditServersChangeObserver.disconnect(); + this.changeName(info, guildname); + }); + guildname.EditServersChangeObserver.observe(guildname, {attributes:true}); + } + else guildname.removeAttribute("changed-by-editservers"); + } + } + + changeGuildIcon (info, icon) { + if (!info || !icon || !icon.parentElement) return; + if (icon.EditServersChangeObserver && typeof icon.EditServersChangeObserver.disconnect == "function") icon.EditServersChangeObserver.disconnect(); + let data = BDFDB.loadData(info.id, this, "servers") || {}; + if (data.url || data.removeIcon || icon.getAttribute("changed-by-editservers")) { + if (icon.tagName == "IMG") icon.setAttribute("src", data.removeIcon ? null : (data.url || BDFDB.getGuildIcon(info.id))); + else { + BDFDB.setInnerText(icon, data.url ? "" : (data.shortName || (info.icon && !data.removeIcon ? "" : info.acronym))); + icon.style.setProperty("background-image", data.removeIcon || data.shortName ? null : `url(${data.url || BDFDB.getGuildIcon(info.id)})`); + icon.style.setProperty("background-color", BDFDB.colorCONVERT(data.color1, "RGB"), "important"); + icon.style.setProperty("color", BDFDB.colorCONVERT(data.color2, "RGB", "important")); + icon.style.setProperty("font-size", this.getFontSize(icon)); + let hasicon = icon.style.getPropertyValue("background-image"); + if (hasicon) BDFDB.removeClass(icon, this.getNoIconClasses(icon)); + else BDFDB.addClass(icon, this.getNoIconClasses(icon)); + if (data.url && !data.removeIcon) { + icon.style.setProperty("background-position", "center"); + icon.style.setProperty("background-size", "cover"); } - body .notice-tooltip:after { - border-right-color: ${bgColor} !important; - }`; - BDFDB.createTooltip(text, input, {type:"right",selector:"notice-tooltip",css:customTooltipCSS}); + } + if (data.url || data.removeIcon) { + icon.setAttribute("changed-by-editservers", true); + icon.EditServersChangeObserver = new MutationObserver((changes, _) => { + changes.forEach( + (change, i) => { + icon.EditServersChangeObserver.disconnect(); + this.changeGuildIcon(info, icon); + } + ); + }); + icon.EditServersChangeObserver.observe(icon, {attributes:true}); + } + else icon.removeAttribute("changed-by-editservers"); } } - removeServerData (id) { - this.resetServer(id); - - BDFDB.removeData(id, this, "servers"); - } - - resetServer (id) { - let serverObj = BDFDB.getDivOfServer(id); - if (typeof serverObj !== "object" || !serverObj) return; - $(serverObj.div) - .off("mouseenter." + this.name) - .removeAttr("custom-editservers") - .find(BDFDB.dotCN.avataricon) - .text(serverObj.icon ? "" : serverObj.data.acronym) - .css("background-image", serverObj.icon ? "url('https://cdn.discordapp.com/icons/" + serverObj.id + "/" + serverObj.icon + ".png')" : "") - .css("background-color", "") - .css("color", ""); - } - - loadServer (serverObj) { - if (typeof serverObj !== "object" || !serverObj) return; - var data = BDFDB.loadData(serverObj.id, this, "servers"); - if (data) { - var name = data.name ? data.name : serverObj.name; - var shortName = data.shortName ? data.shortName : (serverObj.icon ? "" : serverObj.data.acronym); - var bgImage = data.url ? "url(" + data.url + ")" : (serverObj.icon ? "url('https://cdn.discordapp.com/icons/" + serverObj.id + "/" + serverObj.icon + ".png')" : ""); - var removeIcon = data.removeIcon; - var color1 = data.color1 ? BDFDB.color2RGB(data.color1) : ""; - var color2 = data.color2 ? BDFDB.color2RGB(data.color2) : ""; - $(serverObj.div) - .off("mouseenter." + this.name) - .on("mouseenter." + this.name, () => {this.createServerToolTip(serverObj);}) - .attr("custom-editservers", true) - .find(BDFDB.dotCN.avataricon) - .text(data.shortName ? shortName : (removeIcon ? "" : shortName)) - .css("background-image", removeIcon ? "" : bgImage) - .css("background-color", color1) - .css("color", color2); + changeTooltip (info, wrapper, type) { + if (!info || !wrapper || !wrapper.parentElement) return; + let data = BDFDB.loadData(info.id, this, "servers") || {}; + wrapper.removeEventListener("mouseenter", wrapper.tooltipListenerEditServers); + if (data.name || data.color3 || data.color4) { + var bgColor = data.color3 ? BDFDB.colorCONVERT(data.color3, "RGB") : ""; + var fontColor = data.color4 ? BDFDB.colorCONVERT(data.color4, "RGB") : ""; + wrapper.tooltipListenerEditServers = () => { + BDFDB.createTooltip(data.name || info.name, wrapper, {type,selector:"EditServers-tooltip",style:`color: ${fontColor} !important; background-color: ${bgColor} !important; border-color: ${bgColor} !important;`,css:`body ${BDFDB.dotCN.tooltip}:not(.EditServers-tooltip) {display: none !important;}`}); + }; + wrapper.addEventListener("mouseenter", wrapper.tooltipListenerEditServers); } } - loadAllServers () { - var serverObjs = BDFDB.readServerList(); - for (var i = 0; i < serverObjs.length; i++) { - this.loadServer(serverObjs[i]); - } + getFontSize (icon) { + if (icon.style.getPropertyValue("background-image")) return null; + else if (BDFDB.containsClass(icon, BDFDB.disCN.avatariconsizexlarge)) return "12px"; + else if (BDFDB.containsClass(icon, BDFDB.disCN.avatariconsizelarge)) return "10px"; + else if (BDFDB.containsClass(icon, BDFDB.disCN.avatariconsizemedium)) return "8px"; + else if (BDFDB.containsClass(icon, BDFDB.disCN.avatariconsizesmall)) return "4.8px"; + else if (BDFDB.containsClass(icon, BDFDB.disCN.avatariconsizemini)) return "4px"; + else return "10px"; } - createServerToolTip (serverObj) { - var data = BDFDB.loadData(serverObj.id, this, "servers"); - if (data) { - var text = data.name ? data.name : serverObj.name; - var bgColor = data.color3 ? BDFDB.color2RGB(data.color3) : ""; - var fontColor = data.color4 ? BDFDB.color2RGB(data.color4) : ""; - var customTooltipCSS = ` - body ${BDFDB.dotCN.tooltip}:not(.guild-custom-tooltip) { - display: none !important; - } - body .guild-custom-tooltip { - color: ${fontColor} !important; - background-color: ${bgColor} !important; - } - body .guild-custom-tooltip:after { - border-right-color: ${bgColor} !important; - }`; - - BDFDB.createTooltip(text, serverObj.div, {type:"right",selector:"guild-custom-tooltip",css:customTooltipCSS}); - } + getNoIconClasses (icon) { + let noiconclasses = [BDFDB.disCN.avatarnoicon]; + if (BDFDB.containsClass(icon, BDFDB.disCN.userprofilelistavatar)) noiconclasses.push(BDFDB.disCN.userprofilelistguildavatarwithouticon); + return noiconclasses; } getSettingsPanel () { - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + var settingshtml = `
${this.name}
`; settingshtml += `

Reset all Servers.

`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", ".reset-button", () => {this.resetAll();}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "click", ".reset-button", () => { + BDFDB.openConfirmModal(this, "Are you sure you want to reset all servers?", () => { + BDFDB.removeAllData(this, "servers"); + BDFDB.WebModules.forceAllUpdates(this); + }); + }); return settingspanel; } diff --git a/PluginsV2/EditUsers/index.js b/PluginsV2/EditUsers/index.js index fa0d9eebe3..abaf67a6b8 100644 --- a/PluginsV2/EditUsers/index.js +++ b/PluginsV2/EditUsers/index.js @@ -5,35 +5,36 @@ module.exports = (Plugin, Api, Vendor) => { initConstructor () { this.labels = {}; - this.updateUsers = false; + this.patchModules = { + "ChannelTextArea":"componentDidMount", + "NameTag":"componentDidMount", + "AuditLog":"componentDidMount", + "FluxContainer(TypingUsers)":"componentDidUpdate", + "MessageUsername":"componentDidMount", + "DirectMessage":"componentDidMount", + "CallAvatar":"componentDidMount", + "PrivateChannel":["componentDidMount","componentDidUpdate"], + "HeaderBar":["componentDidMount","componentDidUpdate"], + "Clickable":"componentDidMount", + "MessageContent":["componentDidMount","componentDidUpdate"] + }; + + this.avatarselector = BDFDB.dotCNC.avatarinner + BDFDB.dotCNC.avatarimage + BDFDB.dotCNC.callavatarwrapper + BDFDB.dotCNC.voiceavatarcontainer + "[class*='avatar-']"; this.css = ` - .user-tag { - border-radius: 3px; - box-sizing: border-box; - display: inline-block; - flex-shrink: 0; - font-size: 10px; - font-weight: 500; - line-height: 13px; - margin-left: 6px; - padding: 1px 2px; - text-transform: uppercase; - text-indent: 0px !important; - vertical-align: top; - } - ${BDFDB.dotCN.messagecompact} .user-tag { - margin-left: 2px; - margin-right: 6px; - } - .user-tag.popout-tag, - .user-tag.profil-tag { + ${BDFDB.dotCN.bottag} { + top: -4px; position: relative; - top: 2px; + margin-left: 1ch; + } + ${BDFDB.dotCN.friendscolumn} ${BDFDB.dotCN.bottag}, + ${BDFDB.dotCN.memberusername} ~ ${BDFDB.dotCN.bottag} { + top: 0px; + } + ${BDFDB.dotCN.messagegroupcompact} ${BDFDB.dotCN.bottag} { + margin-right: 6px; }`; - this.tagMarkup = ``; - this.userContextEntryMarkup = `
@@ -57,27 +58,33 @@ module.exports = (Plugin, Api, Vendor) => {
`; this.userSettingsModalMarkup = - ` + `
-
+

REPLACE_modal_header_text

- - - - - - +
-
-
REPLACE_modal_tabheader1_text
-
REPLACE_modal_tabheader2_text
-
REPLACE_modal_tabheader3_text
+
+
+
REPLACE_modal_tabheader1_text
+
REPLACE_modal_tabheader2_text
+
REPLACE_modal_tabheader3_text
+
@@ -111,29 +118,21 @@ module.exports = (Plugin, Api, Vendor) => {

REPLACE_modal_colorpicker1_text

-
-
-
+

REPLACE_modal_colorpicker2_text

-
-
-
+

REPLACE_modal_colorpicker3_text

-
-
-
+

REPLACE_modal_colorpicker4_text

-
-
-
+

REPLACE_modal_ignoretagcolor_text

@@ -155,7 +154,9 @@ module.exports = (Plugin, Api, Vendor) => { this.defaults = { settings: { - changeInChatWindow: {value:true, description:"Chat"}, + changeInChatTextarea: {value:true, description:"Chat Textarea"}, + changeInChatWindow: {value:true, description:"Messages"}, + changeInMentions: {value:true, description:"Mentions"}, changeInVoiceChat: {value:true, description:"Voice Channels"}, changeInMemberList: {value:true, description:"Member List"}, changeInRecentDms: {value:true, description:"Direct Message Notifications"}, @@ -164,8 +165,12 @@ module.exports = (Plugin, Api, Vendor) => { changeInDmCalls: {value:true, description:"Direct Message Calls"}, changeInTyping: {value:true, description:"Typing List"}, changeInFriendList: {value:true, description:"Friend List"}, + changeInActivity: {value:true, description:"Activity Page"}, changeInUserPopout: {value:true, description:"User Popouts"}, - changeInUserProfil: {value:true, description:"User Profil Modal"}, + changeInUserProfil: {value:true, description:"User Profile Modal"}, + changeInAutoComplete: {value:true, description:"Autocomplete Menu"}, + changeInAuditLog: {value:true, description:"Audit Log"}, + changeInSearchPopout: {value:true, description:"Search Popout"}, changeInUserAccount: {value:true, description:"Your Account Information"} } }; @@ -191,232 +196,17 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - this.UserStore = BDFDB.WebModules.findByProperties("getUsers", "getUser"); - this.MemberPerms = BDFDB.WebModules.findByProperties("getNicknames", "getNick"); - this.TypingUtils = BDFDB.WebModules.findByProperties("getTypingUsers"); + this.RelationshipUtils = BDFDB.WebModules.findByProperties("isBlocked", "isFriend"); + this.UserUtils = BDFDB.WebModules.findByProperties("getUsers","getUser"); + this.MemberUtils = BDFDB.WebModules.findByProperties("getMembers", "getMember"); + this.ChannelUtils = BDFDB.WebModules.findByProperties("getChannels","getChannel"); this.LastGuildStore = BDFDB.WebModules.findByProperties("getLastSelectedGuildId"); this.LastChannelStore = BDFDB.WebModules.findByProperties("getLastSelectedChannelId"); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu)) { - this.onContextMenu(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"userContextObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (BDFDB.getData("changeInRecentDms", this, "settings")) this.loadUser(node, "recentdms", false); - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.dms, {name:"dmObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.classList && node.classList.length > 0 && node.classList.contains(BDFDB.disCN.dmchannel) && node.classList.contains(BDFDB.disCN.dmchannelprivate) && BDFDB.getData("changeInDmsList", this, "settings")) { - this.loadUser(node, "dms", false); - } - if (node.tagName && node.querySelector(BDFDB.dotCN.voiceuserdefault) && BDFDB.getData("changeInVoiceChat", this, "settings")) { - this.loadUser(node.querySelector(BDFDB.dotCN.voiceuserdefault).parentElement, "voice", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.channels, {name:"channelListObserver",instance:observer}, {childList: true, subtree: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.querySelector(BDFDB.dotCN.friendscolumn) && BDFDB.getData("changeInFriendList", this, "settings")) { - this.loadUser(node, "friends", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.idCN.friends, {name:"friendListObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.querySelector(BDFDB.dotCN.memberusername) && BDFDB.getData("changeInMemberList", this, "settings")) { - this.loadUser(node, "list", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.memberswrap, {name:"userListObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (BDFDB.getData("changeInChatWindow", this, "settings")) { - var compact = document.querySelector(BDFDB.dotCN.messagegroup + BDFDB.dotCN.messagecompact); - if (!compact) { - if (node.tagName && node.querySelector(BDFDB.dotCN.messageusernamewrapper)) { - this.loadUser(node, "chat", compact); - } - else if (node.classList && node.classList.contains(BDFDB.disCN.messagetext)) { - this.loadUser($(BDFDB.dotCN.messagegroup).has(node)[0], "chat", compact); - } - } - else { - if (node.tagName && node.querySelector(BDFDB.dotCN.messageusernamewrapper)) { - if (node.classList.contains(BDFDB.disCN.messagemarkup)) { - this.loadUser(node, "chat", compact); - } - else { - for (let markup of node.querySelectorAll(BDFDB.dotCN.messagemarkup)) this.loadUser(markup, "chat", compact); - } - } - } - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"messagesObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.classList.contains(BDFDB.disCN.typing) && BDFDB.getData("changeInTyping", this, "settings")) { - let innerobserver = new MutationObserver((changes2, _) => { - changes2.forEach( - (change2, i) => { - if (change2.addedNodes) { - change2.addedNodes.forEach((node2) => { - if (node2.tagName && node2.tagName == "STRONG") this.changeTyping(node); - }); - } - if (change2.removedNodes) { - change2.removedNodes.forEach((node2) => { - if (node2.tagName && node2.tagName == "STRONG") this.changeTyping(node); - }); - } - } - ); - }); - innerobserver.observe(node, {childList:true, subtree:true}); - this.changeTyping(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCNS.chat + "form", {name:"chatFormObserver",instance:observer}, {childList:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.classList.contains(BDFDB.disCN.callcurrentcontainer) && BDFDB.getData("changeInDmCalls", this, "settings")) { - for (let user of node.querySelectorAll(BDFDB.dotCN.callavatarwrapper)) this.loadUser(user, "call", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.chat, {name:"chatObserver",instance:observer}, {childList:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - let user; - if (node.tagName && (user = node.querySelector(BDFDB.dotCN.callavatarwrapper)) != null && BDFDB.getData("changeInDmCalls", this, "settings")) { - this.loadUser(user, "call", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.callcurrentcontainer, {name:"callObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.querySelector(BDFDB.dotCN.userpopout) && BDFDB.getData("changeInUserPopout", this, "settings")) { - this.loadUser(node, "popout", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.popouts, {name:"userPopoutObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.tagName && node.querySelector(BDFDB.dotCN.userprofile) && BDFDB.getData("changeInUserProfil", this, "settings")) { - this.loadUser(node.querySelector("[class*='topSection']"), "profil", false); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.app + " ~ [class^='theme-']:not([class*='popouts'])", {name:"userProfilModalObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.removedNodes) { - change.removedNodes.forEach((node) => { - if (node.tagName && node.getAttribute("layer-id") == "user-settings") this.loadAllUsers(); - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.layers, {name:"settingsWindowObserver",instance:observer}, {childList:true}); - - this.loadAllUsers(); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -428,7 +218,12 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - this.resetAllUsers(); + let data = BDFDB.loadAllData(this, "users"); + BDFDB.removeAllData(this, "users"); + BDFDB.WebModules.forceAllUpdates(this); + BDFDB.saveAllData(data, this, "users"); + + BDFDB.removeEles(".autocompleteEditUsers", ".autocompleteEditUsersRow"); BDFDB.unloadMessage(this); return true; @@ -438,37 +233,9 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - $(`${BDFDB.dotCN.channelheadertitletext}[custom-editusers]`).find(`${BDFDB.dotCN.channelheaderchannelname}:not(${BDFDB.dotCN.channelheaderprivate})`).css("color", "").css("background-color", "").parent().removeAttr("custom-editusers"); - BDFDB.addObserver(this, BDFDB.dotCN.memberswrap, {name:"userListObserver"}, {childList:true, subtree:true}); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"messagesObserver"}, {childList:true, subtree:true}); - BDFDB.addObserver(this, BDFDB.dotCNS.chat + "form", {name:"chatFormObserver"}, {childList:true}); - BDFDB.addObserver(this, BDFDB.dotCN.chat, {name:"chatObserver"}, {childList:true}); - BDFDB.addObserver(this, BDFDB.dotCN.callcurrentcontainer, {name:"callObserver"}, {childList:true, subtree:true}); - BDFDB.addObserver(this, BDFDB.idCN.friends, {name:"friendListObserver"}, {childList:true, subtree:true}); - this.loadAllUsers(); - } - } - // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - - resetAll () { - if (confirm("Are you sure you want to reset all users?")) { - BDFDB.removeAllData(this, "users"); - this.resetAllUsers(); - } - } - changeLanguageStrings () { this.userContextEntryMarkup = this.userContextEntryMarkup.replace("REPLACE_context_localusersettings_text", this.labels.context_localusersettings_text); @@ -492,444 +259,743 @@ module.exports = (Plugin, Api, Vendor) => { this.userSettingsModalMarkup = this.userSettingsModalMarkup.replace("REPLACE_btn_save_text", this.labels.btn_save_text); } - onContextMenu (context) { - if (!context || !context.tagName || !context.parentElement || context.querySelector(".localusersettings-item")) return; - var info = BDFDB.getKeyInformation({"node":context, "key":"user"}); - if (info && BDFDB.getKeyInformation({"node":context, "key":"displayName", "value":"UserNoteItem"})) { - $(context).append(this.userContextEntryMarkup) - .on("mouseenter", ".localusersettings-item", (e) => { - this.createContextSubMenu(info, e, context); + onUserContextMenu (instance, menu) { + if (instance.props && instance.props.user && !menu.querySelector(".localusersettings-item")) { + let userContextEntry = BDFDB.htmlToElement(this.userContextEntryMarkup); + menu.appendChild(userContextEntry); + let settingsitem = userContextEntry.querySelector(".localusersettings-item"); + settingsitem.addEventListener("mouseenter", () => { + let userContextSubMenu = BDFDB.htmlToElement(this.userContextSubMenuMarkup); + let useritem = userContextSubMenu.querySelector(".usersettings-item"); + useritem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + this.showUserSettings(instance.props.user); }); - - BDFDB.updateContextPosition(context); - } - } - - createContextSubMenu (info, e, context) { - var userContextSubMenu = $(this.userContextSubMenuMarkup); - - userContextSubMenu - .on("click", ".usersettings-item", () => { - $(context).hide(); - this.showUserSettings(info); + if (BDFDB.loadData(instance.props.user.id, this, "users")) { + let resetitem = userContextSubMenu.querySelector(".resetsettings-item"); + BDFDB.removeClass(resetitem, BDFDB.disCN.contextmenuitemdisabled); + resetitem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + BDFDB.removeData(instance.props.user.id, this, "users"); + BDFDB.WebModules.forceAllUpdates(this); + }); + } + BDFDB.appendSubMenu(settingsitem, userContextSubMenu); }); - - if (BDFDB.loadData(info.id, this, "users")) { - userContextSubMenu - .find(".resetsettings-item") - .removeClass(BDFDB.disCN.contextmenuitemdisabled) - .on("click", () => { - $(context).hide(); - BDFDB.removeData(info.id, this, "users"); - this.loadAllUsers(); - }); } - - BDFDB.appendSubMenu(e.currentTarget, userContextSubMenu); } - showUserSettings (info, e) { - var data = BDFDB.loadData(info.id, this, "users"); + showUserSettings (info) { + var {name,tag,url,removeIcon,ignoreTagColor,color1,color2,color3,color4} = BDFDB.loadData(info.id, this, "users") || {}; - var name = data ? data.name : null; - var tag = data ? data.tag : null; - var url = data ? data.url : null; - var removeIcon = data ? data.removeIcon : false; - var ignoreTagColor = data && data.ignoreTagColor ? data.ignoreTagColor : false; - var color1 = data ? data.color1 : null; - var color2 = data ? data.color2 : null; - var color3 = data ? data.color3 : null; - var color4 = data ? data.color4 : null; + var member = this.MemberUtils.getMember(this.LastGuildStore.getGuildId(), info.id) || {}; - var member = this.MemberPerms.getMember(this.LastGuildStore.getGuildId(), info.id) ; + let userSettingsModal = BDFDB.htmlToElement(this.userSettingsModalMarkup); + let usernameinput = userSettingsModal.querySelector("#input-username"); + let usertaginput = userSettingsModal.querySelector("#input-usertag"); + let userurlinput = userSettingsModal.querySelector("#input-userurl"); + let removeiconinput = userSettingsModal.querySelector("#input-removeicon"); + let ignoretagcolorinput = userSettingsModal.querySelector("#input-ignoretagcolor"); + + userSettingsModal.querySelector(BDFDB.dotCN.modalguildname).innerText = member.nick || info.username; + usernameinput.value = name || ""; + usernameinput.setAttribute("placeholder", member.nick || info.username); + usertaginput.value = tag || ""; + userurlinput.value = url || ""; + userurlinput.setAttribute("placeholder", BDFDB.getUserAvatar(info.id) || ""); + BDFDB.toggleClass(userurlinput, "valid", userurlinput.value.length > 0); + userurlinput.disabled = removeIcon; + removeiconinput.checked = removeIcon; + ignoretagcolorinput.checked = ignoreTagColor; + BDFDB.setColorSwatches(userSettingsModal, color1); + BDFDB.setColorSwatches(userSettingsModal, color2); + BDFDB.setColorSwatches(userSettingsModal, color3); + BDFDB.setColorSwatches(userSettingsModal, color4); + + let ignoredswatches = userSettingsModal.querySelectorAll(".swatches[swatchnr='3'], .swatches[swatchnr='4']"); + + BDFDB.toggleClass(ignoredswatches, "disabled", ignoretagcolorinput.checked); - var userSettingsModal = $(this.userSettingsModalMarkup); - userSettingsModal.find(BDFDB.dotCN.modalguildname).text(member && member.nick ? member.nick : info.username); - userSettingsModal.find("#input-username").val(name); - userSettingsModal.find("#input-username").attr("placeholder", member && member.nick ? member.nick : info.username); - userSettingsModal.find("#input-usertag").val(tag); - userSettingsModal.find("#input-userurl").val(url); - userSettingsModal.find("#input-userurl").attr("placeholder", BDFDB.getUserAvatar(info.id)); - userSettingsModal.find("#input-userurl").addClass(url ? "valid" : ""); - userSettingsModal.find("#input-userurl").prop("disabled", removeIcon); - userSettingsModal.find("#input-removeicon").prop("checked", removeIcon); - userSettingsModal.find(".swatches3, .swatches4").toggleClass("disabled", ignoreTagColor); - userSettingsModal.find("#input-ignoretagcolor").prop("checked", ignoreTagColor); - BDFDB.setColorSwatches(color1, userSettingsModal.find(".swatches1"), "swatch1"); - BDFDB.setColorSwatches(color2, userSettingsModal.find(".swatches2"), "swatch2"); - BDFDB.setColorSwatches(color3, userSettingsModal.find(".swatches3"), "swatch3"); - BDFDB.setColorSwatches(color4, userSettingsModal.find(".swatches4"), "swatch4"); BDFDB.appendModal(userSettingsModal); - userSettingsModal - .on("click", "#input-removeicon", (event) => { - userSettingsModal.find("#input-userurl").prop("disabled", event.target.checked); - }) - .on("click", "#input-ignoretagcolor", (event) => { - userSettingsModal.find(".swatches3, .swatches4").toggleClass("disabled", event.target.checked); - }) - .on("change keyup paste", "#input-userurl", (event) => { - this.checkUrl(userSettingsModal, event); - }) - .on("mouseenter", "#input-userurl", (event) => { - $(event.target).addClass("hovering"); - this.createNoticeTooltip(event); - }) - .on("mouseleave", "#input-userurl", (event) => { - $(BDFDB.dotCN.tooltips).find(".notice-tooltip").remove(); - $(event.target).removeClass("hovering"); - }) - .on("click", ".btn-save", (event) => { - event.preventDefault(); - removeIcon = userSettingsModal.find("#input-removeicon").prop("checked"); - ignoreTagColor = userSettingsModal.find("#input-ignoretagcolor").prop("checked"); + removeiconinput.addEventListener("click", () => { + userurlinput.disabled = removeiconinput.checked; + }); + ignoretagcolorinput.addEventListener("click", () => { + BDFDB.toggleClass(ignoredswatches, "disabled", ignoretagcolorinput.checked); + }); + userurlinput.addEventListener("input", () => { + this.checkUrl(userurlinput); + }); + userurlinput.addEventListener("mouseenter", () => { + BDFDB.addClass(userurlinput, "hovering"); + this.createNoticeTooltip(userurlinput); + }); + userurlinput.addEventListener("mouseleave", () => { + BDFDB.removeClass(userurlinput, "hovering"); + BDFDB.removeEles(BDFDB.dotCNS.tooltips + ".notice-tooltip"); + }); + BDFDB.addChildEventListener(userSettingsModal, "click", ".btn-save", e => { + e.preventDefault(); - name = null; - if (userSettingsModal.find("#input-username").val()) { - if (userSettingsModal.find("#input-username").val().trim().length > 0) { - name = userSettingsModal.find("#input-username").val().trim(); - } - } + name = usernameinput.value.trim(); + name = name ? name : null; - tag = null; - if (userSettingsModal.find("#input-usertag").val()) { - if (userSettingsModal.find("#input-usertag").val().trim().length > 0) { - tag = userSettingsModal.find("#input-usertag").val().trim(); - } - } + tag = usertaginput.value.trim(); + tag = tag ? tag : null; - if (userSettingsModal.find("#input-userurl:not('.invalid')").length > 0) { - url = null; - if (!removeIcon && userSettingsModal.find("#input-userurl").val()) { - if (userSettingsModal.find("#input-userurl").val().trim().length > 0) { - url = userSettingsModal.find("#input-userurl").val().trim(); - } - } - } + removeIcon = removeiconinput.checked; - color1 = BDFDB.getSwatchColor("swatch1"); - color2 = BDFDB.getSwatchColor("swatch2"); - color3 = BDFDB.getSwatchColor("swatch3"); - color4 = BDFDB.getSwatchColor("swatch4"); + ignoreTagColor = ignoretagcolorinput.checked; - if (name == null && tag == null && url == null && !removeIcon && !ignoreTagColor && color1 == null && color2 == null && color3 == null && color4 == null) { - BDFDB.removeData(info.id, this, "users") - } - else { - BDFDB.saveData(info.id, {name,tag,url,removeIcon,ignoreTagColor,color1,color2,color3,color4}, this, "users"); - } - this.loadAllUsers(); - }); - userSettingsModal.find("#input-username").focus(); + url = !removeIcon && BDFDB.containsClass(userurlinput, "valid") ? userurlinput.value.trim() : null; + url = url ? url : null; + + color1 = BDFDB.getSwatchColor(userSettingsModal, 1); + color2 = BDFDB.getSwatchColor(userSettingsModal, 2); + color3 = BDFDB.getSwatchColor(userSettingsModal, 3); + color4 = BDFDB.getSwatchColor(userSettingsModal, 4); + + if (name == null && tag == null && url == null && !removeIcon && !ignoreTagColor && color1 == null && color2 == null && color3 == null && color4 == null) { + BDFDB.removeData(info.id, this, "users") + } + else { + BDFDB.saveData(info.id, {name,tag,url,removeIcon,ignoreTagColor,color1,color2,color3,color4}, this, "users"); + } + BDFDB.WebModules.forceAllUpdates(this); + }); + usernameinput.focus(); } - checkUrl (modal, e) { - if (!e.target.value) { - $(e.target) - .removeClass("valid") - .removeClass("invalid"); - if ($(e.target).hasClass("hovering")) $(BDFDB.dotCNS.tooltips + ".notice-tooltip").remove(); + checkUrl (input) { + BDFDB.removeEles(BDFDB.dotCNS.tooltips + ".notice-tooltip"); + if (!input.value) { + BDFDB.removeClass(input, "valid"); + BDFDB.removeClass(input, "invalid"); } else { - let request = require("request"); - request(e.target.value, (error, response, result) => { + require("request")(input.value, (error, response, result) => { if (response && response.headers["content-type"] && response.headers["content-type"].indexOf("image") != -1) { - $(e.target) - .removeClass("invalid") - .addClass("valid"); + BDFDB.addClass(input, "valid"); + BDFDB.removeClass(input, "invalid"); } else { - $(e.target) - .removeClass("valid") - .addClass("invalid"); + BDFDB.removeClass(input, "valid"); + BDFDB.addClass(input, "invalid"); } - if ($(e.target).hasClass("hovering")) this.createNoticeTooltip(e); + if (BDFDB.containsClass(input, "hovering")) this.createNoticeTooltip(input); }); } } - createNoticeTooltip (e) { - $(BDFDB.dotCN.tooltips).find(".notice-tooltip").remove(); - - var input = e.target; - var disabled = $(input).prop("disabled"); - var valid = $(input).hasClass("valid"); - var invalid = $(input).hasClass("invalid"); + createNoticeTooltip (input) { + var disabled = input.disabled; + var valid = BDFDB.containsClass(input, "valid"); + var invalid = BDFDB.containsClass(input, "invalid"); if (disabled || valid || invalid) { - var text = disabled ? this.labels.modal_ignoreurl_text : valid ? this.labels.modal_validurl_text : this.labels.modal_invalidurl_text; - var bgColor = disabled ? "#282524" : valid ? "#297828" : "#8C2528"; - var customTooltipCSS = ` - body .notice-tooltip { - background-color: ${bgColor} !important; - } - body .notice-tooltip:after { - border-right-color: ${bgColor} !important; - }`; - BDFDB.createTooltip(text, input, {type:"right",selector:"notice-tooltip",css:customTooltipCSS}); + BDFDB.createTooltip(disabled ? this.labels.modal_ignoreurl_text : valid ? this.labels.modal_validurl_text : this.labels.modal_invalidurl_text, input, {type:"right",selector:"notice-tooltip",color: disabled ? "black" : invalid ? "red" : "green"}); } } - loadAllUsers () { - this.resetAllUsers(); - - var settings = BDFDB.getAllData(this, "settings"); - - if (settings.changeInMemberList) { - for (let user of document.querySelectorAll(BDFDB.dotCN.member)) { - this.loadUser(user, "list", false); - } - } - if (settings.changeInChatWindow) { - for (let user of document.querySelectorAll(BDFDB.dotCN.messagegroup)) { - if (user.querySelector(BDFDB.dotCN.avatarlargeold)) { - this.loadUser(user, "chat", false); + processChannelTextArea (instance, wrapper) { + let channel = BDFDB.getReactValue(instance, "props.channel"); + if (channel) { + var textarea = wrapper.querySelector("textarea"); + if (!textarea) return; + if (instance.props.type == "normal" && channel.type == 1) { + let user = this.UserUtils.getUser(channel.recipients[0]); + if (user) { + let data = this.getUserData(user.id, wrapper); + textarea.setAttribute("placeholder", BDFDB.LanguageStrings.TEXTAREA_PLACEHOLDER.replace("{{channel}}", "@" + (data.name || user.username))); } - else { - for (let markup of user.querySelectorAll(BDFDB.dotCN.messagemarkup)) { - this.loadUser(markup, "chat", true); + } + if (BDFDB.getData("changeInAutoComplete", this, "settings")) { + BDFDB.addEventListener(this, textarea, "keydown", e => { + let autocompletemenu = textarea.parentElement.querySelector(BDFDB.dotCN.autocomplete); + if (autocompletemenu && (e.which == 9 || e.which == 13)) { + if (BDFDB.containsClass(autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected).parentElement, "autocompleteEditUsersRow")) { + e.originalEvent.preventDefault(); + e.originalEvent.stopPropagation(); + this.swapWordWithMention(textarea); + } } - } - } - } - if (settings.changeInVoiceChat) { - for (let user of document.querySelectorAll(BDFDB.dotCN.voiceuserdefault)) { - this.loadUser(user.parentElement, "voice", false); - } - } - if (settings.changeInRecentDms) { - for (let user of document.querySelectorAll(BDFDB.dotCNS.dms + BDFDB.dotCN.guild)) { - this.loadUser(user, "recentdms", false); - } - } - if (settings.changeInDmsList) { - for (let user of document.querySelectorAll(BDFDB.dotCN.dmchannel + BDFDB.dotCN.dmchannelprivate)) { - this.loadUser(user, "dms", false); - } - } - if (settings.changeInDmHeader && !this.LastGuildStore.getGuildId()) { - for (let user of document.querySelectorAll(BDFDB.dotCN.channelheadertitletext)) { - this.loadUser(user, "dmheader", false); - } - } - if (settings.changeInDmCalls) { - for (let user of document.querySelectorAll(BDFDB.dotCN.callavatarwrapper)) { - this.loadUser(user, "call", false); - } - } - if (settings.changeInFriendList) { - for (let user of document.querySelectorAll(BDFDB.dotCN.friendscolumn)) { - this.loadUser(user, "friends", false); - } - } - if (settings.changeInUserAccount) { - for (let user of document.querySelectorAll(BDFDB.dotCN.accountinfo)) { - this.loadUser(user, "info", false); - } - } - if (settings.changeInUserPopout) { - for (let user of document.querySelectorAll(BDFDB.dotCN.userpopout)) { - this.loadUser(user.parentElement, "popout", false); - } - } - if (settings.changeInUserProfil) { - for (let user of document.querySelectorAll(`${BDFDB.dotCN.userprofile} [class*='topSection']`)) { - this.loadUser(user, "profil", false); + else if (autocompletemenu && (e.which == 38 || e.which == 40)) { + let autocompleteitems = autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselectable + ":not(.autocompleteEditUsersSelector)"); + let selected = autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected); + if (BDFDB.containsClass(selected, "autocompleteEditUsersSelector") || autocompleteitems[e.which == 38 ? 0 : (autocompleteitems.length-1)] == selected) { + e.originalEvent.preventDefault(); + e.originalEvent.stopPropagation(); + let next = this.getNextSelection(autocompletemenu, null, e.which == 38 ? false : true); + BDFDB.removeClass(selected, BDFDB.disCN.autocompleteselected); + BDFDB.addClass(selected, BDFDB.disCN.autocompleteselector); + BDFDB.addClass(next, BDFDB.disCN.autocompleteselected); + } + } + else if (textarea.value && !e.shiftKey && e.which == 13 && !autocompletemenu && textarea.value.indexOf("s/") != 0) { + this.format = true; + textarea.dispatchEvent(new Event("input")); + } + else if (!e.ctrlKey && e.which != 16 && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) { + clearTimeout(textarea.EditUsersAutocompleteTimeout); + textarea.EditUsersAutocompleteTimeout = setTimeout(() => {this.addAutoCompleteMenu(textarea, channel);},100); + } + + if (!e.ctrlKey && e.which != 38 && e.which != 40 && !(e.which == 39 && textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length)) BDFDB.removeEles(".autocompleteEditUsers", ".autocompleteEditUsersRow"); + }); + BDFDB.addEventListener(this, textarea, "click", e => { + if (textarea.selectionStart == textarea.selectionEnd && textarea.selectionEnd == textarea.value.length) setImmediate(() => {this.addAutoCompleteMenu(textarea, channel);}); + }); } } } - loadUser (div, type, compact) { - if (!div || $(div).attr("custom-editusers") || !div.tagName || (!div.querySelector(BDFDB.dotCN.dmchannelactivitytext) && div.querySelector(BDFDB.dotCN.dmchannelactivity))) return; + processNameTag (instance, wrapper) { + let username = wrapper.parentElement.querySelector("." + (BDFDB.containsClass(wrapper, BDFDB.disCN.userpopoutheadertagwithnickname) ? BDFDB.disCN.userpopoutheadernickname : instance.props.usernameClass).replace(/ /g, ".")); + this.changeName(instance.props.user, username); + this.changeAvatar(instance.props.user, this.getAvatarDiv(wrapper)); + this.addTag(instance.props.user, username.parentElement, BDFDB.disCN.bottagnametag + (instance.props.botClass ? (" " + instance.props.botClass) : "")); + } - let {avatar, username, wrapper} = this.getAvatarNameWrapper(div); - if (!avatar && !username && !wrapper) return; - - $(div).data("compact", compact); - - var info = this.getUserInfo(compact ? $(BDFDB.dotCN.messagegroup).has(div)[0] : div); - if (!info) return; - - var data = BDFDB.loadData(info.id, this, "users"); - - if (data) { - var member = this.MemberPerms.getMember(this.LastGuildStore.getGuildId(), info.id); + processMessageUsername (instance, wrapper) { + let message = BDFDB.getReactValue(instance, "props.message"); + if (message) { + let username = wrapper.querySelector(BDFDB.dotCN.messageusername); if (username) { - var name = data.name ? data.name : (type == "info" || type == "profil" || !member || !member.nick ? info.username : member.nick); - var color1 = data.color1 ? BDFDB.color2RGB(data.color1) : (member && member.colorString ? BDFDB.color2RGB(member.colorString) : ""); - var color2 = data.color2 ? BDFDB.color2RGB(data.color2) : ""; - BDFDB.setInnerText(username, name); - username.style.color = color1; - username.style.background = color2; - } - - if (avatar && (data.removeIcon || data.url)) { - avatar.style.background = data.removeIcon ? "" : "url(" + data.url + ")"; - avatar.style.backgroundSize = "cover"; - avatar.style.backgroundPosition = "center"; - if (type == "call") { - $(avatar) - .off("mouseenter." + this.name) - .on("mouseenter." + this.name, () => { - this.createCallToolTip({"div":div,"nick":data.name,"name":info.username}); - }); + let channel = this.ChannelUtils.getChannel(message.channel_id) || {}; + this.changeName(message.author, username, channel.guild_id); + if (!BDFDB.containsClass(wrapper.parentElement, BDFDB.disCN.messageheadercompact)) { + this.changeAvatar(message.author, this.getAvatarDiv(wrapper)); } + let messagegroup = BDFDB.getParentEle(BDFDB.dotCN.messagegroup, wrapper); + this.addTag(message.author, wrapper, BDFDB.disCN.bottagmessage + " " + (BDFDB.containsClass(messagegroup, BDFDB.disCN.messagegroupcozy) ? BDFDB.disCN.bottagmessagecozy : BDFDB.disCN.bottagmessagecompact)); } - - var tag = data.tag ? data.tag : null; - if (tag && wrapper && !wrapper.querySelector(".user-tag") && (type == "list" || type == "chat" || type == "popout" || type == "profil" || type == "dmheader")) { - var color3 = data.ignoreTagColor ? - (member && member.colorString ? BDFDB.color2RGB(member.colorString) : "") : - (data.color3 ? BDFDB.color2RGB(data.color3) : ""); - var color3COMP = color3 ? BDFDB.color2COMP(color3) : [0,0,0]; - var color4 = !data.ignoreTagColor && data.color4 ? - BDFDB.color2RGB(data.color4) : - (color3COMP[0] > 180 && color3COMP[1] > 180 && color3COMP[2] > 180 ? "black" : "white"); - var thisTag = $(this.tagMarkup)[0]; - thisTag.classList.add(type + "-tag"); - thisTag.innerText = tag; - thisTag.style.background = color3; - thisTag.style.color = color4; - wrapper.appendChild(thisTag); - } - - if (type == "recentdms") { - $(div).find(BDFDB.dotCN.guildinner) - .off("mouseenter." + this.name) - .on("mouseenter." + this.name, () => { - this.createDmToolTip({"div":div,"nick":data.name,"name":info.username}); - }); - } - - $(div).attr("custom-editusers", true); } } - resetAllUsers () { - document.querySelectorAll(".user-tag").forEach(node=>{node.remove();}); - document.querySelectorAll("[custom-editusers]").forEach((div) => { - var {avatar, username, wrapper} = this.getAvatarNameWrapper(div); - if (!avatar && !username && !wrapper) return; + processAuditLog (instance, wrapper) { + let log = BDFDB.getReactValue(instance, "props.log"); + if (log && log.user) { + let hooks = wrapper.querySelectorAll(BDFDB.dotCN.auditloguserhook); + let guild_id = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.guildId"); + if (hooks.length > 0) this.changeName2(log.user, hooks[0].firstChild, guild_id); + if (hooks.length > 1 && log.targetType == "USER") this.changeName2(log.target, hooks[1].firstChild, guild_id); + } + } - var info = this.getUserInfo($(div).data(BDFDB.disCN.messagecompact) ? $(BDFDB.dotCN.messagegroup).has(div)[0] : div); - if (!info) return; - - if (username) { - var serverObj = BDFDB.getSelectedServer(); - var member = serverObj ? this.MemberPerms.getMember(serverObj.id, info.id) : null; - var name = div.classList.contains(BDFDB.disCN.accountinfo) || !member || !member.nick ? info.username : member.nick; - var color1 = member && member.colorString ? BDFDB.color2RGB(member.colorString) : ""; - var color2 = ""; - - BDFDB.setInnerText(username, name); - username.style.color = color1; - username.style.background = color2; - } - - if (avatar) { - avatar.style.background = "url(" + BDFDB.getUserAvatar(info.id) + ")"; - avatar.style.backgroundSize = "cover"; - $(avatar).off("mouseenter." + this.name); - } - - $(div).removeAttr("custom-editusers") - .find(BDFDB.dotCN.guildinner).off("mouseenter." + this.name); + processFluxContainerTypingUsers (instance, wrapper) { + let users = !instance.state.typingUsers ? [] : Object.keys(instance.state.typingUsers).filter(id => id != BDFDB.myData.id).filter(id => !this.RelationshipUtils.isBlocked(id)).map(id => this.UserUtils.getUser(id)).filter(id => id != null); + wrapper.querySelectorAll(BDFDB.dotCNS.typing + "strong").forEach((username, i) => { + if (users[i] && username) this.changeName2(users[i], username); }); } - createDmToolTip (userObj) { - var text = userObj.nick ? userObj.nick : userObj.name; - var customTooltipCSS = ` - ${BDFDB.dotCN.tooltip}:not(.dm-custom-tooltip) { - display: none !important; - }`; - BDFDB.createTooltip(text, userObj.div, {type:"right",selector:"dm-custom-tooltip",css:customTooltipCSS}); + processDirectMessage (instance, wrapper) { + let channel = BDFDB.getReactValue(instance, "props.channel"); + if (channel && channel.type == 1) { + let user = this.UserUtils.getUser(channel.recipients[0]); + if (user) { + let avatar = this.getAvatarDiv(wrapper); + if (avatar) { + this.changeAvatar(user, avatar); + this.changeTooltip(user, avatar, "right"); + } + } + } } - createCallToolTip (userObj) { - var text = userObj.nick ? userObj.nick : userObj.name; - var customTooltipCSS = ` - ${BDFDB.dotCN.tooltip}:not(.call-custom-tooltip) { - display: none !important; - }`; - BDFDB.createTooltip(text, userObj.div, {type:"left",selector:"call-custom-tooltip",css:customTooltipCSS}); + processCallAvatar (instance, wrapper) { + if (instance.props && instance.props.id) { + let user = this.UserUtils.getUser(instance.props.id); + if (!user) { + let channel = this.ChannelUtils.getChannel(instance.props.id); + if (channel && channel.type == 1) user = this.UserUtils.getUser(channel.recipients[0]); + } + if (user) { + let avatar = wrapper.querySelector(BDFDB.dotCN.callavatar); + this.changeName2(user, wrapper.parentElement.querySelector(BDFDB.dotCN.callmembers)); + this.changeAvatar(user, avatar); + if (BDFDB.containsClass(avatar, BDFDB.disCN.callvideo)) this.changeTooltip(user, avatar, "left"); + } + } } - getAvatarNameWrapper (div) { - var avatar = div.querySelector(BDFDB.dotCNC.avatarsmallold + BDFDB.dotCN.avatarlargeold + ":not(" + BDFDB.dotCN.avatarwrapper + "), " + BDFDB.dotCNC.avatarprofileold + BDFDB.dotCNC.voiceavatardefault + BDFDB.dotCNC.avatarimage + BDFDB.dotCN.callavatar); - - var username = div.querySelector(BDFDB.dotCNC.userpopoutheadernickname + BDFDB.dotCNC.userpopoutheadernonickname + BDFDB.dotCNC.userprofileusername + BDFDB.dotCNC.memberusername + BDFDB.dotCNC.voicenamedefault + BDFDB.dotCNC.messageusername + BDFDB.dotCNC.dmchannelname + BDFDB.dotCN.channelheaderchannelname + BDFDB.dotCNC.channelheaderprivate + BDFDB.dotCNS.friendscolumnnamewrap + BDFDB.dotCNC.friendscolumnusername + BDFDB.dotCNS.accountinfodetails + BDFDB.dotCN.accountinfousername); - - var wrapper = div.querySelector(BDFDB.dotCNC.userpopoutheadernickname + BDFDB.dotCNC.userpopoutheadernonickname + BDFDB.dotCNC.userprofileusername + BDFDB.dotCNC.memberusername + BDFDB.dotCNC.voicenamedefault + BDFDB.dotCNC.messageusernamewrapper + BDFDB.dotCNC.dmchannelname + BDFDB.dotCN.channelheaderchannelname + BDFDB.dotCNC.channelheaderprivate + BDFDB.dotCNS.friendscolumnnamewrap + BDFDB.dotCNC.nametag + BDFDB.dotCNS.accountinfodetails + BDFDB.dotCN.accountinfousername); - - return {avatar, username, wrapper}; + processPrivateChannel (instance, wrapper) { + if (instance.props && instance.props.user) { + let username = wrapper.querySelector(BDFDB.dotCN.dmchannelname); + this.changePrivateChannel(instance.props.user, username.firstElementChild ? username.firstElementChild : username); + this.changeAvatar(instance.props.user, this.getAvatarDiv(wrapper)); + } } - getUserInfo (div) { - let info, avatar = div.querySelector("[style*='/avatars/']"); - if (avatar) info = this.UserStore.getUser(avatar.style.backgroundImage.split("/avatars/")[1].split("/")[0]); - else { - info = BDFDB.getKeyInformation({"node":div,"key":"user"}); - if (!info) { - info = this.UserStore.getUser(BDFDB.getKeyInformation({"node":div,"key":"id","up":true})); - if (!info) { - info = BDFDB.getKeyInformation({"node":div,"key":"message"}); - if (info) info = info.author; + processHeaderBar (instance, wrapper) { + let channel_id = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.channelId"); + if (channel_id) { + let username = wrapper.querySelector(BDFDB.dotCN.channelheaderchannelname); + if (username) { + let channel = this.ChannelUtils.getChannel(channel_id); + if (channel) { + if (channel.type == 1) this.changeName(this.UserUtils.getUser(channel.recipients[0]), username); else { - info = BDFDB.getKeyInformation({"node":div,"key":"channel"}); - if (info) info = {"id":info.recipients[0]}; - else { - info = BDFDB.getKeyInformation({"node":$(BDFDB.dotCN.messagegroup).has(div)[0],"key":"message"}); - if (info) info = info.author; - } + if (username.EditUsersChangeObserver && typeof username.EditUsersChangeObserver.disconnect == "function") username.EditUsersChangeObserver.disconnect(); + username.style.removeProperty("color"); + username.style.removeProperty("background"); + BDFDB.setInnerText(username, channel.name); } } } } - return info && info.id ? this.UserStore.getUser(info.id) : null; } - changeTyping (div) { - let i = 0, ids = Object.assign({},this.TypingUtils.getTypingUsers(this.LastChannelStore.getChannelId())), sortedids = [], alldata = BDFDB.loadAllData(this, "users"); - delete ids[BDFDB.myData.id]; - for (let id in ids) sortedids.push({id:id,time:ids[id]}); - BDFDB.sortArrayByKey(sortedids, "time"); - for (let strong of div.querySelectorAll("strong")) { - let data = alldata[sortedids[i].id]; - let user = this.UserStore.getUser(sortedids[i].id); - let member = this.MemberPerms.getMember(this.LastGuildStore.getGuildId(), sortedids[i].id); - if (user) { - var name = data && data.name ? data.name : (member && member.nick ? member.nick : user.username); - var color1 = data && data.color1 ? BDFDB.color2RGB(data.color1) : (member && member.colorString ? BDFDB.color2RGB(member.colorString) : ""); - var color2 = data && data.color2 ? BDFDB.color2RGB(data.color2) : ""; - strong.innerHTML = ``; + processClickable (instance, wrapper) { + if (!wrapper || !instance.props || !instance.props.className) return; + if (instance.props.tag == "a" && instance.props.className.indexOf(BDFDB.disCN.anchorunderlineonhover) > -1) { + if (BDFDB.containsClass(wrapper.parentElement, BDFDB.disCN.messagesystemcontent) && wrapper.parentElement.querySelector("a") == wrapper) { + let message = BDFDB.getKeyInformation({node:wrapper.parentElement, key:"message", up:true}); + if (message) this.changeName(message.author, wrapper); } - i++; + } + else if (instance.props.tag == "span" && instance.props.className.indexOf(BDFDB.disCN.mention) > -1) { + let render = BDFDB.getReactValue(instance, "_reactInternalFiber.return.return.stateNode.props.render"); + if (typeof render == "function") this.changeMention(render().props.user, wrapper); + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.voiceuser) > -1) { + let user = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.user"); + if (user) { + this.changeVoiceUser(user, wrapper.querySelector(BDFDB.dotCN.voicename)); + this.changeAvatar(user, this.getAvatarDiv(wrapper)); + } + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.quickswitchresult) > -1) { + let result = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.result"); + if (result && result.type == "USER") { + this.changeName2(result.record, wrapper.querySelector(BDFDB.dotCN.quickswitchresultmatch)); + this.changeAvatar(result.record, this.getAvatarDiv(wrapper)); + } + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.autocompleterow) > -1) { + let user = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.user"); + if (user) { + this.changeName2(user, wrapper.querySelector(BDFDB.dotCN.marginleft8)); + this.changeAvatar(user, this.getAvatarDiv(wrapper)); + } + } + else if (instance.props.tag == "div" && instance.props.className.indexOf(BDFDB.disCN.searchpopoutoption) > -1) { + let user = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.user"); + let tokens = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedState.tokens"); + if (user && tokens && Array.isArray(tokens)) { + for (let i in tokens) { + let token = tokens[i]; + if (token.type == "ANSWER_USERNAME_FROM" && token._data && token._data.get("user")) { + this.changeName3(token._data.get("user"), wrapper.children[i], true); + this.changeAvatar(user, this.getAvatarDiv(wrapper)); + break; + } + } + } + else if (instance.props.className.indexOf(BDFDB.disCN.searchpopoutuser) > -1) { + let result = BDFDB.getReactValue(instance, "_reactInternalFiber.return.memoizedProps.result"); + if (result && result.user) { + this.changeName3(result.user, wrapper.querySelector(BDFDB.dotCN.searchpopoutdisplayednick), false); + this.changeAvatar(result.user, wrapper.querySelector(BDFDB.dotCN.searchpopoutdisplayavatar)); + } + } + } + } + + processMessageContent (instance, wrapper) { + let message = BDFDB.getReactValue(instance, "props.message"); + if (message && message.author) { + let markup = wrapper.querySelector(BDFDB.dotCN.messagemarkup); + if (markup) { + let channel = this.ChannelUtils.getChannel(message.channel_id) || {}; + let member = this.MemberUtils.getMember(channel.guild_id, message.author.id) || {}; + let data = this.getUserData(message.author.id, wrapper); + markup.style.setProperty("color", settingsCookie["bda-gs-7"] ? BDFDB.colorCONVERT(data.color1 || member.colorString, "RGB") : null, "important"); + } + } + } + + changeName (info, username, guildid = this.LastGuildStore.getGuildId()) { + if (!info || !username || !username.parentElement) return; + if (username.EditUsersChangeObserver && typeof username.EditUsersChangeObserver.disconnect == "function") username.EditUsersChangeObserver.disconnect(); + let data = this.getUserData(info.id, username); + if (data.name || data.color1 || data.color2 || username.getAttribute("changed-by-editusers")) { + let member = this.MemberUtils.getMember(guildid, info.id) || {}; + let isBRCenabled = BDFDB.isPluginEnabled("BetterRoleColors"); + let usenick = !BDFDB.containsClass(username, BDFDB.disCN.userprofileusername) && !BDFDB.containsClass(username.parentElement, BDFDB.disCN.userprofilelistname, BDFDB.disCN.accountinfodetails, false) && member.nick; + let usemembercolor = !BDFDB.containsClass(username.parentElement, BDFDB.disCN.userprofilelistname) && (BDFDB.containsClass(username, BDFDB.disCN.memberusername, BDFDB.disCN.messageusername, false) || isBRCenabled); + username.style.setProperty("color", BDFDB.colorCONVERT(data.color1 || (usemembercolor ? member.colorString : null), "RGB"), "important"); + username.style.setProperty("background-color", BDFDB.colorCONVERT(data.color2, "RGB"), "important"); + BDFDB.setInnerText(username, data.name || (usenick ? member.nick : info.username)); + for (let tag of username.parentElement.querySelectorAll(BDFDB.dotCN.bottag)) { + let invert = tag.className.indexOf(BDFDB.disCN.bottaginvert) > -1; + let tagcolor = BDFDB.colorCONVERT(data.color1 || (isBRCenabled || BDFDB.containsClass(tag, "owner-tag-rolecolor") ? member.colorString : null), "RGB"); + tagcolor = BDFDB.colorISBRIGHT(tagcolor) ? BDFDB.colorCHANGE(tagcolor, -0.3) : tagcolor; + tag.style.setProperty(invert ? "color" : "background-color", tagcolor, "important"); + } + if (data.name || data.color1 || data.color2) { + username.setAttribute("changed-by-editusers", true); + username.EditUsersChangeObserver = new MutationObserver((changes, _) => { + username.EditUsersChangeObserver.disconnect(); + this.changeName(info, username); + }); + username.EditUsersChangeObserver.observe(username, {attributes:true}); + } + else username.removeAttribute("changed-by-editusers"); + } + } + + changeName2 (info, username, guildid = this.LastGuildStore.getGuildId()) { + if (!info || !username || !username.parentElement) return; + if (username.EditUsersChangeObserver && typeof username.EditUsersChangeObserver.disconnect == "function") username.EditUsersChangeObserver.disconnect(); + let data = this.getUserData(info.id, username); + if (data.name || data.color1 || username.getAttribute("changed-by-editusers")) { + let member = this.MemberUtils.getMember(guildid, info.id) || {}; + username.style.setProperty("color", BDFDB.colorCONVERT(data.color1 || (BDFDB.isPluginEnabled("BetterRoleColors") ? member.colorString : null), "RGB"), "important"); + BDFDB.setInnerText(username, data.name || member.nick || info.username); + if (data.name || data.color1) { + username.setAttribute("changed-by-editusers", true); + username.EditUsersChangeObserver = new MutationObserver((changes, _) => { + username.EditUsersChangeObserver.disconnect(); + this.changeName(info, username); + }); + username.EditUsersChangeObserver.observe(username, {attributes:true}); + } + else username.removeAttribute("changed-by-editusers"); + } + } + + changeName3 (info, username, adddisc) { + if (!info || !username || !username.parentElement) return; + if (username.EditUsersChangeObserver && typeof username.EditUsersChangeObserver.disconnect == "function") username.EditUsersChangeObserver.disconnect(); + let data = this.getUserData(info.id, username); + if (data.name || data.color1 || username.getAttribute("changed-by-editusers")) { + let color1 = BDFDB.colorCONVERT(data.color1, "RGB"); + if (adddisc) { + username.innerHTML = `${BDFDB.encodeToHTML(data.name || info.username)}#${info.discriminator}`; + } + else { + username.style.setProperty("color", color1, "important"); + BDFDB.setInnerText(username, data.name || info.username); + } + if (data.name || data.color1) { + username.setAttribute("changed-by-editusers", true); + username.EditUsersChangeObserver = new MutationObserver((changes, _) => { + username.EditUsersChangeObserver.disconnect(); + this.changeName(info, username); + }); + username.EditUsersChangeObserver.observe(username, {attributes:true}); + } + else username.removeAttribute("changed-by-editusers"); + } + } + + changeAvatar (info, avatar) { + if (!info || !avatar || !avatar.parentElement) return; + if (avatar.EditUsersChangeObserver && typeof avatar.EditUsersChangeObserver.disconnect == "function") avatar.EditUsersChangeObserver.disconnect(); + let data = this.getUserData(info.id, avatar); + if (data.url || data.removeIcon || avatar.getAttribute("changed-by-editusers")) { + if (avatar.tagName == "IMG") avatar.setAttribute("src", data.removeIcon ? null : (data.url || BDFDB.getUserAvatar(info.id))); + else { + let url = data.removeIcon ? null : ("url(" + (data.url || BDFDB.getUserAvatar(info.id)) + ")"); + if (url && BDFDB.containsClass(avatar, BDFDB.disCN.avatarmaskprofile) && url.search(/discordapp\.com\/avatars\/[0-9]*\/a_/) > -1) url = url.replace(".webp)", ".gif)"); + avatar.style.setProperty("background-image", url); + if (data.url && !data.removeIcon) { + avatar.style.setProperty("background-position", "center"); + avatar.style.setProperty("background-size", "cover"); + } + } + if (data.url || data.removeIcon) { + avatar.setAttribute("changed-by-editusers", true); + avatar.EditUsersChangeObserver = new MutationObserver((changes, _) => { + changes.forEach( + (change, i) => { + avatar.EditUsersChangeObserver.disconnect(); + this.changeAvatar(info, avatar); + } + ); + }); + avatar.EditUsersChangeObserver.observe(avatar, {attributes:true}); + } + else avatar.removeAttribute("changed-by-editusers"); + } + } + + changeTooltip (info, wrapper, type) { + if (!info || !wrapper || !wrapper.parentElement) return; + let data = this.getUserData(info.id, wrapper); + wrapper.removeEventListener("mouseenter", wrapper.tooltipListenerEditUsers); + if (data.name) { + wrapper.tooltipListenerEditUsers = () => { + BDFDB.createTooltip(data.name, wrapper, {type,selector:"EditUsers-tooltip",css:`body ${BDFDB.dotCN.tooltip}:not(.EditUsers-tooltip) {display: none !important;}`}); + }; + wrapper.addEventListener("mouseenter", wrapper.tooltipListenerEditUsers); + } + } + + addTag (info, wrapper, selector = "") { + if (!info || !wrapper || !wrapper.parentElement || BDFDB.containsClass(wrapper, BDFDB.disCN.accountinfodetails) || BDFDB.containsClass(wrapper, "discord-tag")) return; + BDFDB.removeEles(wrapper.querySelectorAll(".EditUsers-tag")); + let data = this.getUserData(info.id, wrapper); + if (data.tag) { + let member = data.ignoreTagColor ? (this.MemberUtils.getMember(this.LastGuildStore.getGuildId(), info.id) || {}) : {}; + let color3 = BDFDB.colorCONVERT(!data.ignoreTagColor ? data.color3 : member.colorString, "RGB"); + let color4 = !data.ignoreTagColor && data.color4 ? BDFDB.colorCONVERT(data.color4, "RGB") : (BDFDB.colorISBRIGHT(color3) ? "black" : "white"); + let tag = document.createElement("span"); + tag.className = "EditUsers-tag " + BDFDB.disCN.bottag + (selector ? (" " + selector) : ""); + tag.innerText = data.tag; + tag.style.setProperty("background-color", color3, "important"); + tag.style.setProperty("color", color4, "important"); + wrapper.appendChild(tag); + } + } + + changePrivateChannel (info, username) { + if (!info || !username || !username.parentElement) return; + let dmchannel = BDFDB.getParentEle(BDFDB.dotCN.dmchannel, username); + if (!dmchannel) return; + if (username.EditUsersChangeObserver && typeof username.EditUsersChangeObserver.disconnect == "function") username.EditUsersChangeObserver.disconnect(); + dmchannel.removeEventListener("mouseenter", dmchannel.mouseenterListenerEditUsers); + dmchannel.removeEventListener("mouseleave", dmchannel.mouseleaveListenerEditUsers); + let data = this.getUserData(info.id, username); + if (data.name || data.color1 || data.color2 || username.getAttribute("changed-by-editusers")) { + let color1 = BDFDB.colorCONVERT(data.color1, "RGB"); + let color2 = BDFDB.colorCONVERT(data.color2, "RGB"); + BDFDB.setInnerText(username, data.name || info.username); + if (username.EditUsersHovered || BDFDB.containsClass(dmchannel, BDFDB.disCN.dmchannelselected)) colorHover(); + else colorDefault(); + + if (data.name || data.color1 || data.color2) { + dmchannel.mouseenterListenerEditUsers = () => { + username.EditUsersHovered = true; + colorHover(); + }; + dmchannel.mouseleaveListenerEditUsers = () => { + delete username.EditUsersHovered; + colorDefault(); + }; + dmchannel.addEventListener("mouseenter", dmchannel.mouseenterListenerEditUsers); + dmchannel.addEventListener("mouseleave", dmchannel.mouseleaveListenerEditUsers); + username.setAttribute("changed-by-editusers", true); + username.EditUsersChangeObserver = new MutationObserver((changes, _) => { + username.EditUsersChangeObserver.disconnect(); + this.changePrivateChannel(info, username); + }); + username.EditUsersChangeObserver.observe(username, {attributes:true}); + } + else username.removeAttribute("changed-by-editusers"); + function colorDefault() { + username.style.setProperty("color", color1 ? BDFDB.colorCHANGE(color1, -0.5) : null, "important"); + username.style.setProperty("background", color2 ? BDFDB.colorCHANGE(color2, -0.5) : null, "important"); + } + function colorHover() { + username.style.setProperty("color", color1, "important"); + username.style.setProperty("background", color2, "important"); + } + } + } + + changeMention (info, mention) { + if (!info || !mention || !mention.parentElement) return; + if (mention.EditUsersChangeObserver && typeof mention.EditUsersChangeObserver.disconnect == "function") mention.EditUsersChangeObserver.disconnect(); + mention.removeEventListener("mouseover", mention.mouseoverListenerEditUsers); + mention.removeEventListener("mouseout", mention.mouseoutListenerEditUsers); + let data = this.getUserData(info.id, mention); + let member = this.MemberUtils.getMember(this.LastGuildStore.getGuildId(), info.id) || {}; + let color1 = BDFDB.colorCONVERT(data.color1 || (BDFDB.isPluginEnabled("BetterRoleColors") ? member.colorString : null), "RGBCOMP"); + let name = data.name ? data.name : (BDFDB.isPluginEnabled("RemoveNicknames") ? bdplugins.RemoveNicknames.plugin.getNewName(info) : member.nick || info.username); + BDFDB.setInnerText(mention, "@" + name); + if (mention.EditUsersHovered) colorHover(); + else colorDefault(); + mention.mouseoverListenerEditUsers = () => { + mention.EditUsersHovered = true; + colorHover(); + }; + mention.mouseoutListenerEditUsers = () => { + delete mention.EditUsersHovered; + colorDefault(); + }; + mention.addEventListener("mouseover", mention.mouseoverListenerEditUsers); + mention.addEventListener("mouseout", mention.mouseoutListenerEditUsers); + mention.EditUsersChangeObserver = new MutationObserver((changes, _) => { + mention.EditUsersChangeObserver.disconnect(); + this.changeMention(info, mention); + }); + mention.EditUsersChangeObserver.observe(mention, {attributes:true}); + function colorDefault() { + mention.style.setProperty("color", color1 ? "rgb(" + color1[0] + "," + color1[1] + "," + color1[2] + ")" : null, "important"); + mention.style.setProperty("background", color1 ? "rgba(" + color1[0] + "," + color1[1] + "," + color1[2] + ",.1)" : null, "important"); + } + function colorHover() { + mention.style.setProperty("color", color1 ? "#FFFFFF" : null, "important"); + mention.style.setProperty("background", color1 ? "rgba(" + color1[0] + "," + color1[1] + "," + color1[2] + ",.7)" : null, "important"); + } + } + + changeVoiceUser (info, username) { + if (!info || !username || !username.parentElement) return; + if (username.EditUsersChangeObserver && typeof username.EditUsersChangeObserver.disconnect == "function") username.EditUsersChangeObserver.disconnect(); + let data = this.getUserData(info.id, username); + if (data.name || data.color1 || username.getAttribute("changed-by-editusers")) { + let member = this.MemberUtils.getMember(this.LastGuildStore.getGuildId(), info.id) || {}; + let color1 = BDFDB.colorCONVERT(data.color1 || (BDFDB.isPluginEnabled("BetterRoleColors") ? member.colorString : ""), "RGB"); + BDFDB.setInnerText(username, data.name || member.nick || info.username); + username.style.setProperty("color", BDFDB.containsClass(username, BDFDB.disCN.voicenamedefault) ? BDFDB.colorCHANGE(color1, -50) : color1, "important"); + if (data.name || data.color1) { + username.EditUsersChangeObserver = new MutationObserver((changes, _) => { + username.EditUsersChangeObserver.disconnect(); + this.changeVoiceUser(info, username); + }); + username.EditUsersChangeObserver.observe(username, {attributes:true}); + } + else username.removeAttribute("changed-by-editusers"); + } + } + + getAvatarDiv (wrapper) { + var avatar = wrapper.querySelector(this.avatarselector); + while (!avatar && wrapper.parentElement) { + wrapper = wrapper.parentElement; + avatar = wrapper.querySelector(this.avatarselector); + } + return avatar.firstElementChild || avatar; + } + + getUserData (id, wrapper) { + let data = BDFDB.loadData(id, this, "users"); + if (!data) return {}; + let allenabled = true, settings = BDFDB.getAllData(this, "settings"); + for (let i in settings) if (!settings[i]) allenabled = false; + if (allenabled) return data; + let key = null, ele = null; + if (!BDFDB.containsClass(wrapper, BDFDB.disCN.mention) && BDFDB.getParentEle(BDFDB.dotCN.messagegroup, wrapper)) key = "changeInChatWindow"; + else if (BDFDB.containsClass(wrapper, BDFDB.disCN.mention)) key = "changeInMentions"; + else if (BDFDB.getParentEle(BDFDB.dotCN.textareawrapchat, wrapper)) key = "changeInChatTextarea"; + else if (BDFDB.getParentEle(BDFDB.dotCN.voiceuser, wrapper)) key = "changeInVoiceChat"; + else if (BDFDB.getParentEle(BDFDB.dotCN.members, wrapper)) key = "changeInMemberList"; + else if (BDFDB.getParentEle(BDFDB.dotCN.dms, wrapper)) key = "changeInRecentDms"; + else if (BDFDB.getParentEle(BDFDB.dotCN.dmchannels, wrapper)) key = "changeInDmsList"; + else if (BDFDB.getParentEle(BDFDB.dotCN.channelheaderheaderbar, wrapper)) key = "changeInDmHeader"; + else if (BDFDB.getParentEle(BDFDB.dotCN.callavatarwrapper, wrapper)) key = "changeInDmCalls"; + else if (BDFDB.getParentEle(BDFDB.dotCN.callincoming, wrapper) || BDFDB.getParentEle(BDFDB.dotCN.callcurentcontainer, wrapper)) key = "changeInDmCalls"; + else if (BDFDB.getParentEle(BDFDB.dotCN.typing, wrapper)) key = "changeInTyping"; + else if (BDFDB.getParentEle(BDFDB.dotCN.friends, wrapper) || BDFDB.getParentEle(BDFDB.dotCN.userprofilebody, wrapper)) key = "changeInFriendList"; + else if (BDFDB.getParentEle(BDFDB.dotCN.activityfeed, wrapper)) key = "changeInActivity"; + else if (BDFDB.getParentEle(BDFDB.dotCN.userpopout, wrapper)) key = "changeInUserPopout"; + else if (BDFDB.getParentEle(BDFDB.dotCN.userprofileheader, wrapper)) key = "changeInUserProfil"; + else if (BDFDB.getParentEle(BDFDB.dotCN.autocomplete, wrapper)) key = "changeInAutoComplete"; + else if (BDFDB.getParentEle(BDFDB.dotCN.auditlog, wrapper)) key = "changeInAuditLog"; + else if (BDFDB.getParentEle(BDFDB.dotCN.searchpopout, wrapper) || BDFDB.getParentEle(BDFDB.dotCN.searchpopoutdmaddpopout, wrapper)) key = "changeInSearchPopout"; + else if (BDFDB.getParentEle(BDFDB.dotCN.accountinfo, wrapper)) key = "changeInUserAccount"; + + return !key || BDFDB.getData(key, this, "settings") ? data : {}; + } + + addAutoCompleteMenu (textarea, channel) { + if (textarea.parentElement.querySelector(".autocompleteEditUsersRow")) return; + let words = textarea.value.split(/\s/); + let lastword = words[words.length-1].trim(); + if (lastword && lastword.length > 1 && lastword[0] == "@") { + let users = BDFDB.loadAllData(this, "users"); + if (!users) return; + let userarray = []; + for (let id in users) if (users[id].name) { + let user = this.UserUtils.getUser(id); + let member = user ? this.MemberUtils.getMember(channel.guild_id, id) : null; + if (user && member) userarray.push(Object.assign({lowercasename:users[id].name.toLowerCase(),user,member},users[id])); + } + userarray = BDFDB.sortArrayByKey(userarray.filter(n => n.lowercasename.indexOf(lastword.toLowerCase().slice(1)) != -1), "lowercasename"); + if (userarray.length) { + let autocompletemenu = textarea.parentElement.querySelector(BDFDB.dotCNS.autocomplete + BDFDB.dotCN.autocompleteinner), amount = 15; + if (!autocompletemenu) { + autocompletemenu = BDFDB.htmlToElement(`
${BDFDB.LanguageStrings.MEMBERS_MATCHING.replace("{{prefix}}", BDFDB.encodeToHTML(lastword))}
`); + textarea.parentElement.appendChild(autocompletemenu); + autocompletemenu = autocompletemenu.firstElementChild; + } + else { + amount -= autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselectable).length; + } + + BDFDB.addEventListener(this, autocompletemenu, "mouseenter", BDFDB.dotCN.autocompleteselectable, e => { + var selected = autocompletemenu.querySelectorAll(BDFDB.dotCN.autocompleteselected); + BDFDB.removeClass(selected, BDFDB.disCN.autocompleteselected); + BDFDB.addClass(selected, BDFDB.disCN.autocompleteselector); + BDFDB.addClass(e.currentTarget, BDFDB.disCN.autocompleteselected); + }); + + for (let data of userarray) { + if (amount-- < 1) break; + let autocompleterow = BDFDB.htmlToElement(`
${BDFDB.encodeToHTML(data.name || data.member.nick || data.user.username)}
${BDFDB.encodeToHTML(data.user.username)}
#${data.user.discriminator}
`); + autocompleterow.querySelector(BDFDB.dotCN.autocompleteselectable).addEventListener("click", () => {this.swapWordWithMention(textarea);}); + autocompletemenu.appendChild(autocompleterow); + } + if (!autocompletemenu.querySelector(BDFDB.dotCN.autocompleteselected)) { + BDFDB.addClass(autocompletemenu.querySelector(".autocompleteEditUsersRow " + BDFDB.dotCN.autocompleteselectable), BDFDB.disCN.autocompleteselected); + } + } + } + } + + getNextSelection (menu, selected, forward) { + selected = selected ? selected : menu.querySelector(BDFDB.dotCN.autocompleteselected).parentElement; + let next, sibling = forward ? selected.nextElementSibling : selected.previousElementSibling; + if (sibling) { + next = sibling.querySelector(BDFDB.dotCN.autocompleteselectable); + } + else { + let items = menu.querySelectorAll(BDFDB.dotCN.autocompleteselectable); + next = forward ? items[0] : items[items.length-1]; + } + return next ? next : this.getNextSelection(menu, sibling, forward); + } + + swapWordWithMention (textarea) { + let selected = textarea.parentElement.querySelector(".autocompleteEditUsersRow " + BDFDB.dotCN.autocompleteselected); + let words = textarea.value.split(/\s/); + let lastword = words[words.length-1].trim(); + if (selected && lastword) { + let username = selected.querySelector(BDFDB.dotCN.autocompletedescriptionusername).textContent; + let discriminator = selected.querySelector(BDFDB.dotCN.autocompletedescriptiondiscriminator).textContent; + let userid = selected.getAttribute("userid"); + BDFDB.removeEles(".autocompleteEditUsers", ".autocompleteEditUsersRow"); + textarea.focus(); + textarea.selectionStart = textarea.value.length - lastword.length; + textarea.selectionEnd = textarea.value.length; + document.execCommand("insertText", false, (username && discriminator ? ("@" + username + discriminator) : `<@!${userid}>`) + " "); + textarea.selectionStart = textarea.value.length; + textarea.selectionEnd = textarea.value.length; } } getSettingsPanel () { + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var settings = BDFDB.getAllData(this, "settings"); - var settingshtml = `
`; + var settingshtml = `
${this.name}
`; settingshtml += `

Change User in:

`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; } settingshtml += `
`; settingshtml += `

Reset all Users.

`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) - .on("click", ".reset-button", () => {this.resetAll();}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "click", ".reset-button", () => { + BDFDB.openConfirmModal(this, "Are you sure you want to reset all users?", () => { + BDFDB.removeAllData(this, "users"); + BDFDB.WebModules.forceAllUpdates(this); + }); + }); return settingspanel; } onSettingsClosed () { - if (this.updateUsers) { - this.loadAllUsers(); - this.updateUsers = false; + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + BDFDB.WebModules.forceAllUpdates(this); } } diff --git a/PluginsV2/EmojiStatistics/index.js b/PluginsV2/EmojiStatistics/index.js index 91d6999243..5c7061a984 100644 --- a/PluginsV2/EmojiStatistics/index.js +++ b/PluginsV2/EmojiStatistics/index.js @@ -5,7 +5,16 @@ module.exports = (Plugin, Api, Vendor) => { initConstructor () { this.labels = {}; + this.patchModules = { + "EmojiPicker":"componentDidMount" + }; + this.css = ` + .emojistatistics-tooltip, + .emoji-tooltip { + z-index: 2002; + } + .${this.name}-modal .titles { height: 20px; } @@ -17,18 +26,7 @@ module.exports = (Plugin, Api, Vendor) => { } .${this.name}-modal .emojiserver-entry .modal-emojiserver-icon { - background-color: #484B51; - background-size: cover; - border-radius: 25px; - color: #b9bbbe; display: inline-block; - font-size: 16px; - font-weight: 600; - height: 35px; - letter-spacing: .5px; - padding-top: 15px; - text-align: center; - width: 50px; } .${this.name}-modal .titles-entry label, @@ -92,7 +90,7 @@ module.exports = (Plugin, Api, Vendor) => { }`; this.emojiInformationModalMarkup = - ` + `
@@ -102,12 +100,16 @@ module.exports = (Plugin, Api, Vendor) => {

REPLACE_modal_header_text

- - - - - - +
@@ -143,14 +145,13 @@ module.exports = (Plugin, Api, Vendor) => {
`; - this.dividerMarkup = `
`; - - this.emojiButtonMarkup = `
`; - this.defaults = { settings: { enableEmojiHovering: {value:true, description:"Show Information about Emojis on hover over an Emoji in the Emojipicker."}, enableEmojiStatisticsButton: {value:true, description:"Add a Button in the Emojipicker to open the Statistics Overview."} + }, + amounts: { + hoverDelay: {value:1000, description:"Tooltip delay in millisec:"} } }; } @@ -175,40 +176,13 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.emojipicker)) { - this.loadEmojiList(); - if (!node.querySelector(".emojistatistics-button") && BDFDB.getData("enableEmojiStatisticsButton", this, "settings")) { - this.addEmojiInformationButton(node); - } - if (BDFDB.getData("enableEmojiHovering", this, "settings")) { - this.hoverEmoji(node); - } - } - }); - } - if (change.removedNodes) { - change.removedNodes.forEach((node) => { - if (node.querySelector(BDFDB.dotCN.emojipicker)) { - $(BDFDB.dotCN.tooltips).find(".emoji-tooltip").remove(); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.popouts, {name:"emojiPickerObserver",instance:observer}, {childList: true}); - this.GuildEmojis = BDFDB.WebModules.findByProperties("getGuildEmoji", "getDisambiguatedEmojiContext"); + BDFDB.WebModules.forceAllUpdates(this); + return true; } else { @@ -219,6 +193,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + BDFDB.removeEles(".emoji-tooltip",".emojistatistics-button"); BDFDB.unloadMessage(this); return true; } @@ -230,14 +205,6 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - changeLanguageStrings () { this.emojiInformationModalMarkup = this.emojiInformationModalMarkup.replace("REPLACE_modal_header_text", this.labels.modal_header_text); this.emojiInformationModalMarkup = this.emojiInformationModalMarkup.replace("REPLACE_btn_ok_text", this.labels.btn_ok_text); @@ -251,54 +218,81 @@ module.exports = (Plugin, Api, Vendor) => { this.emojiserverTitlesMarkup = this.emojiserverTitlesMarkup.replace("REPLACE_modal_titlescopies_text", this.labels.modal_titlescopies_text); } + processEmojiPicker (instance, wrapper) { + if (!wrapper.querySelector(".emojistatistics-button")) { + let emojipickerdiversityselector = document.querySelector(BDFDB.dotCN.emojipickerdiversityselector); + if (!emojipickerdiversityselector) return; + this.loadEmojiList(); + let settings = BDFDB.getAllData(this, "settings"); + if (settings.enableEmojiStatisticsButton) { + let emojiStatisticsButton = BDFDB.htmlToElement(`
`); + emojipickerdiversityselector.parentElement.insertBefore(emojiStatisticsButton, emojipickerdiversityselector); + emojiStatisticsButton.addEventListener("click", () => { + instance._reactInternalFiber.return.return.return.return.stateNode.close(); + this.showEmojiInformationModal(); + }); + emojiStatisticsButton.addEventListener("mouseenter", e => { + BDFDB.createTooltip("Emoji Statistics", emojiStatisticsButton, {type:"top",selector:"emojistatistics-tooltip"}); + }); + } + if (settings.enableEmojiHovering) { + BDFDB.addEventListener(this, wrapper, "mouseenter", BDFDB.dotCN.emojipickeremojiitem, e => { + let data = this.emojiToServerList[e.target.style.getPropertyValue("background-image").replace('url("',"").replace('")',"")]; + if (data) BDFDB.createTooltip(`${BDFDB.encodeToHTML(data.emoji)}\n${BDFDB.encodeToHTML(data.server)}`, e.target, {type:"right",selector:"emoji-tooltip",delay:BDFDB.getData("hoverDelay", this, "amounts")}); + }); + } + } + } + loadEmojiList () { this.emojiReplicaList = {}; this.emojiToServerList = {}; for (let serverObj of BDFDB.readServerList()) { for (let emoji of this.GuildEmojis.getGuildEmoji(serverObj.id)) { this.emojiToServerList[emoji.url] = {emoji:emoji.allNamesString, server:serverObj.name}; - if (emoji.managed) { - if (this.emojiReplicaList[emoji.name] != undefined) { - this.emojiReplicaList[emoji.name] = true; - } - else { - this.emojiReplicaList[emoji.name] = false; - } - } + if (emoji.managed) this.emojiReplicaList[emoji.name] = this.emojiReplicaList[emoji.name] != undefined; } } } - hoverEmoji (picker) { - $(picker) - .off("mouseenter." + this.name) - .on("mouseenter." + this.name, BDFDB.dotCN.emojipickeremojiitem, (e) => { - var data = this.emojiToServerList[$(e.target).css("background-image").replace("url(\"","").replace("\")","")]; - if (data) { - var text = `${BDFDB.encodeToHTML(data.emoji)}\n${BDFDB.encodeToHTML(data.server)}`; - BDFDB.createTooltip(text, e.target, {type:"right",selector:"emoji-tooltip",css:`.emoji-tooltip{z-index:30000;}`}); - } - }); - } - - addEmojiInformationButton (node) { - $(node).find(BDFDB.dotCN.emojipickerheader) - .append(this.emojiButtonMarkup) - .off("click." + this.name) - .on("click." + this.name, ".emojistatistics-button", () => { - $(node).hide(); - this.showEmojiInformationModal(); - }); - } - showEmojiInformationModal () { - var emojiInformationModal = $(this.emojiInformationModalMarkup); - BDFDB.appendModal(emojiInformationModal); + var emojiInformationModal = BDFDB.htmlToElement(this.emojiInformationModalMarkup); + + let titlescontainer = emojiInformationModal.querySelector(".titles"); + let entriescontainer = emojiInformationModal.querySelector(".entries"); + + if (!titlescontainer || !entriescontainer) return; + + var titleEntry = BDFDB.htmlToElement(this.emojiserverTitlesMarkup); + titlescontainer.appendChild(titleEntry); + BDFDB.addChildEventListener(titleEntry, "click", ".modal-sorttitle-label ", e => { + var oldTitle = e.currentTarget.innerText; + + var reverse = oldTitle.indexOf("▼") < 0 ? false : true; + + titleEntry.querySelector(".modal-titlesname-label").innerText = this.labels.modal_titlesname_text; + titleEntry.querySelector(".modal-titlestotal-label").innerText = this.labels.modal_titlestotal_text; + titleEntry.querySelector(".modal-titlesglobal-label").innerText = this.labels.modal_titlesglobal_text; + titleEntry.querySelector(".modal-titleslocal-label").innerText = this.labels.modal_titleslocal_text; + titleEntry.querySelector(".modal-titlescopies-label").innerText = this.labels.modal_titlescopies_text; + + var sortKey = "index"; + if (oldTitle.indexOf("▲") < 0) { + sortKey = e.currentTarget.getAttribute("sortkey"); + var title = this.labels["modal_titles" + sortKey + "_text"]; + e.currentTarget.innerText = oldTitle.indexOf("▼") < 0 ? title + "▼" : title + "▲"; + } + + BDFDB.sortArrayByKey(entries, sortKey); + if (reverse) entries.reverse(); + + this.updateAllEntries(entriescontainer, entries); + }); var entries = [], index = 0; - for (let serverObj of BDFDB.readServerList()) { + for (let info of BDFDB.readServerList()) { let amountGlobal = 0, amountLocal = 0, amountCopies = 0; - for (let emoji of this.GuildEmojis.getGuildEmoji(serverObj.id)) { + for (let emoji of this.GuildEmojis.getGuildEmoji(info.id)) { if (emoji.managed) { amountGlobal++; if (this.emojiReplicaList[emoji.name]) amountCopies++; @@ -307,68 +301,57 @@ module.exports = (Plugin, Api, Vendor) => { amountLocal++; } } - var entry = $(this.emojiserverEntryMarkup); - if (serverObj.icon) { - entry.find(".modal-emojiserver-icon").css("background-image", "url('https://cdn.discordapp.com/icons/" + serverObj.id + "/" + serverObj.icon + ".png')"); - } - else { - entry.find(".modal-emojiserver-icon").text(serverObj.div.querySelector("a").innerText); - } - entry.find(".modal-emojiname-label").text(serverObj.name); - entry.find(".modal-emojitotal-label").text(amountGlobal+amountLocal); - entry.find(".modal-emojiglobal-label").text(amountGlobal); - entry.find(".modal-emojilocal-label").text(amountLocal); - entry.find(".modal-emojicopies-label").text(amountCopies); - entries.push({entry:entry, index:index++, name:serverObj.name, total:amountGlobal+amountLocal, global:amountGlobal, local:amountLocal, copies:amountCopies}); + var emojiEntry = BDFDB.htmlToElement(this.emojiserverEntryMarkup); + emojiEntry.querySelector(".modal-emojiserver-icon").innerHTML = this.createCopyOfServer(info).outerHTML; + emojiEntry.querySelector(".modal-emojiname-label").innerText = info.name || ""; + emojiEntry.querySelector(".modal-emojitotal-label").innerText = amountGlobal + amountLocal; + emojiEntry.querySelector(".modal-emojiglobal-label").innerText = amountGlobal; + emojiEntry.querySelector(".modal-emojilocal-label").innerText = amountLocal; + emojiEntry.querySelector(".modal-emojicopies-label").innerText = amountCopies; + entries.push({div:emojiEntry, index:index++, name:info.name || "", total:amountGlobal+amountLocal, global:amountGlobal, local:amountLocal, copies:amountCopies}); } - var titleentry = $(this.emojiserverTitlesMarkup) - .appendTo("." + this.name + "-modal .titles") - .on("click", ".modal-title-label ", (e2) => { - var oldTitle = e2.target.innerText; + BDFDB.appendModal(emojiInformationModal); - var reverse = oldTitle.indexOf("▼") < 0 ? false : true; - - titleentry.find(".modal-titlesname-label").text(this.labels.modal_titlesname_text); - titleentry.find(".modal-titlestotal-label").text(this.labels.modal_titlestotal_text); - titleentry.find(".modal-titlesglobal-label").text(this.labels.modal_titlesglobal_text); - titleentry.find(".modal-titleslocal-label").text(this.labels.modal_titleslocal_text); - titleentry.find(".modal-titlescopies-label").text(this.labels.modal_titlescopies_text); - - var sortKey = "index"; - if (oldTitle.indexOf("▲") < 0) { - sortKey = e2.target.getAttribute("sortkey"); - var title = this.labels["modal_titles" + sortKey + "_text"]; - e2.target.innerText = oldTitle.indexOf("▼") < 0 ? title + "▼" : title + "▲"; - } - - this.updateAllEntries(emojiInformationModal, entries); - }); - - this.updateAllEntries(emojiInformationModal, entries); + this.updateAllEntries(entriescontainer, entries); } - updateAllEntries (modal, entries) { - var container = modal.find(".entries"); - container.children().remove(); - for (let i = 0; entries.length > i; i++) { - if (i > 0) container.append(this.dividerMarkup); - container.append(entries[i].entry); + updateAllEntries (entriescontainer, entries) { + BDFDB.removeEles(entriescontainer.childNodes); + for (let entry of entries) { + if (entriescontainer.childElementCount) entriescontainer.appendChild(BDFDB.htmlToElement(`
`)); + entriescontainer.appendChild(entry.div); } } + createCopyOfServer (info) { + let serverCopy = info.div.cloneNode(true); + BDFDB.toggleEles(serverCopy, true); + BDFDB.removeClass(serverCopy, BDFDB.disCN.guildunread, BDFDB.disCN.guildselected); + return serverCopy; + } + getSettingsPanel () { - var settings = BDFDB.getAllData(this, "settings"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + var settings = BDFDB.getAllData(this, "settings"); + var amounts = BDFDB.getAllData(this, "amounts"); + var settingshtml = `
${this.name}
`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; } - settingshtml += `
`; + for (let key in amounts) { + settingshtml += `

${this.defaults.amounts[key].description}

`; + } + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "input", ".amountInput", e => { + var input = parseInt(e.currentTarget.value); + if (!isNaN(input) && input > -1) BDFDB.saveData(e.currentTarget.getAttribute("option"), input, this, "amounts"); + }); return settingspanel; } diff --git a/PluginsV2/FixGermanTranslation/README.md b/PluginsV2/FixGermanTranslation/README.md deleted file mode 100644 index 32bfa7a2e3..0000000000 --- a/PluginsV2/FixGermanTranslation/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# These Plugins are meant only for BDv2, not BD nor BandagedBD. If you got either of those two go to [Plugins](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/). - -## Fix German Translation - [Download Script](https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/PluginsV2/FixGermanTranslation/index.js) [Download Config](https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/PluginsV2/FixGermanTranslation/config.json) - -Fixes some minor translation errors and some untranslated parts in the german version of discord. diff --git a/PluginsV2/FixGermanTranslation/config.json b/PluginsV2/FixGermanTranslation/config.json deleted file mode 100644 index ebfad1dac8..0000000000 --- a/PluginsV2/FixGermanTranslation/config.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "info": { - "name": "FixGermanTranslation", - "authors": [ - { - "name": "DevilBro", - "url": "https://www.paypal.me/MircoWittrien", - "discord_id": "278543574059057154", - "github_username": "mwittrien" - } - ], - "version": 1.0, - "description": "Fixes the german translation. \n\nMy Support Server: http://bit.ly/DevilBrosHaus or https://discordapp.com/invite/Jx3TjNS" - } -} diff --git a/PluginsV2/FixGermanTranslation/index.js b/PluginsV2/FixGermanTranslation/index.js deleted file mode 100644 index ce90bca826..0000000000 --- a/PluginsV2/FixGermanTranslation/index.js +++ /dev/null @@ -1,254 +0,0 @@ -module.exports = (Plugin, Api, Vendor) => { - if (!global.BDFDB || typeof BDFDB != "object") global.BDFDB = {BDv2Api: Api}; - - return class extends Plugin { - initConstructor () { - this.newStrings = { - NO_THANKS: "Nein Danke", - VAD_PERMISSION_SMALL: "Dieser Kanal erfordert Push-to-Talk um zu sprechen.", - FORM_HELP_NSFW: "Benutzer müssen bestätigen, dass sie über 18 Jahre alt sind, um Inhalte des Kanals zu sehen.\nNSFW-Kanäle sind vom expliziten Inhaltsfilter ausgeschlossen.", - SEND_TTS_MESSAGES_DESCRIPTION: "Mitglieder mit dieser Berechtigung können Text-zu-Sprache-Nachrichten schicken, indem sie die Nachricht mit /tts (Text-to-Speech) beginnen. Diese Nachrichten können von jedem gehört werden, der sich in dem Kanal befindet.", - MANAGE_MESSAGES_DESCRIPTION: "Mitglieder mit dieser Berechtigung können Nachrichten von anderen Mitgliedern löschen oder eine Nachricht anpinnen.", - MOVE_MEMBERS_DESCRIPTION: "Mitglieder mit dieser Berechtigung können andere Mitglieder aus diesem Kanal herausziehen. Sie können ausschließlich Mitglieder zwischen Kanälen hin- und herziehen, in denen sowohl sie als auch das Mitglied Zutritt haben.", - USE_VAD_DESCRIPTION: "Wenn diese Berechtigung entzogen wird, müssen Benutzer in diesem Kanal Push-to-Talk verwenden.", - MENTION_USERS_WITH_ROLE: "Benachrichtige Benutzer mit dieser Rolle, welche die Rechte haben diesen Kanal zu sehen.", - MENTION_EVERYONE_AUTOCOMPLETE_DESCRIPTION: "Benachrichtige jeden, der die Berechtigung zum Lesen des Kanals hat.", - MENTION_HERE_AUTOCOMPLETE_DESCRIPTION: "Benachrichtige jeden der Online ist und der die Rechte hat diesen Kanal zu sehen.", - FORM_HELP_CHANNEL_PERMISSIONS: "Das Auswählen der Rollen wird automatisch grundlegende Berechtigungen für diesen Kanal erstellen.", - JOIN_SERVER_DESCRIPTION_MOBILE: "Gib eine Soforteinladung ein, um einen existierenden Server beizutreten.", - INSTANT_INVITE_LOOKS_LIKE: "Die Einladung wird in etwa so aussehen:", - FORM_LABEL_INSTANT_INVITE: "Gib eine Soforteinladung ein", - INVALID_INVITE_LINK_ERROR: "Bitte gib einen gültigen Einladungslink oder Code ein.", - EDIT_CHANNEL: "Kanal bearbeiten", - EDIT_VOICE_CHANNEL_NO_PERMISSION: "Deine Rolle hat keine Berechtigung diesen Sprachkanal zu bearbeiten.", - DELETE_SERVER_ENTER_NAME: "Gib den Servernamen ein", - EXPLICIT_CONTENT_FILTER_HIGH_DESCRIPTION: "Empfohlen, wenn du alles blitze blank haben willst.", - GUILD_SETTINGS_AUDIT_LOG_CHANNEL_PERMISSION_OVERRIDES_CREATE: "Mit Berechtigungsüberschreibung", - GUILD_SETTINGS_AUDIT_LOG_CHANNEL_NSFW_ENABLED: "Hat den Kanal als NSFW markiert", - GUILD_SETTINGS_AUDIT_LOG_ROLE_HOIST_OFF: "Nicht separiert", - SORTING: "Am Sortieren", - GUILD_SETTINGS_WIDGET_ENABLE_WIDGET: "Server Widget aktivieren", - ADMINISTRATOR_DESCRIPTION: "Mitglieder mit dieser Berechtigung haben jede Berechtigung und können kanalspezifische Berechtigungen umgehen. Mit dieser Berechtigung ist vorsichtig umzugehen.", - VIEW_AUDIT_LOG_DESCRIPTION: "Mitglieder mit dieser Berechtigung können die Audit Logs des Servers einsehen.", - ANIMATED_EMOJI: "Animierter Emoji", - NO_EMOJI_BODY: "Nichts", - TOO_MANY_EMOJI: "Du hast keine freien Plätze mehr für Emojis.", - TOO_MANY_ANIMATED_EMOJI: "Du hast keine freien Plätze mehr für animierte Emojis.", - INVITE_FRIEND_MODAL_TITLE: "Lade deine Freunde ein", - INVITE_FRIEND_MODAL_LOADING: "Lädt deine Freundesliste...", - INSTANT_INVITE_INVALID_CHANNEL: "Du kannst keine Soforteinladung für diesen Kanal erstellen. Versuch's mit einem anderen!", - INSTANT_INVITE_NOT_ALLOWED: "Mist. Scheint als könntest du für diesen Server keine Soforteinladung erstellen.", - LOGIN_BODY: "Log dich mit deiner E-Mail-Adresse ein um loszulegen", - FORM_LABEL_EMAIL: "E-Mail", - EMAIL_REQUIRED: "Eine gültige E-Mail-Adresse wird benötigt.", - EMAIL_INVALID: "Die angegebene E-Mail-Adresse ist ungültig. Bitte aktualisiere sie und versuch es erneut.", - PASSWORD_REQUIRED: "Ein Passwort ist erforderlich.", - FORGOT_PASSWORD_BODY: "Keine Sorge. Bitte gib die E-Mail-Adresse deines Accounts an, damit wir deine Identität überprüfen können.", - ACCOUNT_SCHEDULED_FOR_DELETION_TITLE: "Account zur Löschung geplant", - ACCOUNT_SCHEDULED_FOR_DELETION_DESCRIPTION: "Dein Account wird sich bald selbst zerstören.. sicher, dass du dies immer noch möchtest?", - BEGINNING_GROUP_DM_PARTY: "Willkommen zu LFG. Bitte sei freundlich und respektvoll zu einander. Wenn du Freunde findest, vergiss nicht sie hinzuzufügen!", - USERNAME_REQUIRED: "Ein Benutzername ist erforderlich.", - RESEND: "Erneut senden", - NOTICE_SPOTIFY_AUTO_PAUSED: "Dein Mikrofon sendet seit 30 Sekunden. Spotify wurde pausiert.", - SELF_MUTED: "Selbst stummschalten", - SERVER_MUTE: "Mikrofone deaktivieren", - SERVER_UNMUTE: " Mikrofone aktivieren", - SERVER_MUTED: "Mikrofone deaktiviert", - SERVER_DEAFEN: "Lautsprecher deaktivieren", - SERVER_UNDEAFEN: "Lautsprecher aktivieren", - SERVER_DEAFENED: "Lautsprecher deaktiviert", - USER_SETTINGS_STARTUP_BEHAVIOR: "System Startup Behavior", - USER_SETTINGS_CLOSE_BUTTON: "Schließknopf", - USER_SETTINGS_OPEN_ON_STARTUP_LABEL: "Discord öffnen", - USER_SETTINGS_OPEN_ON_STARTUP_BODY: "Spar dir ein paar Klicks und lass Discord dich grüßen, wenn du nach Hause kommst wie ein guter Junge", - USER_SETTINGS_START_MINIMIZED_LABEL: "Minimiert starten", - USER_SETTINGS_START_MINIMIZED_BODY: "Discord startet minimiert wie ein guter Junge und steht dir nicht im Weg", - USER_SETTINGS_MINIMIZE_TO_TRAY_LABEL: "In Symbolleiste minimieren", - USER_SETTINGS_MINIMIZE_TO_TRAY_BODY: "Lass Discord in deiner Symbolleiste wie ein guter Junge kuscheln, wenn du die Anwendung schließt", - USER_SETTINGS_LINUX_SETTINGS: "Linux-Einstellungen", - ADD_KEYBIND_WARNING: "Hotkeys sind deaktiviert, während diese Schaltfläche sichtbar ist.", - GAME_NOTIFICATIONS_USER_OVERRIDES: "Leute mit denen du spielst", - GAME_NOTIFICATION_SETTING_DESKTOP_ONLY_DESC: "Benachrichtigungen werden auf deinem Desktop angezeigt, wenn du online oder untätig bist.", - GAME_NOTIFICATION_SETTINGS_FOLLOWING_EMPTY: "Wir versuchen immer noch herauszufinden mit wem du Spiele spielst. Los spiel ein Bisschen mit deinen Freunden!", - VERIFICATION_EMAIL_ERROR_TITLE: "Fehler bei deiner Verifizierungs-E-Mail", - DESKTOP_NOTIFICATIONS_ENABLE: "Aktiviere Desktopbenachrichtigungen", - MOBILE_ENABLE_HARDWARE_SCALING_DESC: "Experimentelle Funktion, die die Performanz bei Videogesprächen verbessern könnte. Vorsicht kann Stuss verursachen.", - PIN_MESSAGE_BODY_PRIVATE_CHANNEL: "Möchte nur sicherstellen, dass du diese scheinbar bedeutsame Nachricht wirklich in diesen Kanal für die Nachwelt anheften möchtest.", - PINS_DISABLED_NSFW: "Dies ist ein NSFW-Kanal und der Inhalt sollte lieber für niemanden als angeheftete Nachricht sichtbar sein.", - SERVER_MUTE_DMS: "Direktnachrichten stummschalten", - SCOPE_WEBHOOK_INCOMING: "Fügt einen WebHook zu einem Kanal hinzu", - CLAIM_ACCOUNT_REQUIRED_BODY: "Bitte registriere deinen Account um die Desktop App zu benutzen.", - CLAIM_ACCOUNT_GET_APP: "Hol dir die Desktop App", - NOTE_PLACEHOLDER: "Hier tippen, um eine Notiz hinzuzufügen", - VANITY_URL_HELP_CONFLICT: "Vergiss nicht, dass wir Vanity-URLs zurücknehmen, wenn wir einen Missbrauch oder Interessenkonflikt feststellen.", - SCREENSHARE_UNAVAILABLE: "Bildschirmübertragung nicht verfügbar", - SCREENSHARE_UNAVAILABLE_DOWNLOAD_APP: "Lade die Desktop App herunter, um Bildschirmübertragungen zu benutzen!", - VIDEO_POOR_CONNECTION_BODY: "Video wurde deaktiviert. Es wird automatisch fortgesetzt, sobald sich deine Verbindung verbessert hat.", - INVITE_MODAL_ERROR_TITLE: "Upps...", - DISABLE_EMAIL_NOTIFICATIONS_FAILED: "Upps! Wir konnten die E-Mail Benachrichtigungen für deine E-Mail Adresse nicht ausschalten.", - KEYBIND_DESCRIPTION_MODAL_TOGGLE_PINS: "Verankerte Pins an-/ausschalten", - KEYBIND_DESCRIPTION_MODAL_FOCUS_TEXT_AREA: "Textbereich fokussieren", - INVALID_ANIMATED_EMOJI_BODY: "Dieser Emoji funktioniert nicht, da er animiert ist. Hol dir Discord Nitro, um all deine animierten Emoji Träume zu erfüllen.", - INVALID_ANIMATED_EMOJI_BODY_UPGRADE: "Dieser Emoji funktioniert nicht, da er animiert ist. Discord Nitro löst dieses Problem, schau auf Benutzereinstellungen > Discord Nitro für mehr Informationen.", - INVALID_EXTERNAL_EMOJI_BODY: "Dieser Emoji funktioniert nicht, da er von einem anderem Server stammt. Hol dir Discord Nitro, um Emojis von anderen Servern zu benutzen.", - INVALID_EXTERNAL_EMOJI_BODY_UPGRADE: "Dieser Emoji funktioniert nicht, da er von einem anderem Server stammt. Discord Nitro löst dieses Problem, schau auf Benutzereinstellungen > Discord Nitro für mehr Informationen.", - NEW_TERMS_TITLE: "Neue AGBs und Nutzungsbedingungen", - NEW_TERMS_DESCRIPTION: "Um weiterhin Discord zu nutzen, lies und stimme bitte\nunseren neuen AGBs und Nutzungsbedingungen zu.", - PREMIUM_FEATURE_DESCRIPTION_ANIMATED_AVATAR: "Lade ein GIF als Benutzerprofilbild hoch und spiel es ab wenn du im Chat mit der Maus darüber fährst.", - PAYMENT_SOURCE_TITLE: "Zahlungsmethode", - PAYMENT_SOURCE_CREDIT_CARD: "Kreditkarte", - PAYMENT_SOURCE_CHANGE_CARD: "Kreditkarte ändern", - PAYMENT_SOURCE_REMOVE_CARD: "Kreditkarte entfernen", - PAYMENT_SOURCE_CHANGE_PAYPAL: "PayPal-Account ändern", - PAYMENT_SOURCE_INVALID_DETAILS: "Du musst deine Kreditkarte aktualisieren oder dein Nitro Abonnement läuft ab", - PAYMENT_SOURCE_CONFIRM_PAYPAL_DETAILS: "Bestätige deine PayPal Daten in deinem Browser!", - PAYMENT_SOURCE_PAYPAL_REOPEN: "Fenster erneut öffnen", - PAYMENT_STEPS_GO_BACK: "Zurück", - PAYMENT_MODAL_TITLE_CHANGE_CARD: "Kreditkarte ändern", - PAYMENT_MODAL_TITLE_CHANGE_PAYPAL: "PayPal-Account ändern", - PAYMENT_MODAL_SUBTITLE: "Discord Nitro Abonnement", - PAYMENT_MODAL_BUTTON_CHANGE_CARD: "Kreditkarte aktualisieren", - PAYMENT_MODAL_BUTTON_CHANGE_PAYPAL: "PayPal-Account aktualisieren", - PAYPAL_ACCOUNT_VERIFYING: "Zu PayPal verbinden", - PAYPAL_CALLBACK_ERROR: "Etwas ist schief gelaufen, versuche es erneut.", - PERMISSION_CAMERA_ACCESS_DENIED: "Kamerazugriff verweigert - Discord braucht Videozugriff, um einen Videostream zu senden.", - GUILD_SETTINGS_SERVER_INVITE_BACKGROUND: "Soforteinladungshintergrund", - VERIFICATION_FOOTER: "Glaubst du du siehst dies fälschlicher Weise?", - USER_SETTINGS_NOTIFICATIONS_SHOW_BADGE_LABEL: "Ungelesene Nachrichten Indikator aktivieren", - USER_SETTINGS_NOTIFICATIONS_SHOW_BADGE_BODY: "Zeigt einen roten Punkt-Indikator auf dem App Symbol, wenn du ungelesene Nachrichten hast.", - USER_SETTINGS_NOTIFICATIONS_SHOW_FLASH_LABEL: "Taskleisten Blinken aktivieren", - USER_SETTINGS_NOTIFICATIONS_SHOW_FLASH_BODY: "Lässt das App Symbol in der Taskleiste blinken, wenn du neue Benachrichtigungen hast.", - HIDE_MUTED_CHANNELS: "Stumme Kanäle verstecken", - SHOW_MUTED_CHANNELS: "Stumme Kanäle anzeigen", - CREATE_CATEGORY: "Kategorie erstellen", - ADD_CHANNEL_TO_OVERRIDE: "Füge einen Kanal hinzu, um die Standard-Benachrichtigungseinstellungen zu überschreiben", - PRIVATE_CHANNEL_NOTE: "Wenn du einen Kanal auf privat stellst, können nur ausgewählte Rollen Nachrichten in diesem Kanal lesen oder sich mit ihm verbinden.", - PRIVATE_CATEGORY_NOTE: "Wenn du einen Kategorie auf privat stellst, werden alle privaten Kanäle in ihr die Rechte vererbt bekommen.", - USER_ACTIVITY_ERROR_FRIENDS_TITLE: "Freunde!", - USER_ACTIVITY_CANNOT_SPECTATE_SELF: "Du kannst dich nicht selbst beobachten.", - USER_ACTIVITY_LISTEN_ALONG: "Hör zu", - USER_ACTIVITY_CANNOT_PLAY_SELF: "Du kannst nicht mit dir selbst spielen.", - USER_ACTIVITY_CANNOT_SYNC_SELF: "Du kannst dir nicht selbst zuhören.", - USER_ACTIVITY_ALREADY_PLAYING: "Du spielst bereits dieses Spiel.", - USER_ACTIVITY_ALREADY_SYNCING: "Du hörst bereits zu.", - USER_ACTIVITY_NEVER_MIND: "Vergiss es", - USER_ACTIVITY_INVITE_EDUCATION_MODAL_TITLE: "Wusstest du schon?", - USER_ACTIVITY_INVITE_EDUCATION_MODAL_BODY_BOTTOM: "Halte Ausschau nach dem grünen Spielsymbol. Wenn du es siehst, dann kannst Spieleinladungen verschicken! Los hab Spaß!", - INVITE_EMBED_SESSION_HAS_ENDED: "Sitzung wurde beendet", - INVITE_EMBED_JOINED: "Beigetreten", - NUX_POST_REG_JOIN_SERVER_DESCRIPTION: "Hol das Meiste aus Discord raus, indem du einem Server beitrittst.", - VERIFY_BY_RECAPTCHA: "Durch reCaptcha bestätigen", - VERIFY_BY_RECAPTCHA_DESCRIPTION: "Wir müssen überprüfen, dass es sich bei dir um keinen Roboter handelt.", - CAPTCHA_FAILED: "Das Captcha ist fehlgeschlagen. Versuch es erneut.", - CAPTCHA_FAILED_UNSUPPORTED: "Das Captcha ist fehlgeschlagen. Dein Gerät wird nicht unterstützt.", - CAPTCHA_FAILED_PLAY_SERVICES: "Das Captcha ist fehlgeschlagen, Google Play wird benötigt. Nachdem du es heruntergeladen oder aktualisiert hast, versuche es erneut.", - SPOTIFY_APP_NOT_FOUND: "Die Spotify App konnte nicht gefunden werden.", - SPOTIFY_APP_NOT_OPENED: "Die Spotify App konnte nicht geöffnet werden.", - BROWSER_HANDOFF_DETECTING_TITLE: "Ermittle Account", - BROWSER_HANDOFF_DONE_DESCRIPTION: "Es wird versucht die Discord Desktop App zu authentisieren. Schließe nicht das Fenster.", - GAME_FEED_EMPTY_STATE_TITLE: "Niemand spielt gerade irgend etwas...", - GAME_FEED_DIVIDER_TITLE: "Kürzlich gespielte Spiele", - GAME_FEED_RECENT_ACTIVITY: "Letzte Aktivität´", - GAME_FEED_USER_PLAYING_JUST_STARTED: "Gerade angefangen zu spielen", - GAME_FEED_SETTINGS_SHOW_GAME_TITLE: "Du wirst nicht in dem Aktivitäten-Feed von anderen angezeigt!", - GAME_FEED_SETTINGS_SEARCH_MORE_FRIENDS: "Suche um mehr Freunde zu finden.", - GAME_FEED_SETTINGS_SEARCH_MORE_SERVER_MEMBERS: "Suche um mehr Servermitglieder zu finden.", - SPOTIFY_PREMIUM_UPGRADE_HEADER: "*Schallplatten reißen*", - SPOTIFY_PREMIUM_UPGRADE_BODY: "Schade, sieht aus als wärst du kein Spotify Premium Mitglied! Premium Mitglieder können bei anderen Benutzern mithören.", - SPOTIFY_PREMIUM_UPGRADE_BUTTON: "Spotify aktualisieren", - EXPERIMENT_BUTTON_CONNECT_FACEBOOK: "Facebook verbinden", - EXPERIMENT_BUTTON_CONNECT_STEAM: "Steam verbinden", - LFG_FULL: "Gruppe suchen (LFG)", - LFG_LANDING_TITLE: "Suchst du eine Gruppe?", - LFG_LANDING_BODY_1: "Kannste den letzten Platz nicht besetzen? Niemand online?", - LFG_LANDING_BODY_2: "Wähle ein Spiel aus und finde Gruppen mit Leuten mit denen du spielen kannst.", - LFG_SELECT_GAME: "Wähle ein Spiel um zu beginnen:", - LFG_NO_GROUPS_FOUND_TITLE: "Keine Gruppen verfügbar", - LFG_NO_GROUPS_FOUND_BODY: "Sei ein Trendsetter. Erstelle eine neue Gruppe!", - LFG_ALREADY_IN_PARTY_TITLE: "Du bist bereits in einer Gruppe", - LFG_ALREADY_IN_PARTY_BODY: "Möchtest du deine jetzige Gruppe verlassen, um diese Gruppe beizutreten?", - LFG_ALREADY_IN_PARTY_BODY_ALT: "Möchtest du deine jetzige Gruppe verlassen, um eine neue Gruppe zu erstellen?", - LFG_SWITCH_PARTY: "Gruppen wechseln", - GROUP_OWNER: "Gruppenbesitzer", - PARTY_EDIT_HEADER: "Gruppe bearbeiten", - PARTY_CREATE_NEW: "Neue Gruppe erstellen", - PARTY_CREATE_SELECT_GAME: "Spiel auswählen", - PARTY_CREATE_PARTY_TITLE: "Gruppenname", - PARTY_CREATE_PARTY_TITLE_PLACEHOLDER: "Wonach schaust du dich um?", - PARTY_CREATE_PARTY_DESCRIPTION: "Beschreibung", - PARTY_CREATE_PARTY_DESCRIPTION_PLACEHOLDER: "Provide more details like region, rank, classes, level, etc, to better find the right players.", - PARTY_CREATE_PARTY_SIZE: "Gruppengröße", - PARTY_LOCKED: "Geschlossen", - PARTY_FULL: "Volle Gruppe", - FULL: "Voll", - PARTY_JOIN: "Gruppe beitreten", - PARTY_JOINED: "In Gruppe", - LFG_GROUP_ADD_FRIENDS: "Füge Freunde deiner Gruppe hinzu", - LFG_INVITE_FULL_MAIN: "Diese Gruppe ist voll!", - LFG_JOIN_FAILED_TOO_MANY_MEMBERS: "Upps. Du kannst dieser Gruppe nicht beitreten, da sie bereits voll ist.", - LFG_JOIN_FAILED_BLOCKED: "Upps. Du kannst dieser Gruppe nicht beitreten. Entweder blockiert dich der Gruppenbesitzer oder du ihn.", - LFG_REPORT_HEADER: "LFG Gruppe melden", - LFG_LEAVE_BODY: "Bist du sicher, dass du die Gruppe verlassen möchtest?", - LFG_RATE_LIMIT_CREATE_BODY: "Du erstellst Gruppen zu schnell!", - LFG_RATE_LIMIT_JOIN_BODY: "Du trittst Gruppen zu schnell bei!", - LFG_HAS_CHANGES: "Gruppen aktualisieren" - }; - this.oldStrings = {}; - } - - onStart () { - var libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]'); - if (!libraryScript || performance.now() - libraryScript.getAttribute("date") > 600000) { - if (libraryScript) libraryScript.remove(); - libraryScript = document.createElement("script"); - libraryScript.setAttribute("type", "text/javascript"); - libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"); - libraryScript.setAttribute("date", performance.now()); - libraryScript.addEventListener("load", () => { - BDFDB.loaded = true; - this.initialize(); - }); - document.head.appendChild(libraryScript); - } - else if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize(); - this.startTimeout = setTimeout(() => {this.initialize();}, 30000); - } - - initialize () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - BDFDB.loadMessage(this); - this.LanguageUtils = BDFDB.WebModules.findByProperties("getLanguages"); - this.translateInterval = setInterval(() => { - if (document.querySelector("html").lang && document.querySelector("html").lang == "de") { - clearInterval(this.translateInterval); - for (var key in this.newStrings) { - this.oldStrings[key] = this.LanguageUtils.Messages[key]; - this.LanguageUtils.Messages[key] = this.newStrings[key]; - } - } - },100); - - return true; - } - else { - console.error(`%c[${this.name}]%c`, 'color: #3a71c1; font-weight: 700;', '', 'Fatal Error: Could not load BD functions!'); - return false; - } - } - - onStop () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - clearInterval(this.translateInterval); - for (var key in this.oldStrings) { - this.LanguageUtils.Messages[key] = this.oldStrings[key]; - } - - BDFDB.unloadMessage(this); - return true; - } - else { - return false; - } - } - } -}; diff --git a/PluginsV2/ForceImagePreviews/index.js b/PluginsV2/ForceImagePreviews/index.js index 6cbfe57434..19d528d319 100644 --- a/PluginsV2/ForceImagePreviews/index.js +++ b/PluginsV2/ForceImagePreviews/index.js @@ -3,7 +3,9 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { - this.waitTime = 3000; + this.patchModules = { + "Message":"componentDidMount" + }; } onStart () { @@ -26,45 +28,10 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.type == "characterData") { - setTimeout(() => {this.addPreviews(change.target.parentElement);},this.waitTime); - } - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if ($(node).attr("class") == BDFDB.disCN.message) setTimeout(() => {this.addPreviews($(node).find(BDFDB.dotCN.messagemarkup)[0]);},this.waitTime); - }); - } - } - ); - }); - BDFDB.addObserver(this, null, {name:"messageChangeObserver",instance:observer,multi:true}, {childList:true, characterData:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.message)) { - BDFDB.addObserver(this, node, {name:"messageChangeObserver",multi:true}, {childList:true, characterData:true, subtree:true}); - node.querySelectorAll(BDFDB.dotCN.messagemarkup).forEach(message => { - setTimeout(() => {this.addPreviews(message);},this.waitTime); - }); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver",instance:observer}, {childList:true}); - - this.addAllPreviews(); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -76,7 +43,7 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(".FIP-embed").forEach(embed => {embed.remove();}); + BDFDB.removeEles(".FIP-embed"); BDFDB.unloadMessage(this); return true; @@ -86,52 +53,32 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - this.addAllPreviews(); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver"}, {childList:true, subtree:true}); - } - } - // begin of own functions - addAllPreviews () { - document.querySelectorAll(".FIP-embed").forEach(embed => {embed.remove();}); - document.querySelectorAll(BDFDB.dotCN.messagegroup).forEach(messageContainer => { - BDFDB.addObserver(this, messageContainer, {name:"messageChangeObserver",multi:true}, {childList:true, characterData:true, subtree:true}); - messageContainer.querySelectorAll(BDFDB.dotCN.messagemarkup).forEach(message => { - this.addPreviews(message); - }); - }); - } - - addPreviews (message) { - let scroller = document.querySelector(BDFDB.dotCNS.chat + BDFDB.dotCN.messages); - if (!message || !scroller) return; - var messageData = BDFDB.getKeyInformation({node:message,key:"message",up:true}); - if (!messageData) return; - - let accessory = this.getAccessoryOfMessage(message); - if (accessory) { - let links = []; - for (let word of messageData.content.split(new RegExp("\\n|\\s|\\r|\\t|\\0"))) { - if (word.indexOf("https://") > -1 || word.indexOf("http://") > -1) { - if (word.indexOf("<") == 0 && word.indexOf(">") == word.length-1) links.push({src:word.slice(1,-1),embedded:false}); - else if (!accessory.querySelector(`${BDFDB.dotCN.embedimage}[href="${this.parseSrc(word)}"]`) && !accessory.querySelector(`${BDFDB.dotCN.embedtitlelink}[href="${this.parseSrc(word)}"]`)) { - links.push({src:word,embedded:false}); + processMessage (instance, wrapper) { + if (instance.props && instance.props.message) { + let accessory = wrapper.querySelector(BDFDB.dotCN.messageaccessory); + if (accessory) { + let links = []; + for (let word of instance.props.message.content.split(/\n|\s|\r|\t|\0/g)) { + if (word.indexOf("https://") > -1 || word.indexOf("http://") > -1) { + if (word.indexOf("<") == 0 && word.indexOf(">") == word.length-1) links.push({src:word.slice(1,-1),embedded:false}); + else if (!accessory.querySelector(`${BDFDB.dotCN.embedimage}[href="${this.parseSrc(word)}"]`) && !accessory.querySelector(`${BDFDB.dotCN.embedtitlelink}[href="${this.parseSrc(word)}"]`)) { + links.push({src:word,embedded:false}); + } + else links.push({src:word,embedded:true}); } - else links.push({src:word,embedded:true}); } + if (links.length > 0) this.addItemToAccessory(null, links, accessory); } - if (links.length > 0) this.addItemToAccessory(null, links, accessory, scroller); } } - addItemToAccessory (previmage, links, accessory, scroller) { + addItemToAccessory (previmage, links, accessory) { let item = links.shift(); if (!item) return; - else if (item.embedded) this.addItemToAccessory(item, links, accessory, scroller); + else if (item.embedded) this.addItemToAccessory(item, links, accessory); else { let itemsrc = this.parseSrc(item.src); require("request")(itemsrc, (error, response, result) => { @@ -139,13 +86,18 @@ module.exports = (Plugin, Api, Vendor) => { let imagethrowaway = document.createElement("img"); imagethrowaway.src = itemsrc; imagethrowaway.onload = () => { - let width = 400; + let width = imagethrowaway.naturalWidth > 400 ? 400 : imagethrowaway.naturalWidth; let height = Math.round(width*(imagethrowaway.naturalHeight/imagethrowaway.naturalWidth)); - if (!accessory.querySelector(`${BDFDB.dotCN.embedimage}[href="${itemsrc}"]`)) { - let embed = $(`
`)[0]; - this.insertEmbed(embed, previmage, links, accessory, scroller); + if (height > 300) { + width = Math.round(width*(300/height)); + height = 300; } - this.addItemToAccessory(item, links, accessory, scroller); + let checkedsrc = itemsrc.indexOf("imgur.com/") > -1 ? ("imgur.com/" + itemsrc.split("/")[3].split(".")[0]) : itemsrc; + if (!accessory.querySelector(`${BDFDB.dotCN.embedimage}[href*="${checkedsrc}"]`)) { + let embed = BDFDB.htmlToElement(`
`); + this.insertEmbed(embed, previmage, links, accessory); + } + this.addItemToAccessory(item, links, accessory); }; } else if (response && response.headers["server"] && response.headers["server"].toLowerCase().indexOf("youtube") > -1 && result.indexOf("yt-user-info") > -1) { @@ -153,37 +105,31 @@ module.exports = (Plugin, Api, Vendor) => { result = result.replace(new RegExp("[\\r|\\n|\\t]|[\\s]{2,}", "g"), ""); let width = 400; let height = Math.round(width*(result.split('
`)[0]; - $(embed).on("click." + this.name, BDFDB.dotCN.iconplay, (e) => { + let embed = BDFDB.htmlToElement(``); + BDFDB.addChildEventListener(embed, "click", BDFDB.dotCN.iconplay, () => { let videowrapper = embed.querySelector(BDFDB.dotCN.embedvideo); - while (videowrapper.firstChild) videowrapper.firstChild.remove(); - $(``).appendTo(videowrapper); + BDFDB.removeEles(videowrapper.childNodes); + videowrapper.appendChild(BDFDB.htmlToElement(``)); }); - this.insertEmbed(embed, previmage, links, accessory, scroller); + this.insertEmbed(embed, previmage, links, accessory); } - this.addItemToAccessory(item, links, accessory, scroller); + this.addItemToAccessory(item, links, accessory); } - else this.addItemToAccessory(item, links, accessory, scroller); + else this.addItemToAccessory(item, links, accessory); }); } } - insertEmbed (embed, previmage, links, accessory, scroller) { + insertEmbed (embed, previmage, links, accessory) { let prev = accessory.querySelector(`${BDFDB.dotCNS.embed + BDFDB.dotCN.embedimage}[href="${previmage ? this.parseSrc(previmage.src) : void 0}"]`); let next = accessory.querySelector(`${BDFDB.dotCNS.embed + BDFDB.dotCN.embedimage}[href="${links[0] ? this.parseSrc(links[0].src) : void 0}"]`); prev = prev ? prev : accessory.querySelector(`${BDFDB.dotCNS.embed + BDFDB.dotCN.embedtitlelink}[href="${previmage ? this.parseSrc(previmage.src) : void 0}"]`); next = next ? next : accessory.querySelector(`${BDFDB.dotCNS.embed + BDFDB.dotCN.embedtitlelink}[href="${links[0] ? this.parseSrc(links[0].src) : void 0}"]`); + let isempty = accessory.childElementCount == 0; + if (BDFDB.containsClass(embed.firstElementChild, BDFDB.disCN.embedimage)) embed.style.setProperty("pointer-events", "none", "important"); accessory.insertBefore(embed, prev ? prev.nextSibling : next); - scroller.scrollTop += embed.getBoundingClientRect().height; - } - - getAccessoryOfMessage (message) { - var accessory = null; - while (message && !message.querySelector(BDFDB.dotCN.messagegroup) && !accessory) { - accessory = message.querySelector(BDFDB.dotCN.messageaccessory); - message = message.parentElement; - } - return accessory; + let scroller = document.querySelector(BDFDB.dotCNS.chat + BDFDB.dotCN.messages); + if (scroller) scroller.scrollTop += (BDFDB.getRects(embed).height + (isempty ? 15 : 0)); } parseSrc (src) { diff --git a/PluginsV2/FriendNotifications/index.js b/PluginsV2/FriendNotifications/index.js index 65fec1fef1..834e42eedd 100644 --- a/PluginsV2/FriendNotifications/index.js +++ b/PluginsV2/FriendNotifications/index.js @@ -3,12 +3,16 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { + this.patchModules = { + "FluxContainer(FriendsOnline)":["componentDidMount","componentDidUpdate"] + }; + this.friendsOnlineList = {}; this.timeLog = []; this.timeLogModalMarkup = - ` + `
@@ -17,12 +21,16 @@ module.exports = (Plugin, Api, Vendor) => {

Friends LogIn/-Out Timelog

- - - - - - +
@@ -45,14 +53,12 @@ module.exports = (Plugin, Api, Vendor) => {

`; - this.dividerMarkup = `
`; - this.css = ` ${BDFDB.dotCN.guilds} > ${BDFDB.dotCN.friendsonline} { cursor: pointer; } .${this.name}-modal .log-time { - width: 100px; + width: 110px; } .${this.name}-modal .log-avatar { width: 35px; @@ -61,25 +67,25 @@ module.exports = (Plugin, Api, Vendor) => { background-position: center; border-radius: 50%; } - .FriendNotifications-settings .avatar-list { + .${this.name}-settings .avatar-list { display: flex; align-items: center; flex-wrap: wrap; } - .FriendNotifications-settings .type-toast, .FriendNotifications-settings .type-desktop { + .${this.name}-settings .type-toast, .${this.name}-settings .type-desktop { border-radius: 3px; padding: 0 3px; } - .FriendNotifications-settings .type-toast { + .${this.name}-settings .type-toast { background-color: #7289DA; } - .FriendNotifications-settings .type-desktop { + .${this.name}-settings .type-desktop { background-color: #43B581; } - .FriendNotifications-settings .settings-avatar.desktop { + .${this.name}-settings .settings-avatar.desktop { border-color: #43B581; } - .FriendNotifications-settings .settings-avatar { + .${this.name}-settings .settings-avatar { margin: 5px; width: 50px; height: 50px; @@ -90,24 +96,25 @@ module.exports = (Plugin, Api, Vendor) => { box-sizing: border-box; cursor: pointer; } - .FriendNotifications-settings .settings-avatar.desktop { + .${this.name}-settings .settings-avatar.desktop { border-color: #43B581; } - .FriendNotifications-settings .settings-avatar.disabled { + .${this.name}-settings .settings-avatar.disabled { border-color: #36393F; filter: grayscale(100%) brightness(50%); - } - .FriendNotifications-settings .disable-all { - color: white; - background-color: #36393F; - } - `; + }`; this.defaults = { settings: { muteOnDND: {value:false, description:"Do not notify me when I am DnD:"}, onlyOnOnline: {value:false, description:"Only notify me when a User logs in:"}, openOnClick: {value:false, description:"Open the DM when you click a Notification:"} + }, + notificationsounds: { + toastonline: {value:{url:null,song:null,mute:false}}, + toastoffline: {value:{url:null,song:null,mute:false}}, + desktoponline: {value:{url:null,song:null,mute:false}}, + desktopoffline: {value:{url:null,song:null,mute:false}} } }; } @@ -132,65 +139,21 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); this.FriendUtils = BDFDB.WebModules.findByProperties("getFriendIDs", "getRelationships"); this.ChannelUtils = BDFDB.WebModules.findByProperties("getDMFromUserId"); this.ChannelSwitchUtils = BDFDB.WebModules.findByProperties("selectPrivateChannel"); - this.UserMetaStore = BDFDB.WebModules.findByProperties("getStatuses", "getOnlineFriendCount"); + this.PrivateChannelUtils = BDFDB.WebModules.findByProperties("openPrivateChannel"); + this.UserMetaStore = BDFDB.WebModules.findByProperties("getStatus", "getOnlineFriendCount"); this.UserUtils = BDFDB.WebModules.findByProperties("getUsers"); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - let settings = BDFDB.getAllData(this, "settings"); - let notificationsound = BDFDB.loadAllData(this, "notificationsound"); - for (let id of this.FriendUtils.getFriendIDs()) { - let online = this.UserMetaStore.getStatus(id) != "offline"; - let user = this.UserUtils.getUser(id); - if (user && this.friendsOnlineList[id] != online && !BDFDB.loadData(id, this, "disabled")) { - this.timeLog.push({user, online, time: new Date()}); - if (!(settings.onlyOnOnline && !online) && !(settings.muteOnDND && BDFDB.getUserStatus() == "dnd")) { - let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; - let string = `${BDFDB.encodeToHTML(data.name ? data.name : user.username)} is ${online ? "online" : "offline"}.`; - let avatar = data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(user.id)); - let openChannel = () => { - if (settings.openOnClick){ - let DMid = this.ChannelUtils.getDMFromUserId(user.id); - if (DMid) { - require("electron").remote.getCurrentWindow().maximize(); - this.ChannelSwitchUtils.selectPrivateChannel(DMid); - } - } - }; - if (!BDFDB.loadData(id, this, "desktop")) { - let toast = BDFDB.showToast(`
${string}
`, {html:true, timeout:5000, type:(online ? "success" : null), icon:false}); - $(toast).on("click." + this.name, openChannel); - } - else { - BDFDB.showDesktopNotification(string, {icon:avatar, timeout:5000, click:openChannel, silent:notificationsound.mute, sound:notificationsound.song}); - } - } - } - this.friendsOnlineList[id] = online; - } - } - ); - }); - BDFDB.addObserver(this, `${BDFDB.dotCN.guilds} > ${BDFDB.dotCN.friendsonline}`, {name:"friendCountObserver",instance:observer}, {childList:true, subtree:true, characterData:true}); - for (let id of this.FriendUtils.getFriendIDs()) { this.friendsOnlineList[id] = this.UserMetaStore.getStatus(id) != "offline"; } - $(`${BDFDB.dotCN.guilds} > ${BDFDB.dotCN.friendsonline}`).first() - .on("mouseenter." + this.name, (e) => { - BDFDB.createTooltip("Timelog", e.currentTarget, {type:"right"}); - }) - .on("click." + this.name, (e) => { - this.showTimeLog(); - }); + + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -213,32 +176,24 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - - saveAudio (settingspanel) { - var successSavedAudio = (parsedurl, parseddata) => { + saveAudio (settingspanel, option) { + let successSavedAudio = (parsedurl, parseddata) => { if (parsedurl && parseddata) BDFDB.showToast(`Sound was saved successfully.`, {type:"success"}); - let notificationsound = BDFDB.loadAllData(this, "notificationsound"); + let notificationsound = BDFDB.getData(option, this, "notificationsounds"); notificationsound.url = parsedurl; notificationsound.song = parseddata; - BDFDB.saveAllData(notificationsound, this, "notificationsound"); + BDFDB.saveData(option, notificationsound, this, "notificationsounds"); }; - var url = settingspanel.querySelector(".songInput").value; + let url = settingspanel.querySelector(`.songInput[option="${option}"]`).value; if (url.length == 0) { - BDFDB.showToast(`Sound was set to the default sound.`, {type:"warn"}); + BDFDB.showToast(`Sound file was removed.`, {type:"warn"}); successSavedAudio(url, url); } else if (url.indexOf("http") == 0) { require("request")(url, (error, response, result) => { if (response) { - var type = response.headers["content-type"]; + let type = response.headers["content-type"]; if (type && (type.indexOf("octet-stream") > -1 || type.indexOf("audio") > -1 || type.indexOf("video") > -1)) { successSavedAudio(url, url); return; @@ -249,42 +204,84 @@ module.exports = (Plugin, Api, Vendor) => { } else { require("fs").readFile(url, (error, response) => { - if (error) { - BDFDB.showToast("Could not fetch file. Please make sure the file exists.", {type:"danger"}); - } - else { - successSavedAudio(url, `data:audio/mpeg;base64,${response.toString("base64")}`); - } + if (error) BDFDB.showToast("Could not fetch file. Please make sure the file exists.", {type:"danger"}); + else successSavedAudio(url, `data:audio/mpeg;base64,${response.toString("base64")}`); }); } } + processFluxContainerFriendsOnline (instance, wrapper) { + BDFDB.addEventListener(this, wrapper, "mouseenter", () => {BDFDB.createTooltip("Timelog", wrapper, {type:"right"});}); + BDFDB.addEventListener(this, wrapper, "click", () => {this.showTimeLog();}); + + let settings = BDFDB.getAllData(this, "settings"); + for (let id of this.FriendUtils.getFriendIDs()) { + let online = this.UserMetaStore.getStatus(id) != "offline"; + let user = this.UserUtils.getUser(id); + if (user && this.friendsOnlineList[id] != online && !BDFDB.loadData(id, this, "disabled")) { + this.timeLog.push({user, online, time: new Date()}); + if (!(settings.onlyOnOnline && !online) && !(settings.muteOnDND && BDFDB.getUserStatus() == "dnd")) { + let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; + let string = `${BDFDB.encodeToHTML(data.name ? data.name : user.username)} is ${online ? "online" : "offline"}.`; + let avatar = data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(user.id)); + let openChannel = () => { + if (settings.openOnClick) { + let DMid = this.ChannelUtils.getDMFromUserId(user.id) + if (DMid) this.ChannelSwitchUtils.selectPrivateChannel(DMid); + else this.PrivateChannelUtils.openPrivateChannel(BDFDB.myData.id, user.id); + require("electron").remote.getCurrentWindow().maximize(); + } + }; + if (!BDFDB.loadData(id, this, "desktop")) { + let toast = BDFDB.showToast(`
${string}
`, {html:true, timeout:5000, type:(online ? "success" : null), icon:false, selector:`friendnotifications-${online ? "online" : "offline"}-toast`}); + toast.addEventListener("click", openChannel); + let notificationsound = BDFDB.getData(online ? "toastonline" : "toastoffline", this, "notificationsounds"); + if (!notificationsound.mute && notificationsound.song) { + let audio = new Audio(); + audio.src = notificationsound.song; + audio.play(); + } + } + else { + let notificationsound = BDFDB.getData(online ? "desktoponline" : "desktopoffline", this, "notificationsounds"); + BDFDB.showDesktopNotification(string, {icon:avatar, timeout:5000, click:openChannel, silent:notificationsound.mute, sound:notificationsound.song}); + } + } + } + this.friendsOnlineList[id] = online; + } + } + showTimeLog () { - var timeLogModal = $(this.timeLogModalMarkup); + let timeLogModal = BDFDB.htmlToElement(this.timeLogModalMarkup); + let container = timeLogModal.querySelector(".entries"); + if (!container) return; let logs = this.timeLog.slice(0).reverse(); for (let log of logs) { - let entry = $(this.logEntryMarkup); - let divider = $(this.dividerMarkup); + if (container.childElementCount) container.appendChild(BDFDB.htmlToElement(`
`)); let data = BDFDB.loadData(log.user.id, "EditUsers", "users") || {}; - entry.find(".log-time").text(`[${log.time.toLocaleTimeString()}]`); - entry.find(".log-avatar").css("background-image", `url(${data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(log.user.id))})`); - entry.find(".log-description").text(`${data.name ? data.name : log.user.username} is ${log.online ? "online" : "offline"}.`); - timeLogModal.find(".entries").append(entry).append(divider); + let entry = BDFDB.htmlToElement(this.logEntryMarkup); + entry.querySelector(".log-time").innerText = `[${log.time.toLocaleTimeString()}]`; + entry.querySelector(".log-avatar").style.setProperty("background-image", `url(${data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(log.user.id))})`); + entry.querySelector(".log-description").innerText = `${data.name || log.user.username} is ${log.online ? "online" : "offline"}.`; + container.appendChild(entry) } - timeLogModal.find(BDFDB.dotCN.modaldivider + ":last-of-type").remove(); BDFDB.appendModal(timeLogModal); } getSettingsPanel () { - var settings = BDFDB.getAllData(this, "settings"); - var notificationsound = BDFDB.loadAllData(this, "notificationsound"); - var desktop = BDFDB.loadAllData(this, "desktop"); - var disabled = BDFDB.loadAllData(this, "disabled"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + let settings = BDFDB.getAllData(this, "settings"); + let notificationsounds = BDFDB.getAllData(this, "notificationsounds"); + let desktop = BDFDB.loadAllData(this, "desktop"); + let disabled = BDFDB.loadAllData(this, "disabled"); + let settingshtml = `
${this.name}
`; for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; + } + for (let key in notificationsounds) { + if (key.indexOf("desktop") == -1 || "Notification" in window) settingshtml += `
${key} notification sound:
Mute:
`; } - if ("Notification" in window) settingshtml += `
Desktop Notification Sound:
Mute:
`; settingshtml += `

Click on a Icon to toggle Notifications for that User:

`; if ("Notification" in window) settingshtml += `

Rightclick on a Icon to toggle Notifications for that User:

`; settingshtml += `
`; @@ -297,56 +294,56 @@ module.exports = (Plugin, Api, Vendor) => { } settingshtml += `
`; settingshtml += `

Batch set Users:

${"Notification" in window ? `` : ``}
`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", ".settings-checkbox", () => {this.updateSettings(settingspanel);}) - .on("click", ".btn-savesong", () => {this.saveAudio(settingspanel);}) - .on("click", ".mute-checkbox", (e) => { - var notificationsound = BDFDB.loadAllData(this, "notificationsound"); - notificationsound.mute = e.currentTarget.checked; - BDFDB.saveAllData(notificationsound, this, "notificationsound"); - }) - .on("mouseenter", ".settings-avatar", (e) => { - let user = this.UserUtils.getUser(e.currentTarget.getAttribute("user-id")); - let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; - BDFDB.createTooltip(data.name ? data.name : user.username, e.currentTarget, {type:"top"}); - }) - .on("contextmenu", ".settings-avatar", (e) => { - if (!("Notification" in window)) return; - let desktopoff = !e.currentTarget.classList.contains("desktop"); - let id = e.currentTarget.getAttribute("user-id"); - e.currentTarget.classList.remove("disabled"); - e.currentTarget.classList.toggle("desktop", desktopoff); - BDFDB.saveData(id, desktopoff, this, "desktop"); - BDFDB.removeData(id, this, "disabled"); - }) - .on("click", ".settings-avatar", (e) => { - let disableoff = !e.currentTarget.classList.contains("disabled"); - let id = e.currentTarget.getAttribute("user-id"); - e.currentTarget.classList.remove("desktop"); - e.currentTarget.classList.toggle("disabled", disableoff); - BDFDB.saveData(id, disableoff, this, "disabled"); - BDFDB.removeData(id, this, "desktop"); - }) - .on("click", ".disable-all, .toast-all, .desktop-all", (e) => { - let button = e.currentTarget; - let disableon = button.getAttribute("do-disable"); - let desktopon = button.getAttribute("do-desktop"); - let disabledata = BDFDB.loadAllData(this, "disabled"); - let desktopdata = BDFDB.loadAllData(this, "desktop"); - settingspanel.querySelectorAll(".settings-avatar").forEach(avatar => { - let id = avatar.getAttribute("user-id"); - avatar.classList.toggle("disabled", disableon); - avatar.classList.toggle("desktop", desktopon); - disableon ? disabledata[id] = true : delete disabledata[id]; - desktopon ? desktopdata[id] = true : delete desktopdata[id]; - }); - BDFDB.saveAllData(disabledata, this, "disabled"); - BDFDB.saveAllData(desktopdata, this, "desktop"); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "click", ".btn-savesong", e => {this.saveAudio(settingspanel, e.currentTarget.getAttribute("option"));}); + BDFDB.addEventListener(this, settingspanel, "click", ".mute-checkbox", e => { + let option = e.currentTarget.getAttribute("option"); + let notificationsound = BDFDB.getData(option, this, "notificationsounds"); + notificationsound.mute = e.currentTarget.checked; + BDFDB.saveData(option, notificationsound, this, "notificationsounds"); + }); + BDFDB.addEventListener(this, settingspanel, "mouseenter", ".settings-avatar", e => { + let user = this.UserUtils.getUser(e.currentTarget.getAttribute("user-id")); + let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; + BDFDB.createTooltip(data.name ? data.name : user.username, e.currentTarget, {type:"top"}); + }); + BDFDB.addEventListener(this, settingspanel, "contextmenu", ".settings-avatar", e => { + if (!("Notification" in window)) return; + let desktopoff = !BDFDB.containsClass(e.currentTarget, "desktop"); + let id = e.currentTarget.getAttribute("user-id"); + BDFDB.removeClass(e.currentTarget, "disabled"); + BDFDB.toggleClass(e.currentTarget, "desktop", desktopoff); + BDFDB.saveData(id, desktopoff, this, "desktop"); + BDFDB.removeData(id, this, "disabled"); + }); + BDFDB.addEventListener(this, settingspanel, "click", ".settings-avatar", e => { + let disableoff = !BDFDB.containsClass(e.currentTarget, "disabled"); + let id = e.currentTarget.getAttribute("user-id"); + BDFDB.removeClass(e.currentTarget, "desktop"); + BDFDB.toggleClass(e.currentTarget, "disabled", disableoff); + BDFDB.saveData(id, disableoff, this, "disabled"); + BDFDB.removeData(id, this, "desktop"); + }); + BDFDB.addEventListener(this, settingspanel, "click", ".disable-all, .toast-all, .desktop-all", e => { + let disableon = e.currentTarget.getAttribute("do-disable"); + let desktopon = e.currentTarget.getAttribute("do-desktop"); + let disabledata = BDFDB.loadAllData(this, "disabled"); + let desktopdata = BDFDB.loadAllData(this, "desktop"); + settingspanel.querySelectorAll(".settings-avatar").forEach(avatar => { + let id = avatar.getAttribute("user-id"); + BDFDB.toggleClass(avatar, "disabled", disableon); + BDFDB.toggleClass(avatar, "desktop", desktopon); + disableon ? disabledata[id] = true : delete disabledata[id]; + desktopon ? desktopdata[id] = true : delete desktopdata[id]; }); + BDFDB.saveAllData(disabledata, this, "disabled"); + BDFDB.saveAllData(desktopdata, this, "desktop"); + }); return settingspanel; } diff --git a/PluginsV2/GoogleSearchReplace/index.js b/PluginsV2/GoogleSearchReplace/index.js index eb934045c6..08debd1024 100644 --- a/PluginsV2/GoogleSearchReplace/index.js +++ b/PluginsV2/GoogleSearchReplace/index.js @@ -9,20 +9,21 @@ module.exports = (Plugin, Api, Vendor) => { this.defaults = { engines: { - _all: {value:true, name:BDFDB.getLibraryStrings().btn_all_text, url:null}, - Ask: {value:true, name:"Ask", url:"https://ask.com/web?q=" + this.textUrlReplaceString}, - Bing: {value:true, name:"Bing", url:"https://www.bing.com/search?q=" + this.textUrlReplaceString}, - DogPile: {value:true, name:"DogPile", url:"http://www.dogpile.com/search/web?q=" + this.textUrlReplaceString}, - DuckDuckGo: {value:true, name:"DuckDuckGo", url:"https://duckduckgo.com/?q=" + this.textUrlReplaceString}, - Google: {value:true, name:"Google", url:"https://www.google.com/search?q=" + this.textUrlReplaceString}, - GoogleScholar: {value:true, name:"Google Scholar", url:"https://scholar.google.com/scholar?q=" + this.textUrlReplaceString}, - Quora: {value:true, name:"Quora", url:"https://www.quora.com/search?q=" + this.textUrlReplaceString}, - Qwant: {value:true, name:"Qwant", url:"https://www.qwant.com/?t=all&q=" + this.textUrlReplaceString}, - Searx: {value:true, name:"Searx", url:"https://searx.me/?q=" + this.textUrlReplaceString}, - WolframAlpha: {value:true, name:"Wolfram Alpha", url:"https://www.wolframalpha.com/input/?i=" + this.textUrlReplaceString}, - Yandex: {value:true, name:"Yandex", url:"https://yandex.com/search/?text=" + this.textUrlReplaceString}, - Yahoo: {value:true, name:"Yahoo", url:"https://search.yahoo.com/search?p=" + this.textUrlReplaceString}, - YouTube: {value:true, name:"YouTube", url:"https://www.youtube.com/results?q=" + this.textUrlReplaceString} + _all: {value:true, name:BDFDB.getLibraryStrings().btn_all_text, url:null}, + Ask: {value:true, name:"Ask", url:"https://ask.com/web?q=" + this.textUrlReplaceString}, + Bing: {value:true, name:"Bing", url:"https://www.bing.com/search?q=" + this.textUrlReplaceString}, + DogPile: {value:true, name:"DogPile", url:"http://www.dogpile.com/search/web?q=" + this.textUrlReplaceString}, + DuckDuckGo: {value:true, name:"DuckDuckGo", url:"https://duckduckgo.com/?q=" + this.textUrlReplaceString}, + Google: {value:true, name:"Google", url:"https://www.google.com/search?q=" + this.textUrlReplaceString}, + GoogleScholar: {value:true, name:"Google Scholar", url:"https://scholar.google.com/scholar?q=" + this.textUrlReplaceString}, + Quora: {value:true, name:"Quora", url:"https://www.quora.com/search?q=" + this.textUrlReplaceString}, + Qwant: {value:true, name:"Qwant", url:"https://www.qwant.com/?t=all&q=" + this.textUrlReplaceString}, + UrbanDictionary: {value:true, name:"Urban Dictionary", url:"https://www.urbandictionary.com/define.php?term=" + this.textUrlReplaceString}, + Searx: {value:true, name:"Searx", url:"https://searx.me/?q=" + this.textUrlReplaceString}, + WolframAlpha: {value:true, name:"Wolfram Alpha", url:"https://www.wolframalpha.com/input/?i=" + this.textUrlReplaceString}, + Yandex: {value:true, name:"Yandex", url:"https://yandex.com/search/?text=" + this.textUrlReplaceString}, + Yahoo: {value:true, name:"Yahoo", url:"https://search.yahoo.com/search?p=" + this.textUrlReplaceString}, + YouTube: {value:true, name:"YouTube", url:"https://www.youtube.com/results?q=" + this.textUrlReplaceString} } }; @@ -33,13 +34,13 @@ module.exports = (Plugin, Api, Vendor) => {
`; this.messageContextSubMenuMarkup = - `
+ `
REPLACE_submenu_disabled_text
- ${Object.keys(this.defaults.engines).map((key, i) => `
${this.defaults.engines[key].name}
`).join("")} + ${Object.keys(this.defaults.engines).map((key, i) => `
${this.defaults.engines[key].name}
`).join("")}
`; } @@ -64,25 +65,9 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu)) { - this.onContextMenu(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"messageContextObserver",instance:observer}, {childList: true}); - return true; } else { @@ -103,82 +88,64 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "engines"); - } - changeLanguageStrings () { this.messageContextEntryMarkup = this.messageContextEntryMarkup.replace("REPLACE_context_googlesearchreplace_text", this.labels.context_googlesearchreplace_text); this.messageContextSubMenuMarkup = this.messageContextSubMenuMarkup.replace("REPLACE_submenu_disabled_text", this.labels.submenu_disabled_text); } - onContextMenu (context) { - if (!context || !context.tagName || !context.parentElement || context.querySelector(".googlereplacesearch-item")) return; - for (let group of context.querySelectorAll(BDFDB.dotCN.contextmenuitemgroup)) { - if (BDFDB.getKeyInformation({"node":group, "key":"handleSearchWithGoogle"})) { - var text = BDFDB.getKeyInformation({"node":group, "key":"value"}); - if (text) { - $(group).find(BDFDB.dotCN.contextmenuitem).hide(); - $(group).append(this.messageContextEntryMarkup) - .on("mouseenter", ".googlereplacesearch-item", (e) => { - this.createContextSubMenu(text, e, context); - }); + onNativeContextMenu (instance, menu) { + if (instance.props && instance.props.type == "NATIVE_TEXT" && instance.props.value && !menu.querySelector(".reverseimagesearch-item")) { + let searchentry = BDFDB.React.findDOMNodeSafe(BDFDB.getOwnerInstance({node:menu,props:["handleSearchWithGoogle"]})); + if (searchentry) this.appendItem(instance, searchentry, instance.props.value); + } + } - BDFDB.updateContextPosition(context); - } - break; + onMessageContextMenu (instance, menu) { + if (instance.props && instance.props.message && instance.props.channel && instance.props.target && !menu.querySelector(".googlereplacesearch-item")) { + let text = document.getSelection().toString(); + if (text) { + let searchentry = BDFDB.React.findDOMNodeSafe(BDFDB.getOwnerInstance({node:menu,props:["handleSearchWithGoogle"]})); + if (searchentry) this.appendItem(instance, searchentry, text); } } } - createContextSubMenu (text, e, context) { - var messageContextSubMenu = $(this.messageContextSubMenuMarkup); - - messageContextSubMenu - .on("click", ".GRS-item", (e2) => { - $(context).hide(); - var engine = e2.currentTarget.getAttribute("engine"); + appendItem (instance, target, text) { + let messageContextEntry = BDFDB.htmlToElement(this.messageContextEntryMarkup); + target.parentElement.insertBefore(messageContextEntry, target.nextElementSibling); + messageContextEntry.addEventListener("mouseenter", () => { + let messageContextSubMenu = BDFDB.htmlToElement(this.messageContextSubMenuMarkup); + let engines = BDFDB.getAllData(this, "engines"); + for (let key in engines) if (!engines[key]) BDFDB.removeEles(messageContextSubMenu.querySelector("[engine='" + key + "']")); + if (messageContextSubMenu.querySelector(".GRS-item")) BDFDB.removeEles(messageContextSubMenu.querySelector(".alldisabled-item")); + BDFDB.addChildEventListener(messageContextSubMenu, "click", ".GRS-item", e => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + let engine = e.currentTarget.getAttribute("engine"); if (engine == "_all") { - var engines = BDFDB.getAllData(this, "engines"); - for (let key in engines) { - if (key != "_all" && engines[key]) window.open(this.defaults.engines[key].url.replace(this.textUrlReplaceString, encodeURIComponent(text)), "_blank"); - } - } - else { - window.open(this.defaults.engines[engine].url.replace(this.textUrlReplaceString, encodeURIComponent(text)), "_blank"); + for (let key in engines) if (key != "_all" && engines[key]) window.open(this.defaults.engines[key].url.replace(this.textUrlReplaceString, encodeURIComponent(text)), "_blank"); } + else window.open(this.defaults.engines[engine].url.replace(this.textUrlReplaceString, encodeURIComponent(text)), "_blank"); }); - - var engines = BDFDB.getAllData(this, "engines"); - for (let key in engines) { - if (!engines[key]) messageContextSubMenu.find("[engine='" + key + "']").remove(); - } - if (messageContextSubMenu.find(".GRS-item").length > 0) { - messageContextSubMenu.find(".alldisabled-item").remove(); - } - - BDFDB.appendSubMenu(e.currentTarget, messageContextSubMenu); + BDFDB.appendSubMenu(messageContextEntry, messageContextSubMenu); + }); + BDFDB.toggleEles(target, false); } getSettingsPanel () { - var engines = BDFDB.getAllData(this, "engines"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + let engines = BDFDB.getAllData(this, "engines"); + let settingshtml = `
${this.name}
`; settingshtml += `

Search Engines:

`; for (let key in engines) { - settingshtml += `

${this.defaults.engines[key].name}

`; + settingshtml += `

${this.defaults.engines[key].name}

`; } settingshtml += `
`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); + BDFDB.initElements(settingspanel, this); return settingspanel; } diff --git a/PluginsV2/GoogleTranslateOption/index.js b/PluginsV2/GoogleTranslateOption/index.js index dc832d0012..0502a539c6 100644 --- a/PluginsV2/GoogleTranslateOption/index.js +++ b/PluginsV2/GoogleTranslateOption/index.js @@ -5,6 +5,12 @@ module.exports = (Plugin, Api, Vendor) => { initConstructor () { this.labels = {}; + this.patchModules = { + "ChannelTextArea":"componentDidMount", + "Message":"componentDidMount", + "MessageOptionPopout":"componentDidMount" + }; + this.languages = {}; this.doTranslate = false; @@ -12,10 +18,11 @@ module.exports = (Plugin, Api, Vendor) => { this.defaults = { settings: { - sendOriginalMessage: {value:false, description:"Send the original message together with the translation."} + addTranslateButton: {value:true, description:"Adds an translate button to the chatbar."}, + sendOriginalMessage: {value:false, description:"Send the original message together with the translation."} }, translators: { - useGoogle: {value:true, choice1:"DeepL", choice2:"Google", popout:true} + useGoogle: {value:true, choice1:"DeepL", choice2:"Google", popout:true} }, choices: { inputContext: {value:"auto", place:"Context", direction:"Input", popout:false, description:"Input Language in selected Messages:"}, @@ -25,44 +32,54 @@ module.exports = (Plugin, Api, Vendor) => { } }; - this.messageContextEntryMarkup = + this.messageTranslateContextEntryMarkup = `
-
+
REPLACE_context_messagetranslateoption_text
`; - this.messageContextEntryMarkup2 = + this.messageUntranslateContextEntryMarkup = `
-
+
+
REPLACE_context_messageuntranslateoption_text
+
+
+
`; + + this.messageSearchContextEntryMarkup = + `
+
REPLACE_context_googletranslateoption_text
`; - this.optionButtonMarkup = - `
`; + this.popoutTranslateEntryMarkup = + ``; - this.optionsPopoutMarkup = - `
-
`; - - this.popoutEntryMarkup = - `
REPLACE_popout_translateoption_text
`; + this.popoutUntranslateEntryMarkup = + ``; this.translateButtonMarkup = - ` - - `; + `
+
+ + + +
+
`; this.reverseButtonMarkup = ` `; - this.translatePopoutMarkup = `
@@ -99,14 +116,13 @@ module.exports = (Plugin, Api, Vendor) => {

Translator:

${this.defaults.translators[key].choice1}

- +

${this.defaults.translators[key].choice2}

`).join("")}
`; - this.DeepLTranslateAPI = function () { var INPUT, OUTPUT, clearInput, current, domReady, enabled, executeScript, getLanguage, getOutput, langI, langO, setInput, setLanguage, timer, wc, webview; var _extends = Object.assign || function (target) { @@ -304,35 +320,35 @@ module.exports = (Plugin, Api, Vendor) => { }.call(this); this.css = ` - .chat form textarea { - padding-right: 0 !important; + ${BDFDB.dotCN.textareainner} ${BDFDB.dotCN.textareapickerbuttons} { + height: auto; } - .translate-button { - position: absolute; - right: 46px; - top: 11px; - opacity: 0.2; - transition: all 200ms ease; + ${BDFDB.dotCN.textareainner} .send-button { + top: calc(50% - 15px); + right: 9px; } - ${BDFDB.dotCN.themedark} .translate-button { - fill: #fff; + ${BDFDB.dotCN.textareainner} .send-button, + ${BDFDB.dotCN.textareainner} ${BDFDB.dotCN.button} { + max-height: unset; } - ${BDFDB.dotCN.themelight} .translate-button { - fill: #4f545c; - } - - .translate-button.active { - fill: #F04747; + ${BDFDB.dotCN.textareabuttonwrapper}.popout-open ${BDFDB.dotCN.textareabutton}.translate-button { opacity: 1; } - .translate-button:hover { - cursor: pointer; - opacity: 1; - transform: scale(1.1); + ${BDFDB.dotCN.textareabuttonwrapper + BDFDB.dotCNS.textareabuttonactive + BDFDB.dotCN.textareabutton}.translate-button { + color: #F04747 !important; + } + + ${BDFDB.dotCNS.textareabuttonwrapper + BDFDB.dotCN.textareabutton}.translate-button ${BDFDB.dotCN.textareaicon} { + height: 24px; + width: 24px; + } + + ${BDFDB.dotCN.textareabuttonwrapper}.popout-open ${BDFDB.dotCN.textareabutton}.translate-button ${BDFDB.dotCN.textareaicon} { + transform: none; } .reverse-button { @@ -358,14 +374,7 @@ module.exports = (Plugin, Api, Vendor) => { width: 400px; } - ${BDFDB.dotCN.themedark} ${BDFDB.dotCN.popout}.popout-googletranslate ${BDFDB.dotCN.popoutthemedpopout} { - -webkit-box-shadow: 0 2px 10px 0 rgba(0,0,0,20%); - background-color: #2f3136; - border: 1px solid rgba(28,36,43,.6); - box-shadow: 0 2px 10px 0 rgba(0,0,0,.2); - } - - ${BDFDB.dotCN.selectmenuouter} .inChat { + ${BDFDB.dotCN.selectmenuouter}.inChat { top: 0%; transform: translateY(-100%); border-radius: 4px 4px 0 0; @@ -394,73 +403,18 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu)) { - this.onContextMenu(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"messageContextObserver",instance:observer}, {childList: true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.classList && node.classList.contains(BDFDB.disCN.messagegroup)) { - node.querySelectorAll(BDFDB.dotCN.message).forEach(message => {this.addOptionButton(message);}); - } - else if (node && node.tagName && node.classList && node.classList.contains(BDFDB.disCN.message)) { - this.addOptionButton(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver",instance:observer}, {childList:true, subtree:true}); - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.optionpopout) && !node.querySelector(".btn-item-googletranslateoption")) { - $(node).find(BDFDB.dotCN.optionpopout).append(this.popoutEntryMarkup); - this.addClickListener(node); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.popouts, {name:"optionPopoutObserver",instance:observer}, {childList: true}); - - $(document).off("click." + this.name, BDFDB.dotCN.optionpopoutbutton).off("contextmenu." + this.name, BDFDB.dotCN.message) - .on("click." + this.name, BDFDB.dotCN.optionpopoutbutton, (e) => { - this.getMessageData($(BDFDB.dotCN.message).has(e.currentTarget)[0]); - }) - .on("contextmenu." + this.name, BDFDB.dotCN.message, (e) => { - this.getMessageData(e.currentTarget); - }); - - document.querySelectorAll(BDFDB.dotCNS.messagegroup + BDFDB.dotCN.message).forEach(message => {this.addOptionButton(message);}); - - document.querySelectorAll(BDFDB.dotCNS.chat + "form textarea").forEach(textarea => {this.addTranslationButton(textarea);}); + this.GuildUtils = BDFDB.WebModules.findByProperties("getGuilds","getGuild"); + this.ChannelUtils = BDFDB.WebModules.findByProperties("getChannels","getChannel"); + this.LastGuildStore = BDFDB.WebModules.findByProperties("getLastSelectedGuildId"); + this.LastChannelStore = BDFDB.WebModules.findByProperties("getLastSelectedChannelId"); this.setLanguage(); + BDFDB.WebModules.forceAllUpdates(this); + return true; } else { @@ -472,14 +426,12 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { this.stopDeepL(); - $(document).off("click." + this.name, BDFDB.dotCN.optionpopoutbutton).off("contextmenu." + this.name, BDFDB.dotCN.message); document.querySelectorAll(BDFDB.dotCN.message + ".translated").forEach(message => { this.resetMessage(message); }); - document.querySelectorAll(".translate-button").forEach(button => {button.remove();}); - document.querySelectorAll(BDFDB.dotCNS.chat + "form textarea").forEach(textarea => {textarea.parentElement.style.paddingRight = "0px";}); + BDFDB.removeEles(".translate-button-wrapper", ".popout-googletranslate"); BDFDB.unloadMessage(this); return true; @@ -489,80 +441,9 @@ module.exports = (Plugin, Api, Vendor) => { } } - onSwitch () { - if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - document.querySelectorAll(BDFDB.dotCNS.chat + "form textarea").forEach(textarea => {this.addTranslationButton(textarea);}); - document.querySelectorAll(BDFDB.dotCNS.messages + BDFDB.dotCN.message).forEach(message => {this.addOptionButton(message);}); - } - } - // begin of own functions - changeLanguageStrings () { - this.messageContextEntryMarkup = this.messageContextEntryMarkup.replace("REPLACE_context_messagetranslateoption_text", this.labels.context_messagetranslateoption_text); - - this.messageContextEntryMarkup2 = this.messageContextEntryMarkup2.replace("REPLACE_context_googletranslateoption_text", this.labels.context_googletranslateoption_text); - - this.popoutEntryMarkup = this.popoutEntryMarkup.replace("REPLACE_popout_translateoption_text", this.labels.popout_translateoption_text); - } - - updateSettings (settingspanel) { - var data = {}; - for (let input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - let option = input.getAttribute("option"); - let value = input.value; - if (option && value) { - if (!data[option]) data[option] = {}; - data[option][input.value] = input.checked; - } - } - for (let option in data) { - BDFDB.saveAllData(data[option], this, option); - } - this.setLanguage(); - } - - onContextMenu (context) { - if (!context || !context.tagName || !context.parentElement) return; - for (let group of context.querySelectorAll(BDFDB.dotCN.contextmenuitemgroup)) { - if (!context.querySelector(".messagetranslateoption-item") && BDFDB.getKeyInformation({"node":group, "key":"displayName", "value":"MessagePinItem"})) { - $(this.messageContextEntryMarkup).insertAfter(group) - .on("click", ".messagetranslateoption-item", () => { - $(context).hide(); - this.translateMessage(); - }); - - BDFDB.updateContextPosition(context); - } - if (!context.querySelector(".googletranslateoption-item") && BDFDB.getKeyInformation({"node":group, "key":"handleSearchWithGoogle"})) { - var text = BDFDB.getKeyInformation({"node":group, "key":"value"}); - if (text) { - $(this.messageContextEntryMarkup2).insertAfter(group) - .on("mouseenter", ".googletranslateoption-item", (e) => { - this.translateText(text, "context", (translation, input, output) => { - if (translation) { - var tooltiptext = `From ${input.name}:\n${text}\n\nTo ${output.name}:\n${translation}`; - var customTooltipCSS = ` - .googletranslate-tooltip { - max-width: ${window.outerWidth - $(e.currentTarget).offset().left - $(e.currentTarget).outerWidth()}px !important; - }`; - BDFDB.createTooltip(tooltiptext, e.currentTarget, {type: "right",selector:"googletranslate-tooltip",css:customTooltipCSS}); - } - }); - }) - .on("click", ".googletranslateoption-item", (e) => { - $(context).hide(); - window.open(this.getGoogleTranslatePageURL(input.id, output.id, text), "_blank"); - }); - } - - BDFDB.updateContextPosition(context); - } - } - - } - startDeepL () { this.stopDeepL(); this.DeepLTranslate = new this.DeepLTranslateAPI(); @@ -574,6 +455,57 @@ module.exports = (Plugin, Api, Vendor) => { this.DeepLTranslate = undefined; } + changeLanguageStrings () { + this.messageTranslateContextEntryMarkup = this.messageTranslateContextEntryMarkup.replace("REPLACE_context_messagetranslateoption_text", this.labels.context_messagetranslateoption_text); + this.messageUntranslateContextEntryMarkup = this.messageUntranslateContextEntryMarkup.replace("REPLACE_context_messageuntranslateoption_text", this.labels.context_messageuntranslateoption_text); + this.messageSearchContextEntryMarkup = this.messageSearchContextEntryMarkup.replace("REPLACE_context_googletranslateoption_text", this.labels.context_googletranslateoption_text); + + this.popoutTranslateEntryMarkup = this.popoutTranslateEntryMarkup.replace("REPLACE_popout_translateoption_text", this.labels.popout_translateoption_text); + this.popoutUntranslateEntryMarkup = this.popoutUntranslateEntryMarkup.replace("REPLACE_popout_untranslateoption_text", this.labels.popout_untranslateoption_text); + } + + onMessageContextMenu (instance, menu) { + if (instance.props && instance.props.message && instance.props.channel && instance.props.target && !menu.querySelector(".googletranslateoption-item")) { + let {messagediv, pos} = this.getMessageAndPos(instance.props.target); + if (!messagediv || pos == -1) return; + let pinentry = BDFDB.React.findDOMNodeSafe(BDFDB.getOwnerInstance({node:menu,name:"MessagePinItem"})); + let messageTranslateContextEntry = BDFDB.htmlToElement(BDFDB.containsClass(messagediv, "translated") ? this.messageUntranslateContextEntryMarkup : this.messageTranslateContextEntryMarkup); + if (pinentry) pinentry.parentElement.insertBefore(messageTranslateContextEntry, pinentry.nextElementSibling); + else menu.insertBefore(messageTranslateContextEntry, menu.firstElementChild); + let translateitem = messageTranslateContextEntry.querySelector(".googletranslateoption-item"); + translateitem.addEventListener("click", () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + this.translateMessage(instance.props.message, instance.props.target, instance.props.channel); + }); + if (BDFDB.isPluginEnabled("MessageUtilities")) { + BDFDB.setContextHint(translateitem, bdplugins.MessageUtilities.plugin.getActiveShortcutString("__Translate_Message")); + } + let text = document.getSelection().toString(); + if (text) { + let searchentry = BDFDB.React.findDOMNodeSafe(BDFDB.getOwnerInstance({node:menu,props:["handleSearchWithGoogle"]})); + if (searchentry) { + let messageSearchContextEntry = BDFDB.htmlToElement(this.messageSearchContextEntryMarkup); + searchentry.parentElement.appendChild(messageSearchContextEntry); + let searchitem = messageSearchContextEntry.querySelector(".googletranslateoption-search-item"); + searchitem.addEventListener("mouseenter", e => { + this.translateText(text, "context", (translation, input, output) => { + if (translation) { + var openGoogleSearch = () => { + instance._reactInternalFiber.return.memoizedProps.closeContextMenu(); + window.open(this.getGoogleTranslatePageURL(input.id, output.id, text), "_blank"); + }; + searchitem.removeEventListener("click", openGoogleSearch); + searchitem.addEventListener("click", openGoogleSearch); + let rects = BDFDB.getRects(searchitem); + BDFDB.createTooltip(`From ${input.name}:\n${text}\n\nTo ${output.name}:\n${translation}`, searchitem, {type: "right",selector:"googletranslate-tooltip",style:`max-width: ${window.outerWidth - rects.left - rects.width}px !important;`}); + } + }); + }); + } + } + } + } + setLanguage () { this.languages = Object.assign({}, {"auto": {name:"Auto", id:"auto", integrated:false, dic:false, deepl:true}}, @@ -584,9 +516,7 @@ module.exports = (Plugin, Api, Vendor) => { this.languages = BDFDB.filterObject(this.languages, (lang) => {return lang.deepl == true ? lang : null}); this.startDeepL(); } - else { - this.stopDeepL(); - } + else this.stopDeepL(); } getLanguageChoice (direction, place) { @@ -597,159 +527,125 @@ module.exports = (Plugin, Api, Vendor) => { return choice; } - addOptionButton (message) { - if (!message.querySelector(BDFDB.dotCN.optionpopoutbutton) && !message.querySelector(BDFDB.dotCN.messagesystem) && !message.querySelector(BDFDB.dotCN.messageuploadcancel)) { - $(this.optionButtonMarkup).insertBefore(message.querySelector(BDFDB.dotCN.messagetext).firstChild); - $(message).off("click." + this.name).on("click." + this.name, ".btn-googletranslateoption", (e) => { - this.openOptionPopout(e); - }); - } - } - - openOptionPopout (e) { - var wrapper = e.currentTarget; - if (wrapper.classList.contains(BDFDB.disCN.optionpopoutopen)) return; - wrapper.classList.add(BDFDB.disCN.optionpopoutopen); - var popout = $(this.optionsPopoutMarkup); - $(BDFDB.dotCN.popouts).append(popout); - $(popout).find(BDFDB.dotCN.optionpopout).append(this.popoutEntryMarkup); - this.addClickListener(popout); - - popout - .css("left", e.pageX - ($(popout).outerWidth() / 2) + "px") - .css("top", e.pageY + "px"); - - $(document).on("mousedown.optionpopout" + this.name, (e2) => { - if (popout.has(e2.target).length == 0) { - $(document).off("mousedown.optionpopout" + this.name); - popout.remove(); - setTimeout(() => {wrapper.classList.remove(BDFDB.disCN.optionpopoutopen);},300); - } - }); - } - - addClickListener (popout) { - $(popout) - .off("click." + this.name, ".btn-item-googletranslateoption") - .on("click." + this.name, ".btn-item-googletranslateoption", (e) => { - $(BDFDB.dotCN.popout).has(BDFDB.dotCN.optionpopout).hide(); - this.translateMessage(); - setTimeout(() => { - var popoutbutton = document.querySelector(BDFDB.dotCN.optionpopoutbutton + BDFDB.dotCN.optionpopoutopen); - if (popoutbutton) popoutbutton.classList.remove(BDFDB.disCN.optionpopoutopen); - },300); - }); - } - - getMessageData (div) { - if (div && !div.querySelector(BDFDB.dotCN.messagesystem)) { - var messagegroup = $(BDFDB.dotCN.messagegroup).has(div); - var pos = messagegroup.find(BDFDB.dotCN.message).index(div); - if (messagegroup[0] && pos > -1) { - var info = BDFDB.getKeyInformation({"node":div,"key":"messages","up":true,"time":1000}); - if (info) this.message = Object.assign({},info[pos],{"div":div, "group":messagegroup[0], "pos":pos}); - } - } - else { - this.message = null; - } - } - - addTranslationButton (textarea) { - if (!textarea) return; - var textareaWrap = textarea.parentElement; - if (textareaWrap && !textareaWrap.classList.contains(BDFDB.disCN.textareainnerdisabled) && !textareaWrap.querySelector(".translate-button")) { - var textareaInstance = BDFDB.getOwnerInstance({"node":textarea, "props":["handlePaste","saveCurrentText"], "up":true}); - if (textareaInstance && textareaInstance.props && textareaInstance.props.type) { - var button = $(this.translateButtonMarkup)[0]; - $(button).appendTo(textareaWrap) - .on("click." + this.name, () => { - this.openTranslatePopout(button); - }) - .on("contextmenu." + this.name, () => { - this.translating = !this.translating; - document.querySelectorAll(BDFDB.dotCNS.textareawrapchat + ".translate-button").forEach(btn => {btn.classList.toggle("active", this.translating);}); - }); - button.classList.add(textareaInstance.props.type); - button.classList.toggle("active", this.translating); - var sendButtonEnabled = BDFDB.isPluginEnabled("SendButton"); - if (sendButtonEnabled) button.style.marginRight = "40px"; - textareaWrap.style.paddingRight = sendButtonEnabled ? "110px" : "70px"; - $(textarea) - .off("input." + this.name) - .on("input." + this.name, () => { - if (this.doTranslate) { - this.doTranslate = false; - if (document.activeElement == textarea) { - var text = textarea.value; + processChannelTextArea (instance, wrapper) { + if (instance.props && instance.props.type && instance.props.type == "normal" && !instance.props.disabled && !wrapper.querySelector(".translate-button-wrapper") && BDFDB.getData("addTranslateButton", this, "settings")) { + let textarea = wrapper.querySelector("textarea"); + if (textarea) { + var buttoncontainer = wrapper.querySelector(BDFDB.dotCN.textareapickerbuttons); + if (!buttoncontainer) return; + var translateButton = BDFDB.htmlToElement(this.translateButtonMarkup); + translateButton.addEventListener("click", () => { + this.openTranslatePopout(translateButton); + }); + translateButton.addEventListener("contextmenu", () => { + this.translating = !this.translating; + BDFDB.toggleClass(document.querySelectorAll(BDFDB.dotCNS.textareawrapchat + ".translate-button-wrapper"), BDFDB.disCN.textareabuttonactive, this.translating); + }); + buttoncontainer.insertBefore(translateButton, buttoncontainer.firstElementChild); + BDFDB.addClass(translateButton, instance.props.type); + BDFDB.toggleClass(translateButton, BDFDB.disCN.textareabuttonactive, this.translating); + BDFDB.addEventListener(this, textarea, "input", () => { + if (this.doTranslate) { + this.doTranslate = false; + if (document.activeElement == textarea) { + var text = textarea.value; + textarea.focus(); + textarea.selectionStart = 0; + textarea.selectionEnd = text.length; + document.execCommand("insertText", false, ""); + this.translateText(text, "message", (translation, input, output) => { + translation = !translation ? text : (BDFDB.getData("sendOriginalMessage", this, "settings") ? text + "\n\n" + translation : translation); textarea.focus(); - textarea.selectionStart = 0; - textarea.selectionEnd = text.length; - document.execCommand("insertText", false, ""); - this.translateText(text, "message", (translation, input, output) => { - translation = !translation ? text : (BDFDB.getData("sendOriginalMessage", this, "settings") ? text + "\n\n" + translation : translation); - textarea.focus(); - document.execCommand("insertText", false, translation + " "); - BDFDB.triggerSend(textarea); - }); - } - } - }) - .off("keydown." + this.name) - .on("keydown." + this.name, e => { - if (textarea.value && this.translating && !e.shiftKey && e.which == 13 && !textareaWrap.querySelector(BDFDB.dotCN.autocomplete)) { - this.doTranslate = true; - $(textarea).trigger("input"); - } - }); - } - } - } - - translateMessage () { - if (this.message && this.message.content) { - var message = this.message.div; - if (!message.classList.contains("translated")) { - this.translateText(this.message.content, "context", (translation, input, output) => { - if (translation) { - var markup = message.querySelector(BDFDB.dotCN.messagecontent) || message.querySelector(BDFDB.dotCN.messagemarkup); - if (markup) { - $(markup).data("orightmlGoogleTranslate", markup.innerHTML); - markup.innerText = translation; - $(`(${this.labels.translated_watermark_text})`) - .on("mouseenter." + this.name, (e) => { - BDFDB.createTooltip(`
From: ${input.name}
To: ${output.name}
`, e.currentTarget, {html:true, type:"top", selector:"translation-tooltip"}); - }) - .appendTo(markup); - message.classList.add("translated"); + document.execCommand("insertText", false, translation + " "); + BDFDB.triggerSend(textarea); + }); } } }); - } - else { - this.resetMessage(message); + BDFDB.addEventListener(this, textarea, "keydown", e => { + if (textarea.value && this.translating && !e.shiftKey && e.which == 13 && !wrapper.querySelector(BDFDB.dotCN.autocomplete)) { + this.doTranslate = true; + textarea.dispatchEvent(new Event("input")); + } + }); } } - this.message = null; } - resetMessage (message) { - $(message) - .removeClass("translated") - .find(BDFDB.dotCN.messageedited + ".translated").remove(); + processMessage (instance, wrapper) { + if (instance.props && typeof instance.props.renderButtons == "function" && !wrapper.querySelector(BDFDB.dotCN.optionpopoutbutton)) { + let buttonwrap = wrapper.querySelector(BDFDB.dotCN.messagebuttoncontainer); + if (buttonwrap) { + let optionPopoutButton = BDFDB.htmlToElement(`
`); + optionPopoutButton.addEventListener("click", () => {BDFDB.createMessageOptionPopout(optionPopoutButton);}); + buttonwrap.appendChild(optionPopoutButton); + } + } + } - var markup = message.querySelector(BDFDB.dotCN.messagecontent) || message.querySelector(BDFDB.dotCN.messagemarkup); - markup.innerHTML = $(markup).data("orightmlGoogleTranslate"); + processMessageOptionPopout (instance, wrapper) { + if (instance.props.message && instance.props.channel && instance._reactInternalFiber.memoizedProps.target && !wrapper.querySelector(".personalpin-itembtn")) { + let {messagediv, pos} = this.getMessageAndPos(instance._reactInternalFiber.memoizedProps.target); + if (!messagediv || pos == -1) return; + let popoutTranslateEntry = BDFDB.htmlToElement(BDFDB.containsClass(messagediv, "translated") ? this.popoutUntranslateEntryMarkup : this.popoutTranslateEntryMarkup); + wrapper.appendChild(popoutTranslateEntry); + popoutTranslateEntry.addEventListener("click", () => { + this.translateMessage(instance.props.message, instance._reactInternalFiber.memoizedProps.target, instance.props.channel); + instance.props.onClose(); + }); + } + } + + getMessageAndPos (target) { + let messagediv = BDFDB.getParentEle(BDFDB.dotCN.message, target); + let pos = messagediv ? Array.from(messagediv.parentElement.querySelectorAll(BDFDB.dotCN.message)).indexOf(messagediv) : -1; + return {messagediv, pos}; + } + + translateMessage (message, target, channel) { + if (!message || !target) return; + let {messagediv, pos} = this.getMessageAndPos(target); + if (!messagediv || pos == -1) return; + channel = channel ? channel : this.ChannelUtils.getChannel(message.channel_id); + if (!messagediv.querySelector(BDFDB.dotCN.messageedited + ".translated")) { + var markup = messagediv.querySelector(BDFDB.dotCN.messagemarkup); + var fakemarkup = markup.cloneNode(true); + var oldhtml = markup.innerHTML; + let compactheader = fakemarkup.querySelector(BDFDB.dotCN.messageheadercompact); + if (compactheader) compactheader.remove(); + this.translateText(fakemarkup.innerHTML, "context", (translation, input, output) => { + if (translation) { + markup.GoogleTranslateOriginalHTML = oldhtml; + markup.innerHTML = (compactheader ? "" : "") + translation.replace(/\n/g, "DevilBroBDFDBPlacerHolderN").replace(/\s/g, " ").replace(/DevilBroBDFDBPlacerHolderN/g, "\n").replace(/ *([<>]) */g, "$1"); + let translatestamp = BDFDB.htmlToElement(``); + translatestamp.addEventListener("mouseenter", () => { + BDFDB.createTooltip(`
From: ${input.name}
To: ${output.name}
`, translatestamp, {html:true, type:"top", selector:"translation-tooltip"}); + }); + markup.appendChild(translatestamp); + BDFDB.addClass(messagediv, "translated"); + if (compactheader) markup.insertBefore(compactheader, markup.firstElementChild); + } + }); + } + else this.resetMessage(messagediv); + } + + resetMessage (messagediv) { + BDFDB.removeEles(messagediv.querySelector(BDFDB.dotCN.messageedited + ".translated")); + BDFDB.removeClass(messagediv, "translated"); + let markup = messagediv.querySelector(BDFDB.dotCN.messagemarkup); + markup.innerHTML = markup.GoogleTranslateOriginalHTML; + delete markup.GoogleTranslateOriginalHTML; } translateText (text, type, callback) { - var finishTranslation = (translation, mentions, input, output, toast) => { - if (translation) translation = this.addMentions(translation, mentions); + var finishTranslation = (translation, exceptions, input, output, toast) => { + if (translation) translation = this.addExceptions(translation, exceptions); clearInterval(toast.interval); toast.close(); callback(translation, input, output); }; - var [newtext, mentions, translate] = this.removeMentions(text.trim()); + var [newtext, exceptions, translate] = this.removeExceptions(text.trim(), type); var input = Object.assign({}, this.languages[this.getLanguageChoice("input", type)]); var output = Object.assign({}, this.languages[this.getLanguageChoice("output", type)]); var translation = ""; @@ -762,7 +658,7 @@ module.exports = (Plugin, Api, Vendor) => { if (input.id == "binary" && output.id != "binary") translation = this.binary2string(newtext); else if (input.id != "binary" && output.id == "binary") translation = this.string2binary(newtext); else if (input.id == "binary" && output.id == "binary") translation = newtext; - finishTranslation(translation, mentions, input, output, toast); + finishTranslation(translation, exceptions, input, output, toast); } else { if (BDFDB.getData("useGoogle", this, "translators")) { @@ -771,7 +667,7 @@ module.exports = (Plugin, Api, Vendor) => { result = JSON.parse(result); result[0].forEach((array) => {translation += array[0];}); if (this.languages[result[2]]) input.name = this.languages[result[2]].name; - finishTranslation(translation, mentions, input, output, toast); + finishTranslation(translation, exceptions, input, output, toast); } }); } @@ -780,121 +676,146 @@ module.exports = (Plugin, Api, Vendor) => { this.DeepLTranslate.setOutputLanguage(output.id); this.DeepLTranslate.translate(newtext).then((translation) => { if (newtext.lastIndexOf(".") != newtext.length-1 && translation.lastIndexOf(".") == translation.length-1) translation = translation.slice(0,-1); - finishTranslation(translation, mentions, input, output, toast); + finishTranslation(translation, exceptions, input, output, toast); }); - } } } else { translation = text; - finishTranslation(translation, mentions, input, output, toast); + finishTranslation(translation, exceptions, input, output, toast); } } - addMentions (string, mentions) { - for (let i in mentions) { - string = string.replace("a" + i + "_______", mentions[i].indexOf("!") == 0 ? mentions[i].slice(1) : mentions[i]); - } + addExceptions (string, exceptions) { + for (let i in exceptions) string = string.replace("a" + i + "_______", exceptions[i].indexOf("!") == 0 ? exceptions[i].slice(1) : exceptions[i]); return string; } - removeMentions (string) { - var mentions = {}, newString = [], count = 0; - string.split(" ").forEach((word) => { - if (word.indexOf("<@!") == 0 || word.indexOf(":") == 0 || word.indexOf("@") == 0 || word.indexOf("#") == 0 || (word.indexOf("!") == 0 && word.length > 1)) { - newString.push("a" + count + "_______"); - mentions[count] = word; - count++; + removeExceptions (string, type) { + var exceptions = {}, newString = [], count = 0; + if (type == "context") { + let text = [], i = 0; + string.split("").forEach(chara => { + if (chara == "<" && text[i]) i++; + text[i] = text[i] ? text[i] + chara : chara; + if (chara == ">") i++; + }); + for (let j in text) { + if (text[j].indexOf("<") == 0) { + newString.push("a" + count + "_______"); + exceptions[count] = text[j]; + count++; + } + else newString.push(text[j]); } - else { - newString.push(word); - } - }); - return [newString.join(" "), mentions, newString.length-count != 0]; + } + else { + string.split(" ").forEach(word => { + if (word.indexOf("<@!") == 0 || word.indexOf(":") == 0 || word.indexOf("@") == 0 || word.indexOf("#") == 0 || (word.indexOf("!") == 0 && word.length > 1)) { + newString.push("a" + count + "_______"); + exceptions[count] = word; + count++; + } + else newString.push(word); + }); + } + return [newString.join(" "), exceptions, newString.length-count != 0]; } openTranslatePopout (button) { - if (button.classList.contains(BDFDB.disCN.optionpopoutopen)) return; - button.classList.add(BDFDB.disCN.optionpopoutopen); - var popout = $(this.translatePopoutMarkup); - popout - .appendTo(BDFDB.dotCN.popouts) - .css("left", $(button).offset().left + $(button).outerWidth() + "px") - .css("top", $(button).offset().top - $(button).outerHeight()/2 + "px") - .on("click", BDFDB.dotCN.selectcontrol, (e) => {this.openDropdownMenu("inChat", e);}) - .on("click", ".reverse-button", (e) => { - var place = e.currentTarget.getAttribute("type").replace("output",""); - var input = this.getLanguageChoice("output", place); - var output = this.getLanguageChoice("input", place); - output = output == "auto" ? "en" : output; - popout.find(BDFDB.dotCN.select + "[type='input" + place + "']").attr("value", input).find(BDFDB.dotCN.title).text(this.languages[input].name); - popout.find(BDFDB.dotCN.select + "[type='output" + place + "']").attr("value", output).find(BDFDB.dotCN.title).text(this.languages[output].name); - BDFDB.saveData("input" + place, input, this, "choices"); - BDFDB.saveData("output" + place, output, this, "choices"); - }); + let container = document.querySelector(BDFDB.dotCN.popouts); + if (!container || BDFDB.containsClass(button, "popout-open")) return; + BDFDB.addClass(button, "popout-open"); + let translatepopout = BDFDB.htmlToElement(this.translatePopoutMarkup); + container.appendChild(translatepopout); + let buttonrects = BDFDB.getRects(button); + translatepopout.style.setProperty("left", buttonrects.left + buttonrects.width + "px"); + translatepopout.style.setProperty("top", buttonrects.top - buttonrects.height/2 + "px") - popout.find(BDFDB.dotCN.select).each((_,selectWrap) => { + BDFDB.addChildEventListener(translatepopout, "click", BDFDB.dotCN.selectcontrol, e => {this.openDropdownMenu("inChat", e);}); + BDFDB.addChildEventListener(translatepopout, "click", ".reverse-button", e => { + let place = e.currentTarget.getAttribute("type").replace("output",""); + let input = this.getLanguageChoice("output", place); + let output = this.getLanguageChoice("input", place); + output = output == "auto" ? "en" : output; + let inputselect = translatepopout.querySelector(BDFDB.dotCN.select + "[type='input" + place + "']"); + let outputselect = translatepopout.querySelector(BDFDB.dotCN.select + "[type='output" + place + "']"); + inputselect.setAttribute("value", input); + inputselect.querySelector(BDFDB.dotCN.title).innerText = this.languages[input].name; + outputselect.setAttribute("value", output); + outputselect.querySelector(BDFDB.dotCN.title).innerText = this.languages[output].name; + BDFDB.saveData("input" + place, input, this, "choices"); + BDFDB.saveData("output" + place, output, this, "choices"); + }); + + translatepopout.querySelectorAll(BDFDB.dotCN.select).forEach(selectWrap => { let language = this.getLanguageChoice(selectWrap.getAttribute("type")); selectWrap.setAttribute("value", language); selectWrap.querySelector(BDFDB.dotCN.title).innerText = this.languages[language].name; }); - var checkbox = popout[0].querySelector("#translating-checkbox"); - checkbox.checked = this.translating; - $(checkbox).on("click." + this.name, () => { - button.classList.toggle("active", checkbox.checked); - this.translating = checkbox.checked; + var translatecheckbox = translatepopout.querySelector("#translating-checkbox"); + translatecheckbox.checked = this.translating; + translatecheckbox.addEventListener("click", () => { + BDFDB.toggleClass(button, BDFDB.disCN.textareabuttonactive, translatecheckbox.checked); + this.translating = translatecheckbox.checked; }); var translators = BDFDB.getAllData(this, "translators"); - popout[0].querySelectorAll(BDFDB.dotCN.switchinner + "[option=translators]").forEach((checkbox) => { - checkbox.checked = translators[checkbox.value]; - $(checkbox).on("click." + this.name, () => { - this.updateSettings(popout[0]); - popout.remove(); - button.classList.remove(BDFDB.disCN.optionpopoutopen); - this.openTranslatePopout(button); + translatepopout.querySelectorAll(".translators-switch").forEach(translatorcheckbox => { + translatorcheckbox.checked = translators[translatorcheckbox.value.split(" ")[1]]; + translatorcheckbox.addEventListener("click", () => { + document.removeEventListener("mousedown", removePopout); + translatepopout.remove(); + BDFDB.removeClass(button, "popout-open"); + setImmediate(() => {this.openTranslatePopout(button);}); }); }); - $(document).on("mousedown.translatepopout" + this.name, (e) => { - if (popout.has(e.target).length == 0) { - $(document).off("mousedown.translatepopout" + this.name); - popout.remove(); - setTimeout(() => {button.classList.remove(BDFDB.disCN.optionpopoutopen);},300); + var removePopout = e => { + if (!translatepopout.contains(e.target)) { + document.removeEventListener("mousedown", removePopout); + translatepopout.remove(); + setTimeout(() => {BDFDB.removeClass(button, "popout-open");},300); } - }); + }; + document.addEventListener("mousedown", removePopout); - BDFDB.initElements(popout[0], this); + BDFDB.initElements(translatepopout, this); } openDropdownMenu (selector, e) { - var selectControl = e.currentTarget; - var selectWrap = selectControl.parentElement; + let selectControl = e.currentTarget; + let selectWrap = selectControl.parentElement; + let plugincard = selector == "inSettings" ? BDFDB.getParentEle("li", selectWrap) : document.createElement("div"); - if (selectWrap.classList.contains(BDFDB.disCN.selectisopen)) return; + if (!plugincard || BDFDB.containsClass(selectWrap, BDFDB.disCN.selectisopen)) return; - selectWrap.classList.add(BDFDB.disCN.selectisopen); - $("li").has(selectWrap).css("overflow", "visible"); + BDFDB.addClass(selectWrap, BDFDB.disCN.selectisopen); + plugincard.style.setProperty("overflow", "visible", "important"); var type = selectWrap.getAttribute("type"); var selectMenu = this.createDropdownMenu(selectWrap.getAttribute("value"), type); + BDFDB.addClass(selectMenu, selector); selectWrap.appendChild(selectMenu); - $(selectMenu).addClass(selector).on("mousedown." + this.name, BDFDB.dotCN.selectoption, (e2) => { + BDFDB.addChildEventListener(selectMenu, "mousedown", BDFDB.dotCN.selectoption, e2 => { var language = e2.currentTarget.getAttribute("value"); selectWrap.setAttribute("value", language); selectControl.querySelector(BDFDB.dotCN.title).innerText = this.languages[language].name; BDFDB.saveData(type, language, this, "choices"); }); - $(document).on("mousedown.select" + this.name, (e2) => { - if (e2.target.parentElement == selectMenu) return; - $(document).off("mousedown.select" + this.name); - selectMenu.remove(); - $("li").has(selectWrap).css("overflow", "auto"); - setTimeout(() => {selectWrap.classList.remove(BDFDB.disCN.selectisopen);},100); - }); + + var removeMenu = e2 => { + if (e2.target.parentElement != selectMenu) { + document.removeEventListener("mousedown", removeMenu); + selectMenu.remove(); + plugincard.style.removeProperty("overflow"); + setTimeout(() => {BDFDB.removeClass(selectWrap, BDFDB.disCN.selectisopen);},100); + } + }; + document.addEventListener("mousedown", removeMenu); } createDropdownMenu (choice, type) { @@ -905,7 +826,7 @@ module.exports = (Plugin, Api, Vendor) => { menuhtml += `
${this.languages[key].name}
` } menuhtml += `
`; - return $(menuhtml)[0]; + return BDFDB.htmlToElement(menuhtml); } string2binary (string) { @@ -945,178 +866,230 @@ module.exports = (Plugin, Api, Vendor) => { } getSettingsPanel () { + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var choices = BDFDB.getAllData(this, "choices"); var settings = BDFDB.getAllData(this, "settings"); var translators = BDFDB.getAllData(this, "translators"); - var settingshtml = `
`; + var settingshtml = `
${this.name}
`; for (let key in choices) { let choice = this.getLanguageChoice(key); settingshtml += `

${this.defaults.choices[key].description}

${this.languages[choice].name}
` } for (let key in settings) { - settingshtml += `

${this.defaults.settings[key].description}

`; + settingshtml += `

${this.defaults.settings[key].description}

`; } for (let key in translators) { - settingshtml += `

Translator:

${this.defaults.translators[key].choice1}

${this.defaults.translators[key].choice2}

`; + settingshtml += `

Translator:

${this.defaults.translators[key].choice1}

${this.defaults.translators[key].choice2}

`; } - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.selectcontrol, (e) => {this.openDropdownMenu("inSettings", e);}) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); + BDFDB.initElements(settingspanel, this); + + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.selectcontrol, e => {this.openDropdownMenu("inSettings", e);}); return settingspanel; } + onSettingsClosed () { + if (this.SettingsUpdated) { + delete this.SettingsUpdated; + this.setLanguage(); + BDFDB.removeEles(".translate-button-wrapper"); + BDFDB.WebModules.forceAllUpdates(this, "ChannelTextArea"); + } + } + setLabelsByLanguage () { switch (BDFDB.getDiscordLanguage().id) { case "hr": //croatian return { context_messagetranslateoption_text: "Prijevod poruke", + context_messageuntranslateoption_text: "Prijenos poruke", context_googletranslateoption_text: "Traži prijevod", - popout_translateoption_text: "Prevedi", + popout_translateoption_text: "Prevesti", + popout_untranslateoption_text: "Prevesti natrag", translated_watermark_text: "preveo" }; case "da": //danish return { context_messagetranslateoption_text: "Oversæt Besked", + context_messageuntranslateoption_text: "Oversæt Besked tilbage", context_googletranslateoption_text: "Søg oversættelse", popout_translateoption_text: "Oversætte", + popout_untranslateoption_text: "Oversæt tilbage", translated_watermark_text: "oversat" }; case "de": //german return { context_messagetranslateoption_text: "Nachricht übersetzen", + context_messageuntranslateoption_text: "Nachricht unübersetzen", context_googletranslateoption_text: "Suche Übersetzung", popout_translateoption_text: "Übersetzen", + popout_untranslateoption_text: "Unübersetzen", translated_watermark_text: "übersetzt" }; case "es": //spanish return { context_messagetranslateoption_text: "Traducir mensaje", + context_messageuntranslateoption_text: "Traducir mensaje de vuelta", context_googletranslateoption_text: "Buscar traducción", popout_translateoption_text: "Traducir", + popout_untranslateoption_text: "Traducir de vuelta", translated_watermark_text: "traducido" }; case "fr": //french return { context_messagetranslateoption_text: "Traduire le message", + context_messageuntranslateoption_text: "Traduire le message en retour", context_googletranslateoption_text: "Rechercher une traduction", popout_translateoption_text: "Traduire", + popout_untranslateoption_text: "Traduire en arrière", translated_watermark_text: "traduit" }; case "it": //italian return { - context_messagetranslateoption_text: "Traduci messaggio", + context_messagetranslateoption_text: "Tradurre il messaggio", + context_messageuntranslateoption_text: "Tradurre il messaggio indietro", context_googletranslateoption_text: "Cerca la traduzione", - popout_translateoption_text: "Tradurre", + popout_translateoption_text: "Traduci", + popout_untranslateoption_text: "Traduci indietro", translated_watermark_text: "tradotto" }; case "nl": //dutch return { context_messagetranslateoption_text: "Vertaal bericht", + context_messageuntranslateoption_text: "Vertaal bericht terug", context_googletranslateoption_text: "Zoek vertaling", - popout_translateoption_text: "Vertalen", + popout_translateoption_text: "Vertaal", + popout_untranslateoption_text: "Vertaal terug", translated_watermark_text: "vertaalde" }; case "no": //norwegian return { context_messagetranslateoption_text: "Oversett melding", + context_messageuntranslateoption_text: "Oversett melding tilbake", context_googletranslateoption_text: "Søk oversettelse", - popout_translateoption_text: "Oversette", + popout_translateoption_text: "Oversett", + popout_untranslateoption_text: "Oversett tilbake", translated_watermark_text: "oversatt" }; case "pl": //polish return { context_messagetranslateoption_text: "Przetłumacz wiadomość", + context_messageuntranslateoption_text: "Przetłumacz wiadomość z powrotem", context_googletranslateoption_text: "Wyszukaj tłumaczenie", - popout_translateoption_text: "Tłumaczyć", + popout_translateoption_text: "Przetłumacz", + popout_untranslateoption_text: "Przetłumacz ponownie", translated_watermark_text: "przetłumaczony" }; case "pt-BR": //portuguese (brazil) return { context_messagetranslateoption_text: "Traduzir mensagem", + context_messageuntranslateoption_text: "Traduzir mensagem de volta", context_googletranslateoption_text: "Pesquisar tradução", popout_translateoption_text: "Traduzir", + popout_untranslateoption_text: "Traduzir de volta", translated_watermark_text: "traduzido" }; case "fi": //finnish return { context_messagetranslateoption_text: "Käännä viesti", + context_messageuntranslateoption_text: "Käännä viesti takaisin", context_googletranslateoption_text: "Etsi käännös", popout_translateoption_text: "Kääntää", + popout_untranslateoption_text: "Käännä takaisin", translated_watermark_text: "käännetty" }; case "sv": //swedish return { context_messagetranslateoption_text: "Översätt meddelande", + context_messageuntranslateoption_text: "Översätt meddelandet tillbaka", context_googletranslateoption_text: "Sök översättning", popout_translateoption_text: "Översätt", + popout_untranslateoption_text: "Översätt tillbaka", translated_watermark_text: "översatt" }; case "tr": //turkish return { context_messagetranslateoption_text: "Mesajı çevir", + context_messageuntranslateoption_text: "İletiyi geri çevir", context_googletranslateoption_text: "Arama tercümesi", popout_translateoption_text: "Çevirmek", + popout_untranslateoption_text: "Geri çevir", translated_watermark_text: "tercüme" }; case "cs": //czech return { - context_messagetranslateoption_text: "Přeložit zprávu", + context_messagetranslateoption_text: "Přeposlat zprávu", + context_messageuntranslateoption_text: "Přeposlat zprávu zpátky", context_googletranslateoption_text: "Hledat překlad", - popout_translateoption_text: "Přeložit", + popout_translateoption_text: "Přeposlat", + popout_untranslateoption_text: "Přeposlat zpět", translated_watermark_text: "přeloženo" }; case "bg": //bulgarian return { - context_messagetranslateoption_text: "Превод на съобщението", + context_messagetranslateoption_text: "Преведете на съобщението", + context_messageuntranslateoption_text: "Преведете съобщението обратно", context_googletranslateoption_text: "Търсене на превод", - popout_translateoption_text: "Превеждам", + popout_translateoption_text: "Превод", + popout_untranslateoption_text: "Превод обратно", translated_watermark_text: "преведена" }; case "ru": //russian return { context_messagetranslateoption_text: "Перевести сообщение", + context_messageuntranslateoption_text: "Перевести сообщение обратно", context_googletranslateoption_text: "Поиск перевода", - popout_translateoption_text: "Переведите", + popout_translateoption_text: "Перевести", + popout_untranslateoption_text: "Перевести обратно", translated_watermark_text: "переведенный" }; case "uk": //ukrainian return { context_messagetranslateoption_text: "Перекласти повідомлення", + context_messageuntranslateoption_text: "Перекласти повідомлення назад", context_googletranslateoption_text: "Пошук перекладу", popout_translateoption_text: "Перекласти", + popout_untranslateoption_text: "Перекласти назад", translated_watermark_text: "перекладений" }; case "ja": //japanese return { context_messagetranslateoption_text: "メッセージを翻訳する", + context_messageuntranslateoption_text: "メッセージを翻訳する", context_googletranslateoption_text: "翻訳の検索", popout_translateoption_text: "翻訳", + popout_untranslateoption_text: "翻訳する", translated_watermark_text: "翻訳された" }; case "zh-TW": //chinese (traditional) return { context_messagetranslateoption_text: "翻譯消息", + context_messageuntranslateoption_text: "翻譯消息", context_googletranslateoption_text: "搜索翻譯", popout_translateoption_text: "翻譯", + popout_untranslateoption_text: "翻譯回來", translated_watermark_text: "翻譯" }; case "ko": //korean return { context_messagetranslateoption_text: "메시지 번역", + context_messageuntranslateoption_text: "메시지 번역 뒤로", context_googletranslateoption_text: "검색 번역", - popout_translateoption_text: "옮기다", + popout_translateoption_text: "다시", + popout_untranslateoption_text: "다시 번역", translated_watermark_text: "번역 된" }; default: //default: english return { context_messagetranslateoption_text: "Translate Message", + context_messageuntranslateoption_text: "Untranslate Message", context_googletranslateoption_text: "Search translation", popout_translateoption_text: "Translate", + popout_untranslateoption_text: "Untranslate", translated_watermark_text: "translated" }; } diff --git a/PluginsV2/ImageGallery/index.js b/PluginsV2/ImageGallery/index.js index 63fe9ce03f..e3006a66e3 100644 --- a/PluginsV2/ImageGallery/index.js +++ b/PluginsV2/ImageGallery/index.js @@ -3,6 +3,9 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { + this.patchModules = { + "ImageModal":["componentDidMount","componentWillUnmount"] + } this.eventFired = false; this.imageMarkup = `
`; @@ -42,31 +45,10 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - var observer = null; - - observer = new MutationObserver((changes, _) => { - changes.forEach( - (change, i) => { - if (change.addedNodes) { - change.addedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.imagewrapper) && node.querySelector(BDFDB.dotCN.downloadlink)) { - this.loadImages(node); - } - }); - } - if (change.removedNodes) { - change.removedNodes.forEach((node) => { - if (node && node.tagName && node.querySelector(BDFDB.dotCN.imagewrapper) && node.querySelector(BDFDB.dotCN.downloadlink)) { - $(document).off("keyup." + this.name).off("keydown." + this.name); - } - }); - } - } - ); - }); - BDFDB.addObserver(this, BDFDB.dotCN.app + " ~ [class^='theme-']:not([class*='popouts'])", {name:"imageModalObserver",instance:observer}, {childList: true}); + BDFDB.WebModules.forceAllUpdates(this); return true; } @@ -78,6 +60,15 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + this.closemodal = true; + + BDFDB.WebModules.forceAllUpdates(this, "ImageModal"); + + delete this.closemodal; + + document.removeEventListener("keydown", document.keydownImageGalleryListener); + document.removeEventListener("keyup", document.keyupImageGalleryListener); + BDFDB.unloadMessage(this); return true; } @@ -89,22 +80,31 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions - loadImages (modal) { - var start = performance.now(); - var waitForImg = setInterval(() => { - var img = modal.querySelector(BDFDB.dotCNS.imagewrapper + "img"); - if (img && img.src) { - clearInterval(waitForImg); - var message = this.getMessageGroupOfImage(img); - if (message) { - modal.classList.add("image-gallery"); - this.addImages(modal, message.querySelectorAll(BDFDB.dotCNS.imagewrapper + "img"), img); + processImageModal (instance, wrapper, methodnames) { + if (this.closemodal && instance.props && instance.props.onClose) instance.props.onClose(); + else if (methodnames.includes("componentDidMount")) { + let modal = BDFDB.getParentEle(BDFDB.dotCN.modal, wrapper); + if (!modal) return; + let start = performance.now(); + let waitForImg = setInterval(() => { + let img = modal.querySelector(BDFDB.dotCNS.imagewrapper + "img"); + if (img && img.src) { + clearInterval(waitForImg); + let message = this.getMessageGroupOfImage(img); + if (message) { + BDFDB.addClass(modal, "image-gallery"); + this.addImages(modal, message.querySelectorAll(BDFDB.dotCNS.imagewrapper + "img"), img); + } } - } - else if (performance.now() - start > 10000) { - clearInterval(waitForImg); - } - }, 100); + else if (performance.now() - start > 10000) { + clearInterval(waitForImg); + } + }, 100); + } + else if (methodnames.includes("componentWillUnmount")) { + document.removeEventListener("keydown", document.keydownImageGalleryListener); + document.removeEventListener("keyup", document.keyupImageGalleryListener); + } } getMessageGroupOfImage (thisimg) { @@ -121,12 +121,15 @@ module.exports = (Plugin, Api, Vendor) => { } getSrcOfImage (img) { - var src = img.src ? img.src : (img.querySelector("canvas") ? img.querySelector("canvas").src : ""); - return src.split("?width=")[0]; + return (img.src || (img.querySelector("canvas") ? img.querySelector("canvas").src : "")).split("?width=")[0]; } addImages (modal, imgs, img) { - modal.querySelectorAll(`${BDFDB.dotCN.imagewrapper}.prev, ${BDFDB.dotCN.imagewrapper}.next`).forEach(ele => {ele.remove();}); + BDFDB.removeEles(modal.querySelector(`${BDFDB.dotCN.imagewrapper}.prev, ${BDFDB.dotCN.imagewrapper}.next`)); + + let inner = modal.querySelector(BDFDB.dotCN.modalinner); + + if (!inner) return; var prevImg, nextImg, index; for (index = 0; index < imgs.length; index++) { @@ -138,46 +141,39 @@ module.exports = (Plugin, Api, Vendor) => { } } - $(modal).find(BDFDB.dotCN.imagewrapper) - .addClass("current") - .find("img").attr("src", this.getSrcOfImage(img)); + var imagesrc = this.getSrcOfImage(img); + modal.querySelector(BDFDB.dotCN.downloadlink).setAttribute("href", imagesrc); - $(modal.querySelector(BDFDB.dotCN.downloadlink)) - .attr("href", this.getSrcOfImage(img)); + var imagewrapper = modal.querySelector(BDFDB.dotCN.imagewrapper); + BDFDB.addClass(imagewrapper, "current"); + var imagewrapperimage = imagewrapper.querySelector("img"); + imagewrapperimage.setAttribute("src", imagesrc); - this.resizeImage(modal, img, modal.querySelector(BDFDB.dotCN.imagewrapper + ".current img")); - if (prevImg) { - $(this.imageMarkup) - .appendTo(modal.querySelector(BDFDB.dotCN.modalinner)) - .addClass("prev") - .off("click." + this.name).on("click." + this.name, () => { - this.addImages(modal, imgs, prevImg); - }) - .find("img").attr("src", this.getSrcOfImage(prevImg)); - this.resizeImage(modal, prevImg, modal.querySelector(BDFDB.dotCN.imagewrapper + ".prev img")); - } - if (nextImg) { - $(this.imageMarkup) - .appendTo(modal.querySelector(BDFDB.dotCN.modalinner)) - .addClass("next") - .off("click." + this.name).on("click." + this.name, () => { - this.addImages(modal, imgs, nextImg); - }) - .find("img").attr("src", this.getSrcOfImage(nextImg)); - this.resizeImage(modal, nextImg, modal.querySelector(BDFDB.dotCN.imagewrapper + ".next img")); - } + this.resizeImage(modal, img, imagewrapperimage); - $(document).off("keydown." + this.name).off("keyup." + this.name) - .on("keydown." + this.name, (e) => { - this.keyPressed({modal, imgs, prevImg, nextImg}, e); - }) - .on("keyup." + this.name, () => { - this.eventFired = false; - }); + if (prevImg) inner.appendChild(this.createImage(modal, imgs, prevImg, "prev")); + if (nextImg) inner.appendChild(this.createImage(modal, imgs, nextImg, "next")); + + document.removeEventListener("keydown", document.keydownImageGalleryListener); + document.removeEventListener("keyup", document.keyupImageGalleryListener); + document.keydownImageGalleryListener = e => {this.keyPressed({modal, imgs, prevImg, nextImg}, e);}; + document.keyupImageGalleryListener = e => {this.eventFired = false;}; + document.addEventListener("keydown", document.keydownImageGalleryListener); + document.addEventListener("keyup", document.keyupImageGalleryListener); + } + + createImage (modal, imgs, img, type) { + var imagewrapper = BDFDB.htmlToElement(this.imageMarkup); + BDFDB.addClass(imagewrapper, type); + imagewrapper.addEventListener("click", () => {this.addImages(modal, imgs, img);}); + var imagewrapperimage = imagewrapper.querySelector("img"); + imagewrapperimage.setAttribute("src", this.getSrcOfImage(img)); + this.resizeImage(modal, img, imagewrapperimage); + return imagewrapper; } resizeImage (container, src, img) { - $(img).hide(); + BDFDB.toggleEles(img, false); var temp = new Image(); temp.src = src.src.split("?width=")[0]; temp.onload = function () { @@ -190,29 +186,22 @@ module.exports = (Plugin, Api, Vendor) => { newHeight = temp.height > newHeight ? newHeight : temp.height; var wrapper = img.parentElement; + if (!BDFDB.containsClass(wrapper, "current")) wrapper.style.setProperty("top", (container.clientHeight - newHeight) / 2 + "px"); + wrapper.style.setProperty("width", newWidth + "px"); + wrapper.style.setProperty("height", newHeight + "px"); + img.style.setProperty("width", newWidth + "px"); + img.style.setProperty("height", newHeight + "px"); - $(wrapper) - .css("top", !wrapper.classList.contains("current") ? (container.clientHeight - newHeight) / 2 : "") - .css("width", newWidth) - .css("height", newHeight); - - $(img) - .css("width", newWidth) - .css("height", newHeight) - .show(); + BDFDB.toggleEles(img, true); }; } - keyPressed (data, e) { + keyPressed ({modal, imgs, prevImg, nextImg}, e) { if (!this.eventFired) { this.eventFired = true; - if (e.keyCode == 37 && data.prevImg) { - this.addImages(data.modal, data.imgs, data.prevImg); - } - else if (e.keyCode == 39 && data.nextImg) { - this.addImages(data.modal, data.imgs, data.nextImg); - } + if (e.keyCode == 37 && prevImg) this.addImages(modal, imgs, prevImg); + else if (e.keyCode == 39 && nextImg) this.addImages(modal, imgs, nextImg); } } } diff --git a/PluginsV2/MessageUtilities/index.js b/PluginsV2/MessageUtilities/index.js index 75048da10f..c87711f0aa 100644 --- a/PluginsV2/MessageUtilities/index.js +++ b/PluginsV2/MessageUtilities/index.js @@ -7,7 +7,7 @@ module.exports = (Plugin, Api, Vendor) => { this.firedEvents = []; - this.clickMap = ["SINGLE" /*[0]*/, "DOUBLE" /*[1]*/]; + this.clickMap = ["CLICK" /*[0]*/, "DBLCLICK" /*[1]*/]; this.keyboardMap = [ "NONE" /*[0]*/, "" /*[1]*/, "" /*[2]*/, "CANCEL" /*[3]*/, "" /*[4]*/, "" /*[5]*/, "HELP" /*[6]*/, "" /*[7]*/, "BACK_SPACE" /*[8]*/, "TAB" /*[9]*/, "" /*[10]*/, "" /*[11]*/, "CLEAR" /*[12]*/, "ENTER" /*[13]*/, "ENTER_SPECIAL" /*[14]*/, "" /*[15]*/, "SHIFT" /*[16]*/, "CONTROL" /*[17]*/, "ALT" /*[18]*/, "PAUSE" /*[19]*/, "CAPS_LOCK" /*[20]*/, "KANA" /*[21]*/, "EISU" /*[22]*/, "JUNJA" /*[23]*/, "FINAL" /*[24]*/, "HANJA" /*[25]*/, "" /*[26]*/, "ESCAPE" /*[27]*/, "CONVERT" /*[28]*/, "NONCONVERT" /*[29]*/, "ACCEPT" /*[30]*/, "MODECHANGE" /*[31]*/, "SPACE" /*[32]*/, "PAGE_UP" /*[33]*/, "PAGE_DOWN" /*[34]*/, "END" /*[35]*/, "HOME" /*[36]*/, "LEFT" /*[37]*/, "UP" /*[38]*/, "RIGHT" /*[39]*/, "DOWN" /*[40]*/, "SELECT" /*[41]*/, "PRINT" /*[42]*/, "EXECUTE" /*[43]*/, "PRINTSCREEN" /*[44]*/, "INSERT" /*[45]*/, "DELETE" /*[46]*/, "" /*[47]*/,"0" /*[48]*/, "1" /*[49]*/, "2" /*[50]*/, "3" /*[51]*/, "4" /*[52]*/, "5" /*[53]*/, "6" /*[54]*/, "7" /*[55]*/, "8" /*[56]*/, "9" /*[57]*/, "COLON" /*[58]*/, "SEMICOLON" /*[59]*/, "LESS_THAN" /*[60]*/, "EQUALS" /*[61]*/, "GREATER_THAN" /*[62]*/, "QUESTION_MARK" /*[63]*/, "AT" /*[64]*/, "A" /*[65]*/, "B" /*[66]*/, "C" /*[67]*/, "D" /*[68]*/, "E" /*[69]*/, "F" /*[70]*/, "G" /*[71]*/, "H" /*[72]*/, "I" /*[73]*/, "J" /*[74]*/, "K" /*[75]*/, "L" /*[76]*/, "M" /*[77]*/, "N" /*[78]*/, "O" /*[79]*/, "P" /*[80]*/, "Q" /*[81]*/, "R" /*[82]*/, "S" /*[83]*/, "T" /*[84]*/, "U" /*[85]*/, "V" /*[86]*/, "W" /*[87]*/, "X" /*[88]*/, "Y" /*[89]*/, "Z" /*[90]*/, "OS_KEY" /*[91]*/, "" /*[92]*/, "CONTEXT_MENU" /*[93]*/, "" /*[94]*/, "SLEEP" /*[95]*/, "NUMPAD0" /*[96]*/, "NUMPAD1" /*[97]*/, "NUMPAD2" /*[98]*/, "NUMPAD3" /*[99]*/, "NUMPAD4" /*[100]*/, "NUMPAD5" /*[101]*/, "NUMPAD6" /*[102]*/, "NUMPAD7" /*[103]*/, "NUMPAD8" /*[104]*/, "NUMPAD9" /*[105]*/, "MULTIPLY" /*[106]*/, "ADD" /*[107]*/, "SEPARATOR" /*[108]*/, "SUBTRACT" /*[109]*/, "DECIMAL" /*[110]*/, "DIVIDE" /*[111]*/, "F1" /*[112]*/, "F2" /*[113]*/, "F3" /*[114]*/, "F4" /*[115]*/, "F5" /*[116]*/, "F6" /*[117]*/, "F7" /*[118]*/, "F8" /*[119]*/, "F9" /*[120]*/, "F10" /*[121]*/, "F11" /*[122]*/, "F12" /*[123]*/, "F13" /*[124]*/, "F14" /*[125]*/, "F15" /*[126]*/, "F16" /*[127]*/, "F17" /*[128]*/, "F18" /*[129]*/, "F19" /*[130]*/, "F20" /*[131]*/, "F21" /*[132]*/, "F22" /*[133]*/, "F23" /*[134]*/, "F24" /*[135]*/, "" /*[136]*/, "" /*[137]*/, "" /*[138]*/, "" /*[139]*/, "" /*[140]*/, "" /*[141]*/, "" /*[142]*/, "" /*[143]*/, "NUM_LOCK" /*[144]*/, "SCROLL_LOCK" /*[145]*/, "WIN_OEM_FJ_JISHO" /*[146]*/, "WIN_OEM_FJ_MASSHOU" /*[147]*/, "WIN_OEM_FJ_TOUROKU" /*[148]*/, "WIN_OEM_FJ_LOYA" /*[149]*/, "WIN_OEM_FJ_ROYA" /*[150]*/, "" /*[151]*/, "" /*[152]*/, "" /*[153]*/, "" /*[154]*/, "" /*[155]*/, "" /*[156]*/, "" /*[157]*/, "" /*[158]*/, "" /*[159]*/, "CIRCUMFLEX" /*[160]*/, "EXCLAMATION" /*[161]*/, "DOUBLE_QUOTE" /*[162]*/, "HASH" /*[163]*/, "DOLLAR" /*[164]*/, "PERCENT" /*[165]*/, "AMPERSAND" /*[166]*/, "UNDERSCORE" /*[167]*/, "OPEN_PAREN" /*[168]*/, "CLOSE_PAREN" /*[169]*/, "ASTERISK" /*[170]*/, "PLUS" /*[171]*/, "PIPE" /*[172]*/, "HYPHEN_MINUS" /*[173]*/, "OPEN_CURLY_BRACKET" /*[174]*/, "CLOSE_CURLY_BRACKET" /*[175]*/, "TILDE" /*[176]*/, "" /*[177]*/, "" /*[178]*/, "" /*[179]*/, "" /*[180]*/, "VOLUME_MUTE" /*[181]*/, "VOLUME_DOWN" /*[182]*/, "VOLUME_UP" /*[183]*/, "" /*[184]*/, "" /*[185]*/, "SEMICOLON" /*[186]*/, "EQUALS" /*[187]*/, "COMMA" /*[188]*/, "MINUS" /*[189]*/, "PERIOD" /*[190]*/, "SLASH" /*[191]*/, "BACK_QUOTE" /*[192]*/, "" /*[193]*/, "" /*[194]*/, "" /*[195]*/, "" /*[196]*/, "" /*[197]*/, "" /*[198]*/, "" /*[199]*/, "" /*[200]*/, "" /*[201]*/, "" /*[202]*/, "" /*[203]*/, "" /*[204]*/, "" /*[205]*/, "" /*[206]*/, "" /*[207]*/, "" /*[208]*/, "" /*[209]*/, "" /*[210]*/, "" /*[211]*/, "" /*[212]*/, "" /*[213]*/, "" /*[214]*/, "" /*[215]*/, "" /*[216]*/, "" /*[217]*/, "" /*[218]*/, "OPEN_BRACKET" /*[219]*/, "BACK_SLASH" /*[220]*/, "CLOSE_BRACKET" /*[221]*/, "QUOTE" /*[222]*/, "" /*[223]*/, "META" /*[224]*/, "ALTGR" /*[225]*/, "" /*[226]*/, "WIN_ICO_HELP" /*[227]*/, "WIN_ICO_00" /*[228]*/, "" /*[229]*/, "WIN_ICO_CLEAR" /*[230]*/, "" /*[231]*/,"" /*[232]*/, "WIN_OEM_RESET" /*[233]*/, "WIN_OEM_JUMP" /*[234]*/, "WIN_OEM_PA1" /*[235]*/, "WIN_OEM_PA2" /*[236]*/, "WIN_OEM_PA3" /*[237]*/, "WIN_OEM_WSCTRL" /*[238]*/,"WIN_OEM_CUSEL" /*[239]*/, "WIN_OEM_ATTN" /*[240]*/, "WIN_OEM_FINISH" /*[241]*/, "WIN_OEM_COPY" /*[242]*/, "WIN_OEM_AUTO" /*[243]*/, "WIN_OEM_ENLW" /*[244]*/, "WIN_OEM_BACKTAB" /*[245]*/, "ATTN" /*[246]*/, "CRSEL" /*[247]*/, "EXSEL" /*[248]*/, "EREOF" /*[249]*/, "PLAY" /*[250]*/, "ZOOM" /*[251]*/, "" /*[252]*/, "PA1" /*[253]*/, "WIN_OEM_CLEAR" /*[254]*/, "" /*[255]*/ @@ -32,10 +32,10 @@ module.exports = (Plugin, Api, Vendor) => { "Delete_Message": {name:"Delete Message", func:this.doDelete, value:{click:0, key1:46, key2:0}}, "Pin/Unpin_Message": {name:"Pin/Unpin Message", func:this.doPinUnPin, value:{click:0, key1:17, key2:0}}, "React_to_Message": {name:"React to Message", func:this.doOpenReact, value:{click:0, key1:9, key2:0}}, - "__Note_Message": {name:"Note Message (Pesonal Pins)", func:this.doNote, value:{click:0, key1:16, key2:0}}, - "__Translate_Message": {name:"Translate Message (Google Translate Option)", func:this.doTranslate, value:{click:0, key1:20, key2:0}}, - "__Quote_Message": {name:"Quote Message (Quoter)", func:this.doQuote, value:{click:0, key1:113, key2:0}}, - "__Citate_Message": {name:"Quote Message (Citador)", func:this.doCitate, value:{click:0, key1:114, key2:0}} + "__Note_Message": {name:"Note Message (Pesonal Pins)", func:this.doNote, value:{click:0, key1:16, key2:0}, plugin:"PersonalPins"}, + "__Translate_Message": {name:"Translate Message (Google Translate Option)", func:this.doTranslate, value:{click:0, key1:20, key2:0}, plugin:"GoogleTranslateOption"}, + "__Quote_Message": {name:"Quote Message (Quoter)", func:this.doQuote, value:{click:0, key1:113, key2:0}, plugin:"Quoter"}, + "__Citate_Message": {name:"Quote Message (Citador)", func:this.doCitate, value:{click:0, key1:114, key2:0}, plugin:"Citador"} } }; } @@ -60,24 +60,24 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); - this.ChannelStore = BDFDB.WebModules.findByProperties("getChannel", "getChannels"); + this.ChannelUtils = BDFDB.WebModules.findByProperties("getChannels","getChannel"); this.MessageActions = BDFDB.WebModules.findByProperties("startEditMessage", "endEditMessage"); this.PinActions = BDFDB.WebModules.findByProperties("pinMessage", "unpinMessage"); this.CurrentUserPerms = BDFDB.WebModules.findByProperties("getChannelPermissions", "can"); this.Permissions = BDFDB.WebModules.findByProperties("Permissions", "ActivityTypes").Permissions - $(document) - .on("click." + this.name, BDFDB.dotCN.message, (e) => { - this.onClick(e.currentTarget, 0, "onSglClick"); - }) - .on("dblclick." + this.name, BDFDB.dotCN.message, (e) => { - this.onClick(e.currentTarget, 1, "onDblClick"); - }) - .on("keydown." + this.name, BDFDB.dotCN.textareawrapchat, (e) => { - this.onKeyDown(e.currentTarget, e.which, "onKeyDown"); - }); + BDFDB.addEventListener(this, document, "click", BDFDB.dotCNC.message + BDFDB.dotCN.messagesystem, e => { + this.onClick(e.currentTarget, 0, "onSglClick"); + }) + BDFDB.addEventListener(this, document, "dblclick", BDFDB.dotCNC.message + BDFDB.dotCN.messagesystem, e => { + this.onClick(e.currentTarget, 1, "onDblClick"); + }); + BDFDB.addEventListener(this, document, "keydown", BDFDB.dotCN.textareawrapchat, e => { + this.onKeyDown(e.currentTarget, e.which, "onKeyDown"); + }); return true; } @@ -89,10 +89,6 @@ module.exports = (Plugin, Api, Vendor) => { onStop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - $(document).off("click." + this.name, BDFDB.dotCN.message); - $(document).off("dblclick." + this.name, BDFDB.dotCN.message); - $(document).off("keydown." + this.name, BDFDB.dotCN.textareawrapchat); - BDFDB.unloadMessage(this); return true; } @@ -104,116 +100,117 @@ module.exports = (Plugin, Api, Vendor) => { //begin of own functions - updateSettings (settingspanel) { - var settings = {}; - for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { - settings[input.value] = input.checked; - } - BDFDB.saveAllData(settings, this, "settings"); - } - resetAll (settingspanel) { - if (confirm("Are you sure you want to delete all key bindings?")) { + BDFDB.openConfirmModal(this, "Are you sure you want to delete all key bindings?", () => { BDFDB.removeAllData(this, "bindings"); - var bindings = BDFDB.getAllData(this, "bindings"); + let bindings = BDFDB.getAllData(this, "bindings"); settingspanel.querySelectorAll(BDFDB.dotCN.select).forEach((wrap) => { - var action = wrap.getAttribute("type"); - var option = wrap.getAttribute("option"); + let action = wrap.getAttribute("type"); + let option = wrap.getAttribute("option"); wrap.setAttribute("value", bindings[action][option]); wrap.querySelector(BDFDB.dotCN.title).innerText = this.clickMap[bindings[action][option]]; }); settingspanel.querySelectorAll(BDFDB.dotCN.hotkeycontainer).forEach((wrap) => { - var action = wrap.getAttribute("type"); - var option = wrap.getAttribute("option"); + let action = wrap.getAttribute("type"); + let option = wrap.getAttribute("option"); wrap.setAttribute("value", bindings[action][option]); wrap.querySelector("input").setAttribute("value", this.keyboardMap[bindings[action][option]]); - });; - } + }); + }); } - openDropdownMenu (settingspanel, e) { - var selectControl = e.currentTarget; - var selectWrap = e.currentTarget.parentElement; + openDropdownMenu (e) { + let selectControl = e.currentTarget; + let selectWrap = selectControl.parentElement; + let plugincard = BDFDB.getParentEle("li", selectWrap); - if (selectWrap.classList.contains(BDFDB.disCN.selectisopen)) return; + if (!plugincard || BDFDB.containsClass(selectWrap, BDFDB.disCN.selectisopen)) return; - selectWrap.classList.add(BDFDB.disCN.selectisopen); + BDFDB.addClass(selectWrap, BDFDB.disCN.selectisopen); + plugincard.style.setProperty("overflow", "visible", "important"); - var action = selectWrap.getAttribute("type"); - var option = selectWrap.getAttribute("option"); - var value = selectWrap.getAttribute("value"); + let action = selectWrap.getAttribute("type"); + let option = selectWrap.getAttribute("option"); + let value = selectWrap.getAttribute("value"); - var selectMenu = this.createDropdownMenu(action, value); + let selectMenu = this.createDropdownMenu(action, value); selectWrap.appendChild(selectMenu); - $(selectMenu).on("mousedown." + this.name, BDFDB.dotCN.selectoption, (e2) => { - var binding = BDFDB.getData(action, this, "bindings"); - var selection = e2.currentTarget.getAttribute("value"); + BDFDB.addChildEventListener(selectMenu, "mousedown", BDFDB.dotCN.selectoption, e2 => { + let binding = BDFDB.getData(action, this, "bindings"); + let selection = e2.currentTarget.getAttribute("value"); selectWrap.setAttribute("value", selection); selectControl.querySelector(BDFDB.dotCN.title).innerText = e2.currentTarget.textContent; binding[option] = parseInt(selection); BDFDB.saveData(action, binding, this, "bindings"); }); - $(document).on("mousedown.select" + this.name, (e2) => { - if (e2.target.parentElement == selectMenu) return; - $(document).off("mousedown.select" + this.name); - selectMenu.remove() - setTimeout(() => {selectWrap.classList.remove(BDFDB.disCN.selectisopen);},100); - }); + + var removeMenu = e2 => { + if (e2.target.parentElement != selectMenu) { + document.removeEventListener("mousedown", removeMenu); + selectMenu.remove(); + plugincard.style.removeProperty("overflow"); + setTimeout(() => {BDFDB.removeClass(selectWrap, BDFDB.disCN.selectisopen);},100); + } + }; + document.addEventListener("mousedown", removeMenu); } createDropdownMenu (action, value) { - var menuhtml = `
`; - for (var i in this.clickMap) { - var isSelected = i == value ? ` ${BDFDB.disCN.selectselected}` : ``; + let menuhtml = `
`; + for (let i in this.clickMap) { + let isSelected = i == value ? ` ${BDFDB.disCN.selectselected}` : ``; menuhtml += `
${this.clickMap[i]}
` } menuhtml += `
`; - return $(menuhtml)[0]; + return BDFDB.htmlToElement(menuhtml); } startRecording (settingspanel, e) { - var recorderWrap = e.currentTarget; + let recorderWrap = e.currentTarget; + if (BDFDB.containsClass(recorderWrap, BDFDB.disCN.hotkeyrecording)) return; - if (recorderWrap.classList.contains(BDFDB.disCN.hotkeyrecording)) return; + let recorderInput = recorderWrap.querySelector("input"); + let recorderText = recorderWrap.querySelector(BDFDB.dotCN.hotkeytext); + let action = recorderWrap.getAttribute("type"); + let option = recorderWrap.getAttribute("option"); - var recorderInput = recorderWrap.querySelector("input"); - var recorderText = recorderWrap.querySelector(BDFDB.dotCN.hotkeytext); - var action = recorderWrap.getAttribute("type"); - var option = recorderWrap.getAttribute("option"); - - recorderWrap.classList.add(BDFDB.disCN.hotkeyrecording); - recorderWrap.classList.remove(BDFDB.disCN.hotkeyhasvalue); + BDFDB.addClass(recorderWrap, BDFDB.disCN.hotkeyrecording); + BDFDB.removeClass(recorderWrap, BDFDB.disCN.hotkeyhasvalue); recorderText.innerText = BDFDB.LanguageStrings.SHORTCUT_RECORDER_BUTTON_RECORDING; - $(document).on("keydown.recorder" + this.name, (e) => { + + var saveRecording = e => { recorderWrap.setAttribute("value", e.which); recorderInput.setAttribute("value", this.keyboardMap[e.which]); - }); + }; - $(document).on("mousedown.recorder" + this.name, () => { - $(document).off("mousedown.recorder" + this.name); - $(document).off("keydown.recorder" + this.name); - var binding = BDFDB.getData(action, this, "bindings"); + var stopRecording = e => { + document.removeEventListener("mousedown", stopRecording); + document.removeEventListener("keydown", saveRecording); + let binding = BDFDB.getData(action, this, "bindings"); binding[option] = parseInt(recorderWrap.getAttribute("value")); BDFDB.saveData(action, binding, this, "bindings"); setTimeout(() => { - recorderWrap.classList.remove(BDFDB.disCN.hotkeyrecording); - recorderWrap.classList.add(BDFDB.disCN.hotkeyhasvalue); + BDFDB.removeClass(recorderWrap, BDFDB.disCN.hotkeyrecording); + BDFDB.addClass(recorderWrap, BDFDB.disCN.hotkeyhasvalue); recorderText.innerText = BDFDB.LanguageStrings.SHORTCUT_RECORDER_BUTTON_EDIT; },100); - }); + }; + + document.addEventListener("mousedown", stopRecording); + document.addEventListener("keydown", saveRecording); } resetRecorder (settingspanel, e) { - var resetButton = e.currentTarget; - var recorderWrap = e.currentTarget.parentElement.parentElement.querySelector(BDFDB.dotCN.hotkeycontainer); - var recorderInput = recorderWrap.querySelector("input"); - var action = recorderWrap.getAttribute("type"); - var option = recorderWrap.getAttribute("option"); + let resetButton = e.currentTarget; + let recorderWrap = e.currentTarget.parentElement.parentElement.querySelector(BDFDB.dotCN.hotkeycontainer); + let recorderInput = recorderWrap.querySelector("input"); + let action = recorderWrap.getAttribute("type"); + let option = recorderWrap.getAttribute("option"); recorderWrap.setAttribute("value", 0); recorderInput.setAttribute("value", this.keyboardMap[0]); - var binding = BDFDB.getData(action, this, "bindings"); + let binding = BDFDB.getData(action, this, "bindings"); binding[option] = parseInt(recorderWrap.getAttribute("value")); BDFDB.saveData(action, binding, this, "bindings"); } @@ -221,12 +218,12 @@ module.exports = (Plugin, Api, Vendor) => { onClick (div, click, name) { if (!this.isEventFired(name)) { this.fireEvent(name); - var settings = BDFDB.getAllData(this, "settings"); - var bindings = BDFDB.getAllData(this, "bindings") + let settings = BDFDB.getAllData(this, "settings"); + let bindings = BDFDB.getAllData(this, "bindings"); for (let action in bindings) { if (settings[action] && this.checkIfBindingIsValid(bindings[action], click)) { - var message = this.getMessageData(div); - if (message) this.defaults.bindings[action].func.bind(this)(message); + let {messagediv, pos, message} = this.getMessageData(div); + if (messagediv && pos > -1 && message) this.defaults.bindings[action].func.bind(this)({messagediv, pos, message}); break; } } @@ -235,7 +232,7 @@ module.exports = (Plugin, Api, Vendor) => { } checkIfBindingIsValid (binding, doneclick) { - var valid = true; + let valid = true; for (let click of this.clicks) { if (binding[click] != doneclick) valid = false; } @@ -245,58 +242,56 @@ module.exports = (Plugin, Api, Vendor) => { return valid; } - doDelete (message) { - var channel = this.ChannelStore.getChannel(message.channel_id); + doDelete ({messagediv, pos, message}) { + let channel = this.ChannelUtils.getChannel(message.channel_id); if ((channel && this.CurrentUserPerms.can(this.Permissions.MANAGE_MESSAGES, channel)) || message.author.id == BDFDB.myData.id) { this.MessageActions.deleteMessage(message.channel_id, message.id); } } - doEdit (message) { - if (message.author.id == BDFDB.myData.id) { + doEdit ({messagediv, pos, message}) { + if (message.author.id == BDFDB.myData.id && !messagediv.querySelector("textarea")) { this.MessageActions.startEditMessage(message.channel_id, message.id, message.content); } } - doOpenReact (message) { - var reactButton = message.div.querySelector(BDFDB.dotCN.emojipickerbutton); + doOpenReact ({messagediv, pos, message}) { + let reactButton = messagediv.querySelector(BDFDB.dotCN.emojipickerbutton); if (reactButton) reactButton.click(); } - doPinUnPin (message) { - var channel = this.ChannelStore.getChannel(message.channel_id); + doPinUnPin ({messagediv, pos, message}) { + let channel = this.ChannelUtils.getChannel(message.channel_id); if (channel && this.CurrentUserPerms.can(this.Permissions.MANAGE_MESSAGES, channel)) { - if (message.pinned) this.PinActions.unpinMessage(channel, message.id); - else this.PinActions.pinMessage(channel, message.id); + if (message.pinned) this.PinActions.unpinMessage(channel, message.id); + else this.PinActions.pinMessage(channel, message.id); } } - doNote (message) { - if (BDFDB.isPluginEnabled("PersonalPins") == true) { - var PersonalPins = window.bdplugins["PersonalPins"].plugin; - PersonalPins.getMessageData(message.div); - PersonalPins.addMessageToNotes(); + doNote ({messagediv, pos, message}) { + if (BDFDB.isPluginEnabled(this.defaults.bindings.__Note_Message.plugin)) { + let channel = this.ChannelUtils.getChannel(message.channel_id); + if (channel) bdplugins[this.defaults.bindings.__Note_Message.plugin].plugin.addMessageToNotes(message, messagediv, channel); } } - doTranslate (message) { - if (BDFDB.isPluginEnabled("GoogleTranslateOption") == true) { - var GoogleTranslateOption = window.bdplugins["GoogleTranslateOption"].plugin; - GoogleTranslateOption.getMessageData(message.div); - GoogleTranslateOption.translateMessage(); + doTranslate ({messagediv, pos, message}) { + if (BDFDB.isPluginEnabled(this.defaults.bindings.__Translate_Message.plugin)) { + let channel = this.ChannelUtils.getChannel(message.channel_id); + if (channel) bdplugins[this.defaults.bindings.__Translate_Message.plugin].plugin.translateMessage(message, messagediv, channel); } } - doQuote (message) { - if (BDFDB.isPluginEnabled("Quoter") == true) { - var quoteButton = message.div.querySelector(".btn-quote"); + doQuote ({messagediv, pos, message}) { + if (BDFDB.isPluginEnabled(this.defaults.bindings.__Quote_Message.plugin)) { + let quoteButton = messagediv.querySelector(".btn-quote"); if (quoteButton) quoteButton.click(); } } - doCitate (message) { - if (BDFDB.isPluginEnabled("Citador") == true) { - var citarButton = message.div.parentElement.querySelector(".citar-btn"); + doCitate ({messagediv, pos, message}) { + if (BDFDB.isPluginEnabled(this.defaults.bindings.__Citate_Message.plugin)) { + let citarButton = messagediv.parentElement.querySelector(".citar-btn"); if (citarButton) citarButton.click(); } } @@ -305,23 +300,33 @@ module.exports = (Plugin, Api, Vendor) => { if (!this.isEventFired(name)) { this.fireEvent(name); if (key == 27 && BDFDB.getData("clearOnEscape", this, "settings")) { - var instance = BDFDB.getOwnerInstance({"node":div, "name":"ChannelTextAreaForm", "up":true}); - if (instance) instance.setState({textValue:""}); + let instance = BDFDB.getOwnerInstance({"node":div, "name":"ChannelTextAreaForm", "up":true}); + if (instance) { + instance.setState({textValue:""}); + } } this.cancelEvent(name); } } - getMessageData (div) { - if (div) { - var messagegroup = $(BDFDB.dotCN.messagegroup).has(div); - var pos = messagegroup.find(BDFDB.dotCN.message).index(div); - if (messagegroup[0] && pos > -1) { - var info = BDFDB.getKeyInformation({"node":div,"key":"messages","up":true,"time":1000}); - if (info) return Object.assign({},info[pos],{"div":div, "group":messagegroup[0], "pos":pos}); + getActiveShortcutString (action) { + let str = ""; + if (BDFDB.getData(action, this, "settings")) { + let binding = BDFDB.getData(action, this, "bindings"); + if (binding) for (let type in binding) { + let typename = type.indexOf("click") == 0 ? this.clickMap[binding[type]] : this.keyboardMap[binding[type]]; + if (typename && typename != "NONE") str += typename + "+"; } } - return null; + return str ? str.slice(0,-1) : null; + } + + getMessageData (target) { + let messagediv = BDFDB.getParentEle(BDFDB.dotCN.message, target); + let pos = messagediv ? Array.from(messagediv.parentElement.querySelectorAll(BDFDB.dotCN.message)).indexOf(messagediv) : -1; + let instance = BDFDB.getReactInstance(messagediv); + let message = instance && instance.return && instance.return.memoizedProps && instance.return.memoizedProps.message ? instance.return.memoizedProps.message : null; + return {messagediv, pos, message}; } fireEvent (name) { @@ -337,38 +342,36 @@ module.exports = (Plugin, Api, Vendor) => { } getSettingsPanel () { - var settings = BDFDB.getAllData(this, "settings"); - var bindings = BDFDB.getAllData(this, "bindings"); - var settingshtml = `
`; + if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; + let settings = BDFDB.getAllData(this, "settings"); + let bindings = BDFDB.getAllData(this, "bindings"); + let settingshtml = `
${this.name}
`; for (let key in settings) { - if (this.defaults.settings[key].description) settingshtml += `

${this.defaults.settings[key].description}

`; + if (this.defaults.settings[key].description) settingshtml += `

${this.defaults.settings[key].description}

`; } for (let action in bindings) { - settingshtml += `

${this.defaults.bindings[action].name}:

`; - for (let click of this.clicks) { - settingshtml += `
${click}:
${this.clickMap[bindings[action][click]]}
`; + if (!this.defaults.bindings[action].plugin || BDFDB.isPluginEnabled(this.defaults.bindings[action].plugin)) { + settingshtml += `

${this.defaults.bindings[action].name}:

`; + for (let click of this.clicks) { + settingshtml += `
${click}:
${this.clickMap[bindings[action][click]]}
`; + } + for (let key of this.keys) { + settingshtml += `
${key}:
`; + } + settingshtml += `
`; } - for (let key of this.keys) { - settingshtml += `
${key}:
`; - } - settingshtml += `
`; } settingshtml += `

Reset all key bindings.

`; - settingshtml += `
`; + settingshtml += `
`; - var settingspanel = $(settingshtml)[0]; + let settingspanel = BDFDB.htmlToElement(settingshtml); - $(settingspanel) - .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) - .on("click", BDFDB.dotCN.selectcontrol, (e) => {this.openDropdownMenu(settingspanel, e);}) - .on("click", BDFDB.dotCN.hotkeycontainer, (e) => {this.startRecording(settingspanel, e);}) - .on("click", ".reset-recorder", (e) => {this.resetRecorder(settingspanel, e);}) - .on("click", ".reset-button", () => {this.resetAll(settingspanel);}); + BDFDB.initElements(settingspanel, this); - $(settingspanel).find(".__Note_Message-key-settings").toggle(BDFDB.isPluginEnabled("PersonalPins") == true); - $(settingspanel).find(".__Translate_Message-key-settings").toggle(BDFDB.isPluginEnabled("GoogleTranslateOption") == true); - $(settingspanel).find(".__Quote_Message-key-settings").toggle(BDFDB.isPluginEnabled("Quoter") == true); - $(settingspanel).find(".__Citate_Message-key-settings").toggle(BDFDB.isPluginEnabled("Citador") == true); + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.selectcontrol, e => {this.openDropdownMenu(e);}) + BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.hotkeycontainer, e => {this.startRecording(settingspanel, e);}) + BDFDB.addEventListener(this, settingspanel, "click", ".reset-recorder", e => {this.resetRecorder(settingspanel, e);}) + BDFDB.addEventListener(this, settingspanel, "click", ".reset-button", () => {this.resetAll(settingspanel);}); return settingspanel; } diff --git a/PluginsV2/MoveablePopups/index.js b/PluginsV2/MoveablePopups/index.js index d66f2476f4..a82e14fd6c 100644 --- a/PluginsV2/MoveablePopups/index.js +++ b/PluginsV2/MoveablePopups/index.js @@ -22,6 +22,7 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return true; BDFDB.loadMessage(this); var observer = null; @@ -31,7 +32,7 @@ module.exports = (Plugin, Api, Vendor) => { (change, i) => { if (change.addedNodes) { change.addedNodes.forEach((node) => { - if (node && node.classList && node.classList.length > 0 && node.classList.contains(BDFDB.disCN.popout)) { + if (node && BDFDB.containsClass(node, BDFDB.disCN.popout)) { this.makeMoveable(node); } }); @@ -46,10 +47,10 @@ module.exports = (Plugin, Api, Vendor) => { (change, i) => { if (change.addedNodes) { change.addedNodes.forEach((node) => { - if (node && node.classList && node.classList.contains(BDFDB.disCN.modal) && !node.querySelector(BDFDB.dotCN.downloadlink)) { + if (node && BDFDB.containsClass(node, BDFDB.disCN.modal) && !node.querySelector(BDFDB.dotCN.downloadlink)) { this.makeMoveable(node.querySelector(BDFDB.dotCN.modalinner)); } - else if (node && node.tagName && node.querySelector(BDFDB.dotCN.modal) && !node.querySelector(BDFDB.dotCN.downloadlink)) { + else if (node.tagName && node.querySelector(BDFDB.dotCN.modal) && !node.querySelector(BDFDB.dotCN.downloadlink)) { this.makeMoveable(node.querySelector(BDFDB.dotCN.modalinner)); } }); @@ -82,46 +83,44 @@ module.exports = (Plugin, Api, Vendor) => { // begin of own functions makeMoveable (div) { - $(div) - .off("mousedown." + this.name).off("click." + this.name) - .on("click." + this.name, (e) => { - if (this.dragging) { - e.stopPropagation(); - e.preventDefault(); - } - }) - .on("mousedown." + this.name, (e) => { - if (e.ctrlKey) { - this.dragging = true; + div.removeEventListener("click", div.clickMovablePopups); + div.removeEventListener("mousedown", div.mousedownMovablePopups); + div.clickMovablePopups = e => { + if (this.dragging) { + e.stopPropagation(); + e.preventDefault(); + } + }; + div.mousedownMovablePopups = e => { + if (!e.ctrlKey) return; + div.style.setProperty("position", "fixed", "important"); + this.dragging = true; + var rects = BDFDB.getRects(div); + var transform = getComputedStyle(div,null).getPropertyValue("transform").replace(/[^0-9,-]/g,"").split(","); + var left = rects.left - (transform.length > 4 ? parseFloat(transform[4]) : 0); + var top = rects.top - (transform.length > 4 ? parseFloat(transform[5]) : 0); + var oldX = e.pageX; + var oldY = e.pageY; + var mouseup = e2 => { + BDFDB.removeLocalStyle("disableTextSelection"); + document.removeEventListener("mouseup", mouseup); + document.removeEventListener("mousemove", mousemove); + setTimeout(() => {this.dragging = false},1); + }; + var mousemove = e2 => { + left = left - (oldX - e2.pageX); + top = top - (oldY - e2.pageY); + oldX = e2.pageX; + oldY = e2.pageY; + div.style.setProperty("left", left + "px", "important"); + div.style.setProperty("top", top + "px", "important"); - var disableTextSelectionCSS = ` - * { - user-select: none !important; - }`; - - BDFDB.appendLocalStyle("disableTextSelection", disableTextSelectionCSS); - var left = div.getBoundingClientRect().left; - var top = div.getBoundingClientRect().top; - var oldX = e.pageX; - var oldY = e.pageY; - $(document) - .off("mouseup." + this.name).off("mousemove." + this.name) - .on("mouseup." + this.name, () => { - BDFDB.removeLocalStyle("disableTextSelection"); - $(document).off("mouseup." + this.name).off("mousemove." + this.name); - setTimeout(() => {this.dragging = false},1); - }) - .on("mousemove." + this.name, (e2) => { - var newX = e2.pageX; - var newY = e2.pageY; - left = left - (oldX - newX); - top = top - (oldY - newY); - oldX = newX; - oldY = newY; - $(div).offset({"left":left,"top":top}); - }); - } - }); + }; + document.addEventListener("mouseup", mouseup); + document.addEventListener("mousemove", mousemove); + }; + div.addEventListener("click", div.clickMovablePopups); + div.addEventListener("mousedown", div.mousedownMovablePopups); } } }; diff --git a/PluginsV2/NotificationSounds/index.js b/PluginsV2/NotificationSounds/index.js index 5fdd455e6e..71ddbbd296 100644 --- a/PluginsV2/NotificationSounds/index.js +++ b/PluginsV2/NotificationSounds/index.js @@ -113,7 +113,7 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - if (this.started) return; + if (this.started) return true; BDFDB.loadMessage(this); this.ChannelSettingsUtils = BDFDB.WebModules.findByProperties("isGuildOrCategoryOrChannelMuted"); diff --git a/PluginsV2/OldTitleBar/index.js b/PluginsV2/OldTitleBar/index.js index 4645d49d05..5836e59e89 100644 --- a/PluginsV2/OldTitleBar/index.js +++ b/PluginsV2/OldTitleBar/index.js @@ -107,7 +107,7 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - if (this.started) return; + if (this.started) return true; BDFDB.loadMessage(this); BDFDB.addEventListener(this, window, "resize", e => {this.changeMaximizeButtons();}); diff --git a/PluginsV2/PersonalPins/index.js b/PluginsV2/PersonalPins/index.js index 76da5707d5..8de9ebf010 100644 --- a/PluginsV2/PersonalPins/index.js +++ b/PluginsV2/PersonalPins/index.js @@ -168,7 +168,7 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - if (this.started) return; + if (this.started) return true; BDFDB.loadMessage(this); this.SelectChannelUtils = BDFDB.WebModules.findByProperties("selectGuild","selectChannel"); diff --git a/PluginsV2/PinDMs/index.js b/PluginsV2/PinDMs/index.js index 4bfa3857b6..3eba2bcd34 100644 --- a/PluginsV2/PinDMs/index.js +++ b/PluginsV2/PinDMs/index.js @@ -113,7 +113,7 @@ module.exports = (Plugin, Api, Vendor) => { initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - if (this.started) return; + if (this.started) return true; BDFDB.loadMessage(this); this.UserUtils = BDFDB.WebModules.findByProperties("getUsers", "getUser"); diff --git a/PluginsV2/RemoveNicknames/index.js b/PluginsV2/RemoveNicknames/index.js index f1c08c97b9..237b076161 100644 --- a/PluginsV2/RemoveNicknames/index.js +++ b/PluginsV2/RemoveNicknames/index.js @@ -7,8 +7,7 @@ module.exports = (Plugin, Api, Vendor) => { "NameTag":"componentDidMount", "FluxContainer(TypingUsers)":"componentDidUpdate", "MessageUsername":"componentDidMount", - "Clickable":"componentDidMount", - "StandardSidebarView":"componentWillUnmount" + "Clickable":"componentDidMount" }; this.defaults = { diff --git a/PluginsV2/ShowHiddenChannels/index.js b/PluginsV2/ShowHiddenChannels/index.js index 6ea0cf584d..686c18a73f 100644 --- a/PluginsV2/ShowHiddenChannels/index.js +++ b/PluginsV2/ShowHiddenChannels/index.js @@ -6,8 +6,7 @@ module.exports = (Plugin, Api, Vendor) => { this.patchModules = { "Channels":["componentDidMount","componentDidUpdate"], "ChannelItem":"componentDidMount", - "ChannelCategoryItem":"componentDidMount", - "StandardSidebarView":"componentWillUnmount" + "ChannelCategoryItem":"componentDidMount" }; this.categoryMarkup = diff --git a/PluginsV2/ShowImageDetails/index.js b/PluginsV2/ShowImageDetails/index.js index be32925a74..21ce6fd3af 100644 --- a/PluginsV2/ShowImageDetails/index.js +++ b/PluginsV2/ShowImageDetails/index.js @@ -4,8 +4,7 @@ module.exports = (Plugin, Api, Vendor) => { return class extends Plugin { initConstructor () { this.patchModules = { - "LazyImageZoomable":"componentDidMount", - "StandardSidebarView":"componentWillUnmount" + "LazyImageZoomable":"componentDidMount" }; this.css = `