BetterDiscordAddons/PluginsV2/PinDMs/index.js

400 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module.exports = (Plugin, Api, Vendor) => {
if (typeof BDFDB !== "object") global.BDFDB = {$: Vendor.$, BDv2Api: Api};
const {$} = Vendor;
return class extends Plugin {
initConstructor () {
this.pinDMEntryMarkup =
`<div class="${BDFDB.disCN.contextmenuitem} pindm-item">
<span>REPLACE_context_pindm_text</span>
<div class="${BDFDB.disCN.contextmenuhint}"></div>
</div>`;
this.pinDMsHeaderMarkup =
`<header class="pinneddms-header">REPLACE_header_pinneddms_text</header>`;
this.pinnedDMMarkup =
`<div class="${BDFDB.disCNS.dmchannel + BDFDB.disCN.dmchannelprivate} pinned" style="height: 42px; opacity: 1;">
<a>
<div class="${BDFDB.disCNS.avatarwrapper + BDFDB.disCNS.avatarsmall + BDFDB.disCNS.forcedarktheme + BDFDB.disCN.avatarsmallold}">
<div class="${BDFDB.disCN.avatarsmallold} stop-animation"></div>
<div class="${BDFDB.disCNS.status + BDFDB.disCNS.statusold + BDFDB.disCN.avatarsmall}"></div>
</div>
<div class="${BDFDB.disCN.dmchannelname}">
<label style="cursor: pointer;"></label>
<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.flex2 + BDFDB.disCNS.horizontal + BDFDB.disCNS.horizontal2 + BDFDB.disCNS.directionrow + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.dmchannelactivity}" style="flex: 1 1 auto;">
<div class="${BDFDB.disCN.dmchannelactivitytext}"></div>
</div>
</div>
<button class="${BDFDB.disCN.dmchannelclose}"></button>
</a>
</div>`;
this.richActivityMarkup =
`<svg name="RichActivity" class="${BDFDB.disCN.dmchannelactivityicon}" width="16" height="16" viewBox="0 0 16 16">
<path class="${BDFDB.disCN.dmchannelactivityiconforeground}" fill="currentColor" d="M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z" transform="translate(3 3)"></path>
</svg>`;
}
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}!!**", `<strong>${name}</strong>`).replace("**!!{game}!!**", `<strong>${name}</strong>`);
}
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"
};
}
}
}
};