module.exports = (Plugin, Api, Vendor) => { if (typeof BDFDB !== "object") global.BDFDB = {$: Vendor.$, BDv2Api: Api}; const {$} = Vendor; return class extends Plugin { initConstructor () { this.pinDMEntryMarkup = `
REPLACE_context_pindm_text
`; this.pinDMsHeaderMarkup = `
REPLACE_header_pinneddms_text
`; this.pinnedDMMarkup = `
`; this.richActivityMarkup = ` `; } onStart () { var libraryScript = null; if (typeof BDFDB !== "object" || typeof BDFDB.isLibraryOutdated !== "function" || BDFDB.isLibraryOutdated()) { libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]'); if (libraryScript) libraryScript.remove(); libraryScript = document.createElement("script"); libraryScript.setAttribute("type", "text/javascript"); libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"); document.head.appendChild(libraryScript); } this.startTimeout = setTimeout(() => {this.initialize();}, 30000); if (typeof BDFDB === "object" && typeof BDFDB.isLibraryOutdated === "function") this.initialize(); else libraryScript.addEventListener("load", () => {this.initialize();}); return true; } initialize () { if (typeof BDFDB === "object") { BDFDB.loadMessage(this); this.UserStore = BDFDB.WebModules.findByProperties("getUsers", "getUser"); this.ActivityStore = BDFDB.WebModules.findByProperties("getStatuses", "getActivities"); this.ChannelStore = BDFDB.WebModules.findByProperties("getDMFromUserId"); this.ChannelSwitchUtils = BDFDB.WebModules.findByProperties("selectPrivateChannel"); this.UserContextMenuUtils = BDFDB.WebModules.findByProperties("openUserContextMenu"); var observer = null; 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:"dmContextObserver",instance:observer}, {childList: true}); observer = new MutationObserver((changes, _) => { changes.forEach( (change, i) => { if (change.addedNodes) { change.addedNodes.forEach((node) => { if (node && node.classList && node.classList.contains("btn-friends")) { $(BDFDB.dotCN.dmchannel + BDFDB.dotCN.dmchannelprivate + ".pinned, header.pinneddms-header").remove(); this.addAllPinnedDMs(); } }); } } ); }); BDFDB.addObserver(this, BDFDB.dotCNS.dmchannels + BDFDB.dotCN.scroller, {name:"friendButtonObserver",instance:observer}, {childList: true}); setTimeout(() => {this.onSwitch();},1000); return true; } else { console.error(this.name + ": Fatal Error: Could not load BD functions!"); return false; } } onStop () { if (typeof BDFDB === "object") { $(BDFDB.dotCN.dmchannel + BDFDB.dotCN.dmchannelprivate + ".pinned, header.pinneddms-header").remove(); clearInterval(this.statusInterval); BDFDB.unloadMessage(this); return true; } else { return false; } } onSwitch () { if (!document.querySelector(BDFDB.dotCNS.guildactive + BDFDB.dotCN.friendsicon) || document.querySelector(BDFDB.dotCN.dmchannel + BDFDB.dotCN.dmchannelprivate + ".pinned")) return; this.addAllPinnedDMs(); BDFDB.addObserver(this, BDFDB.dotCNS.dmchannels + BDFDB.dotCN.scroller, {name:"friendButtonObserver"}, {childList: true}); } // begin of own functions changeLanguageStrings () { this.pinDMsHeaderMarkup = this.pinDMsHeaderMarkup.replace("REPLACE_header_pinneddms_text", this.labels.header_pinneddms_text); this.pinDMEntryMarkup = this.pinDMEntryMarkup.replace("REPLACE_context_pindm_text", this.labels.context_pindm_text); } onContextMenu (context) { if (!document.querySelector(BDFDB.dotCNS.guildactive + BDFDB.dotCN.friendsicon) || !context || !context.tagName || !context.parentElement || context.querySelector(".pindm-item")) return; var info = BDFDB.getKeyInformation({"node":context, "key":"user"}), ele = null; if (info && BDFDB.getKeyInformation({"node":context, "key":"handleClose"})) { ele = context.querySelectorAll(BDFDB.dotCN.contextmenuitem)[3]; } else { info = BDFDB.getKeyInformation({"node":context, "key":"channel"}); if (info && BDFDB.getKeyInformation({"node":context, "key":"handleChangeIcon"})) { ele = context.querySelectorAll(BDFDB.dotCN.contextmenuitem)[1]; } } if (ele) { $(this.pinDMEntryMarkup).insertBefore(ele) .on("click", (e) => { $(context).hide(); var pinnedDMs = BDFDB.loadAllData(this, "pinnedDMs"); if (typeof pinnedDMs[info.id] == "undefined") { var pos = Object.keys(pinnedDMs).length; pinnedDMs[info.id] = pos; BDFDB.saveAllData(pinnedDMs, this, "pinnedDMs") this.addPinnedDM(info.id, pos); } }); BDFDB.updateContextPosition(context); } } addAllPinnedDMs () { var pinnedDMs = BDFDB.loadAllData(this, "pinnedDMs"); var sortedDMs = []; for (let id in pinnedDMs) sortedDMs[pinnedDMs[id]] = id; for (let pos in sortedDMs.reverse()) { this.addPinnedDM(sortedDMs[pos], pos); } } addPinnedDM (id, pos) { if (!document.querySelector(BDFDB.dotCN.dmchannel + BDFDB.dotCN.friendsbutton + " + header.pinneddms-header")) { $(this.pinDMsHeaderMarkup).insertBefore(BDFDB.dotCN.dmchannel + BDFDB.dotCN.friendsbutton + " + header"); this.startUpdateInterval(); } let user = this.UserStore.getUser(id); let channel = this.ChannelStore.getChannel(id); if (user || channel) { let DMid = user ? this.ChannelStore.getDMFromUserId(user.id) : channel.id; let pinnedDM = $(this.pinnedDMMarkup); pinnedDM.attr("user-id", user ? user.id : null).attr("channel-id", DMid).insertAfter(BDFDB.dotCN.dmchannel + BDFDB.dotCN.friendsbutton + " + header.pinneddms-header") .on("contextmenu." + this.name, (e) => { if (user && DMid) this.UserContextMenuUtils.openUserContextMenu(e, user, this.ChannelStore.getChannel(DMid)); else { var channelObj = BDFDB.getDivOfChannel(channel.id); if (channelObj && channelObj.div) BDFDB.getKeyInformation({"node":channelObj.div,"key":"onContextMenu"})(e); else BDFDB.showToast("Could not open ContextMenu, make sure the DM exists, Group DMs habe to be loaded in the list.", {type:"error"}); } }) .on("click." + this.name, (e) => { if (e.target.classList && e.target.classList.contains(BDFDB.disCN.dmchannelclose)) return; if (DMid) this.ChannelSwitchUtils.selectPrivateChannel(DMid); else BDFDB.showToast("Could not open DM, make sure it exists.", {type:"error"}); }) .on("click." + this.name, BDFDB.dotCN.dmchannelclose, () => { pinnedDM.remove(); BDFDB.removeData(user ? user.id : DMid, this, "pinnedDMs"); this.updatePinnedDMPositions(); }); this.setPinnedDM(pinnedDM[0]); } } setPinnedDM (pinnedDM) { if (pinnedDM && pinnedDM.parentElement) { let id = pinnedDM.getAttribute("user-id"); let user = this.UserStore.getUser(id); if (user) { let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; let activity = this.ActivityStore.getActivity(user.id); pinnedDM.querySelector(BDFDB.dotCN.avatarsmallold + ":not(" + BDFDB.dotCN.avatarwrapper + ")").style.backgroundImage = `url(${data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(user.id))})`; pinnedDM.querySelector(BDFDB.dotCN.status).classList.add(BDFDB.disCN[`status${BDFDB.getUserStatus(user.id)}`]); pinnedDM.querySelector(BDFDB.dotCN.dmchannelname + " > label").textContent = data.name ? data.name : user.username; pinnedDM.querySelector(BDFDB.dotCN.dmchannelname).style.color = data.color1 ? BDFDB.color2RGB(data.color1) : ""; pinnedDM.querySelector(BDFDB.dotCN.dmchannelname).style.background = data.color2 ? BDFDB.color2RGB(data.color2) : ""; pinnedDM.querySelector(BDFDB.dotCN.dmchannelactivitytext).innerHTML = activity ? this.getActivityString(activity.type, activity.name) : ""; if (activity && activity.application_id && activity.session_id) { if (!pinnedDM.querySelector(BDFDB.dotCN.dmchannelactivityicon)) $(BDFDB.dotCN.dmchannelactivity, pinnedDM).append(this.richActivityMarkup); } else $(BDFDB.dotCN.dmchannelactivityicon, pinnedDM).remove(); } else { id = pinnedDM.getAttribute("channel-id") let channel = this.ChannelStore.getChannel(id); if (channel) { pinnedDM.querySelector(BDFDB.dotCN.avatarsmallold + ":not(" + BDFDB.dotCN.avatarwrapper + ")").style.backgroundImage = `url(${BDFDB.getChannelAvatar(channel.id)})`; var channelname = channel.name; if (!channelname && channel.recipients.length > 0) { for (let dmmemberID of channel.recipients) { channelname = channelname ? channelname + ", " : channelname; channelname = channelname + this.UserStore.getUser(dmmemberID).username; } } pinnedDM.querySelector(BDFDB.dotCN.dmchannelname + " > label").textContent = channelname ? channelname : BDFDB.LanguageStrings.UNNAMED; pinnedDM.querySelectorAll(BDFDB.dotCNC.status + BDFDB.dotCN.dmchannelactivitytext).forEach(ele => {ele.remove();}); pinnedDM.querySelector(BDFDB.dotCN.dmchannelactivity).innerHTML = channel.recipients.length+1 + " " + (channel.recipients.length+1 == 1 ? BDFDB.LanguageStrings.MEMBER : BDFDB.LanguageStrings.MEMBERS); } } } } startUpdateInterval () { this.statusInterval = setInterval(() => { for (let pinnedDM of document.querySelectorAll(BDFDB.dotCN.dmchannel + BDFDB.dotCN.dmchannelprivate + ".pinned")) this.setPinnedDM(pinnedDM); if (!document.querySelector(BDFDB.dotCN.dmchannel + BDFDB.dotCN.friendsbutton + " + header.pinneddms-header")) clearInterval(this.statusInterval); },10000); } getActivityString (type, name) { let stringname = ""; switch (type) { case 0: stringname = "PLAYING_GAME"; break; case 1: stringname = "STREAMING"; break; case 2: stringname = "LISTENING_TO"; break; case 3: stringname = "WATCHING"; break; } let string = BDFDB.LanguageStrings[stringname] || ""; return string.replace("**!!{name}!!**", `${name}`).replace("**!!{game}!!**", `${name}`); } updatePinnedDMPositions () { let pinnedDMs = BDFDB.loadAllData(this, "pinnedDMs"); let pinnedDMEles = document.querySelectorAll(BDFDB.dotCN.dmchannel + BDFDB.dotCN.dmchannelprivate + ".pinned"); for (let i = 0; i < pinnedDMEles.length; i++) { pinnedDMs[pinnedDMEles[i].id] = i; } if (pinnedDMEles.length == 0) $(BDFDB.dotCN.dmchannel + BDFDB.dotCN.friendsbutton + " + header.pinneddms-header").remove(); BDFDB.saveAllData(pinnedDMs, this, "pinnedDMs") } setLabelsByLanguage () { switch (BDFDB.getDiscordLanguage().id) { case "hr": //croatian return { context_pindm_text: "Prikljucite Izravnu Dopisivanje", header_pinneddms_text: "Prikvačene izravne poruke" }; case "da": //danish return { context_pindm_text: "Pin DB", header_pinneddms_text: "Pinned Privat Beskeder" }; case "de": //german return { context_pindm_text: "Direktnachricht anpinnen", header_pinneddms_text: "Gepinnte Direktnachrichten" }; case "es": //spanish return { context_pindm_text: "Pin MD", header_pinneddms_text: "Mensajes Directos Fijados" }; case "fr": //french return { context_pindm_text: "Épingler MP", header_pinneddms_text: "Messages Prives Épinglés" }; case "it": //italian return { context_pindm_text: "Appuntare il messaggio diretto", header_pinneddms_text: "Messaggi Diretti Aggiunti" }; case "nl": //dutch return { context_pindm_text: "PB vastpinnen", header_pinneddms_text: "Vastgezette Persoonluke Berichten" }; case "no": //norwegian return { context_pindm_text: "Pinne DM", header_pinneddms_text: "Pinned Direktemeldinger" }; case "pl": //polish return { context_pindm_text: "Przypnij PW", header_pinneddms_text: "Prywatne Wiadomości Bezpośrednie" }; case "pt-BR": //portuguese (brazil) return { context_pindm_text: "Fixar MD", header_pinneddms_text: "Mensagens diretas fixadas" }; case "fi": //finnish return { context_pindm_text: "Kiinnitä yksityisviestit", header_pinneddms_text: "Liitetyt yksityisviestit" }; case "sv": //swedish return { context_pindm_text: "Peka DM", header_pinneddms_text: "Inlagda Direktmeddelanden" }; case "tr": //turkish return { context_pindm_text: "DM'yi Sabitle", header_pinneddms_text: "Direkt Mesajlar Sabitleyin" }; case "cs": //czech return { context_pindm_text: "Připojte PZ", header_pinneddms_text: "Připojené přímá zpráva" }; case "bg": //bulgarian return { context_pindm_text: "Закачете", header_pinneddms_text: "Свързани директни съобщения" }; case "ru": //russian return { context_pindm_text: "Подключить ЛС", header_pinneddms_text: "Прикрепленные Личные сообщения" }; case "uk": //ukrainian return { context_pindm_text: "Прикріпити ОП", header_pinneddms_text: "Прикріплені oсобисті повідомлення" }; case "ja": //japanese return { context_pindm_text: "DMをピン留めする", header_pinneddms_text: "固定された直接メッセージ" }; case "zh-TW": //chinese (traditional) return { context_pindm_text: "引用私人信息", header_pinneddms_text: "固定私人信息" }; case "ko": //korean return { context_pindm_text: "개인 메시지 비공개", header_pinneddms_text: "고정 된 비공개 메시지" }; default: //default: english return { context_pindm_text: "Pin DM", header_pinneddms_text: "Pinned Direct Messages" }; } } } };