BetterDiscordAddons/Plugins/PinDMs/PinDMs.plugin.js

399 lines
14 KiB
JavaScript
Raw Normal View History

2018-10-11 10:21:26 +02:00
//META{"name":"PinDMs"}*//
class PinDMs {
getName () {return "PinDMs";}
getVersion () {return "1.2.8";}
getAuthor () {return "DevilBro";}
getDescription () {return "Allows you to pin DMs, making them appear at the top of your DM-list.";}
2018-10-11 10:21:26 +02:00
initConstructor () {
this.patchModules = {
"LazyScroller":["render"]
};
2018-10-11 10:21:26 +02:00
this.pinDMEntryMarkup =
`<div class="${BDFDB.disCN.contextmenuitem} pindms-item pindm-item">
2019-01-02 22:08:55 +01:00
<span class="DevilBro-textscrollwrapper" speed=3><div class="DevilBro-textscroll">REPLACE_context_pindm_text</div></span>
2018-10-11 10:21:26 +02:00
<div class="${BDFDB.disCN.contextmenuhint}"></div>
</div>`;
this.unpinDMEntryMarkup =
`<div class="${BDFDB.disCN.contextmenuitem} pindms-item unpindm-item">
2019-01-02 22:08:55 +01:00
<span class="DevilBro-textscrollwrapper" speed=3><div class="DevilBro-textscroll">REPLACE_context_unpindm_text</div></span>
<div class="${BDFDB.disCN.contextmenuhint}"></div>
</div>`;
2018-10-11 10:21:26 +02:00
}
//legacy
load () {}
start () {
2019-01-17 23:48:29 +01:00
var libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]');
if (!libraryScript || performance.now() - libraryScript.getAttribute("date") > 600000) {
2018-10-11 10:21:26 +02:00
if (libraryScript) libraryScript.remove();
libraryScript = document.createElement("script");
libraryScript.setAttribute("type", "text/javascript");
libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js");
2019-01-17 23:48:29 +01:00
libraryScript.setAttribute("date", performance.now());
libraryScript.addEventListener("load", () => {
BDFDB.loaded = true;
this.initialize();
});
2018-10-11 10:21:26 +02:00
document.head.appendChild(libraryScript);
}
2019-01-17 23:48:29 +01:00
else if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize();
2018-10-11 10:21:26 +02:00
this.startTimeout = setTimeout(() => {this.initialize();}, 30000);
}
initialize () {
2019-01-17 23:48:29 +01:00
if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
2019-01-22 11:05:54 +01:00
if (this.started) return;
2018-10-11 10:21:26 +02:00
BDFDB.loadMessage(this);
2018-12-20 22:54:42 +01:00
this.ChannelUtils = BDFDB.WebModules.findByProperties("getDMFromUserId");
2018-12-25 11:54:01 +01:00
this.PrivateChannelUtils = BDFDB.WebModules.findByProperties("ensurePrivateChannel");
2018-10-11 10:21:26 +02:00
BDFDB.addEventListener(this, document, "click", BDFDB.dotCNS.dmchannels + BDFDB.dotCN.dmchannel, e => {
let instance = BDFDB.getReactInstance(e.currentTarget);
if (BDFDB.getReactValue(instance, "return.return.return.memoizedProps.ispin")) {
let dmsscroller = document.querySelector(BDFDB.dotCNS.dmchannels + BDFDB.dotCN.scroller);
if (dmsscroller) {
this.oldScrollerPos = dmsscroller.scrollTop;
setTimeout(() => {this.oldScrollerPos = null;},1000);
2018-10-11 10:21:26 +02:00
}
}
2018-10-11 10:21:26 +02:00
});
BDFDB.addEventListener(this, document, "click", BDFDB.dotCNS.dmchannels + BDFDB.dotCNS.dmchannel + BDFDB.dotCN.dmchannelclose, e => {
let instance = BDFDB.getReactInstance(e.currentTarget);
if (BDFDB.getReactValue(instance, "return.return.return.return.return.memoizedProps.ispin")) {
e.originalEvent.stopPropagation();
e.originalEvent.preventDefault();
this.removePinnedDM(BDFDB.getReactValue(instance, "return.return.return.return.return.memoizedProps.channel.id"));
}
});
this.forceAdding = true;
BDFDB.WebModules.forceAllUpdates(this);
delete this.forceAdding;
2018-10-11 10:21:26 +02:00
}
else {
console.error(this.getName() + ": Fatal Error: Could not load BD functions!");
}
}
stop () {
2019-01-17 23:48:29 +01:00
if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
let dmsscrollerinstance = BDFDB.getReactInstance(document.querySelector(BDFDB.dotCNS.dmchannels + BDFDB.dotCN.scroller));
if (dmsscrollerinstance) {
let dms = dmsscrollerinstance.return.return.return.memoizedProps.children;
let amount = 0;
let insertpoint = null;
for (let i in dms) {
let ele = dms[i];
if (ele && ele.pinned) {
delete ele.pinned;
if (ele.props.ispin) {
if (ele.type == "header") insertpoint = i;
amount++;
}
}
}
dms.splice(insertpoint, amount);
this.forceUpdateScroller(dmsscrollerinstance.stateNode);
}
2018-10-11 10:21:26 +02:00
BDFDB.unloadMessage(this);
}
}
// begin of own functions
changeLanguageStrings () {
2018-10-11 10:21:26 +02:00
this.pinDMEntryMarkup = this.pinDMEntryMarkup.replace("REPLACE_context_pindm_text", this.labels.context_pindm_text);
this.unpinDMEntryMarkup = this.unpinDMEntryMarkup.replace("REPLACE_context_unpindm_text", this.labels.context_unpindm_text);
2018-10-11 10:21:26 +02:00
}
onUserContextMenu (instance, menu) {
if (instance.props && instance.props.user && !menu.querySelector(".pindms-item")) {
let closeentry = BDFDB.React.findDOMNodeSafe(BDFDB.getOwnerInstance({node:menu,props:["handleClose"]}));
if (closeentry) {
let id = this.ChannelUtils.getDMFromUserId(instance.props.user.id);
if (id) this.appendItem(instance, id, closeentry);
else this.PrivateChannelUtils.ensurePrivateChannel(BDFDB.myData.id, instance.props.user.id).then(id => {this.appendItem(instance, id, closeentry);});
}
2018-10-11 10:21:26 +02:00
}
}
onGroupDMContextMenu (instance, menu) {
if (instance.props && instance.props.channelId && !menu.querySelector(".pindms-item")) {
let changeentry = BDFDB.React.findDOMNodeSafe(BDFDB.getOwnerInstance({node:menu,props:["handleChangeIcon"]}));
if (changeentry) {
this.appendItem(instance, instance.props.channelId, changeentry);
2018-10-11 10:21:26 +02:00
}
}
}
appendItem (instance, id, target) {
let pinnedDMs = BDFDB.loadAllData(this, "pinnedDMs");
if (!pinnedDMs[id]) {
let pinDMEntry = BDFDB.htmlToElement(this.pinDMEntryMarkup);
target.parentElement.insertBefore(pinDMEntry, target);
pinDMEntry.addEventListener("click", () => {
instance._reactInternalFiber.return.memoizedProps.closeContextMenu();
let dmsscrollerinstance = BDFDB.getReactInstance(document.querySelector(BDFDB.dotCNS.dmchannels + BDFDB.dotCN.scroller));
if (dmsscrollerinstance) {
let dms = dmsscrollerinstance.return.return.return.memoizedProps.children;
let insertpoint = this.getInsertPoint(dms);
this.addPinnedDM(id, dms, insertpoint);
this.forceUpdateScroller(dmsscrollerinstance.stateNode);
2018-11-27 00:15:10 +01:00
}
pinnedDMs[id] = Object.keys(pinnedDMs).length;
BDFDB.saveAllData(pinnedDMs, this, "pinnedDMs");
});
}
else {
let unpinDMEntry = BDFDB.htmlToElement(this.unpinDMEntryMarkup);
target.parentElement.insertBefore(unpinDMEntry, target);
unpinDMEntry.addEventListener("click", () => {
instance._reactInternalFiber.return.memoizedProps.closeContextMenu();
this.removePinnedDM(id);
});
2018-10-11 10:21:26 +02:00
}
}
processLazyScroller (instance, wrapper) {
if (instance._reactInternalFiber && instance._reactInternalFiber.return.memoizedProps && instance._reactInternalFiber.return.memoizedProps.privateChannelIds) {
if (this.forceAdding || !instance.props.PinDMsPatched) {
instance.props.PinDMsPatched = true;
let dms = instance.props.children;
let sortedDMs = this.sortAndUpdate();
if (sortedDMs.length > 0) {
let insertpoint = this.getInsertPoint(dms);
for (let pos in sortedDMs) this.addPinnedDM(sortedDMs[pos], dms, insertpoint);
}
this.forceUpdateScroller(instance.getScrollerNode());
}
if (this.oldScrollerPos != null) {
instance.getScrollerNode().scrollTop = this.oldScrollerPos;
2018-11-29 15:19:09 +01:00
}
2018-10-11 10:21:26 +02:00
}
}
getInsertPoint (dms) {
let insertpoint = null;
for (let i in dms) {
let ele = dms[i];
if (ele && ele.type == "header") {
2018-11-27 00:15:10 +01:00
insertpoint = parseInt(i);
if (!ele.pinned && !ele.props.ispin) {
ele.pinned = true;
let headerpin = Object.assign({},ele);
headerpin.key = "pin" + headerpin.key;
headerpin.props = {children:this.labels.header_pinneddms_text,ispin:true};
dms.splice(insertpoint,0,headerpin);
}
insertpoint++;
break;
}
2018-10-11 10:21:26 +02:00
}
return insertpoint;
2018-10-11 10:21:26 +02:00
}
addPinnedDM (id, dms, insertpoint) {
for (let ele of dms) {
if (ele && !ele.pinned && id == ele.key) {
ele.pinned = true;
let dmpin = Object.assign({ispin:true},ele);
dmpin.key = "pin" + ele.key;
dmpin.props = {channel:ele.props.channel,selected:ele.props.selected,ispin:true};
dms.splice(insertpoint,0,dmpin);
2018-10-11 10:21:26 +02:00
}
}
}
removePinnedDM (id) {
if (!id) return;
BDFDB.removeData(id, this, "pinnedDMs");
let dmsscrollerinstance = BDFDB.getReactInstance(document.querySelector(BDFDB.dotCNS.dmchannels + BDFDB.dotCN.scroller));
if (dmsscrollerinstance) {
let dms = dmsscrollerinstance.return.return.return.memoizedProps.children;
let existingDMs = this.sortAndUpdate();
let removepoint = null;
for (let i in dms) {
let ele = dms[i];
if (ele && ele.pinned && (id == ele.key || ("pin" + id) == ele.key)) {
delete ele.pinned;
if (ele.props.ispin) removepoint = parseInt(i);
}
}
if (removepoint) {
let offset = existingDMs.length ? 0 : 1;
if (offset) delete dms[removepoint + offset].pinned;
dms.splice(removepoint-offset,1+offset);
}
this.forceUpdateScroller(dmsscrollerinstance.stateNode);
2018-10-11 10:21:26 +02:00
}
}
sortAndUpdate () {
let pinnedDMs = BDFDB.loadAllData(this, "pinnedDMs");
delete pinnedDMs[""];
let sortedDMs = [], existingDMs = [], sortDM = (id) => {
2018-12-01 11:07:00 +01:00
if (typeof sortedDMs[pinnedDMs[id]] == "undefined") sortedDMs[pinnedDMs[id]] = id;
else sortDM(sortedDMs, pinnedDMs[id]+1, id);
};
for (let id in pinnedDMs) sortDM(id);
sortedDMs = sortedDMs.filter(n => n);
for (let pos in sortedDMs) {
pinnedDMs[sortedDMs[pos]] = parseInt(pos);
if (this.ChannelUtils.getChannel(sortedDMs[pos])) existingDMs.push(sortedDMs[pos]);
}
BDFDB.saveAllData(pinnedDMs, this, "pinnedDMs");
return existingDMs;
2018-10-11 10:21:26 +02:00
}
forceUpdateScroller (scroller) {
if (this.updatingScroller) return;
this.updatingScroller = true;
var stateNode = BDFDB.getReactValue(scroller, "return.return.return.stateNode");
if (stateNode) stateNode.updater.enqueueForceUpdate(stateNode);
setTimeout(() => {delete this.updatingScroller;},1000);
2018-10-11 10:21:26 +02:00
}
setLabelsByLanguage () {
switch (BDFDB.getDiscordLanguage().id) {
case "hr": //croatian
return {
context_pindm_text: "Prikljucite Izravnu Poruku",
context_unpindm_text: "Otključaj Izravnu Poruku",
header_pinneddms_text: "Prikvačene Izravne Poruke"
2018-10-11 10:21:26 +02:00
};
case "da": //danish
return {
context_pindm_text: "Fastgør PB",
context_unpindm_text: "Frigør PB",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Pinned Privat Beskeder"
};
case "de": //german
return {
context_pindm_text: "Direktnachricht anheften",
context_unpindm_text: "Direktnachricht loslösen",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Gepinnte Direktnachrichten"
};
case "es": //spanish
return {
context_pindm_text: "Anclar MD",
context_unpindm_text: "Desanclar MD",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Mensajes Directos Fijados"
};
case "fr": //french
return {
context_pindm_text: "Épingler MP",
context_unpindm_text: "Désépingler MP",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Messages Prives Épinglés"
};
case "it": //italian
return {
context_pindm_text: "Fissa il messaggio diretto",
context_unpindm_text: "Togli il messaggio diretto",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Messaggi Diretti Aggiunti"
};
case "nl": //dutch
return {
context_pindm_text: "PB pinnen",
context_unpindm_text: "PB losmaken",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Vastgezette Persoonluke Berichten"
};
case "no": //norwegian
return {
context_pindm_text: "Fest DM",
context_unpindm_text: "Løsne DM",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Pinned Direktemeldinger"
};
case "pl": //polish
return {
context_pindm_text: "Przypnij PW",
context_unpindm_text: "Odepnij PW",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Prywatne Wiadomości Bezpośrednie"
};
case "pt-BR": //portuguese (brazil)
return {
context_pindm_text: "Fixar MD",
context_unpindm_text: "Desafixar MD",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Mensagens diretas fixadas"
};
case "fi": //finnish
return {
context_pindm_text: "Kiinnitä yksityisviestit",
context_unpindm_text: "Poista yksityisviestit",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Liitetyt yksityisviestit"
};
case "sv": //swedish
return {
context_pindm_text: "Fäst DM",
context_unpindm_text: "Lossa DM",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Inlagda Direktmeddelanden"
};
case "tr": //turkish
return {
context_pindm_text: "DM'yi Sabitle",
context_unpindm_text: "DM'yi Kaldır",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Direkt Mesajlar Sabitleyin"
};
case "cs": //czech
return {
context_pindm_text: "Připnout PZ",
context_unpindm_text: "Odepnout PZ",
header_pinneddms_text: "Připojené Přímá Zpráva"
2018-10-11 10:21:26 +02:00
};
case "bg": //bulgarian
return {
context_pindm_text: "Закачени ДС",
context_unpindm_text: "Откачи ДС",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Свързани директни съобщения"
};
case "ru": //russian
return {
context_pindm_text: "Закрепить ЛС",
context_unpindm_text: "Открепить ЛС",
header_pinneddms_text: "Прикрепленные Личные Сообщения"
2018-10-11 10:21:26 +02:00
};
case "uk": //ukrainian
return {
context_pindm_text: "Закріпити ОП",
context_unpindm_text: "Відкріпити ОП",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Прикріплені oсобисті повідомлення"
};
case "ja": //japanese
return {
context_pindm_text: "DMピン",
context_unpindm_text: "DMをピン止めする",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "固定された直接メッセージ"
};
case "zh-TW": //chinese (traditional)
return {
context_pindm_text: "引腳直接留言",
context_unpindm_text: "分離直接消息",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "固定私人信息"
};
case "ko": //korean
return {
context_pindm_text: "비공개 메시지 고정",
context_unpindm_text: "비공개 메시지 고정 해제",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "고정 된 비공개 메시지"
};
default: //default: english
return {
context_pindm_text: "Pin DM",
context_unpindm_text: "Unpin DM",
2018-10-11 10:21:26 +02:00
header_pinneddms_text: "Pinned Direct Messages"
};
}
}
}