//META{"name":"PersonalPins"}*//
class PersonalPins {
initConstructor () {
this.labels = {};
this.messageContextEntryMarkup =
`
`;
this.notesButton =
``;
this.notesPopoutMarkup =
`
`;
this.popoutEntryMarkup =
`
`;
this.messageMarkupCozy =
`
`;
}
getName () {return "PersonalPins";}
getDescription () {return "Similar to normal pins. Lets you save messages as notes for yourself.";}
getVersion () {return "1.6.1";}
getAuthor () {return "DevilBro";}
getSettingsPanel () {
if (!this.started || typeof BDFDB !== "object") return;
var settingshtml = `
${this.getName()}
`;
settingshtml += `
`;
settingshtml += `
`;
var settingspanel = $(settingshtml)[0];
BDFDB.initElements(settingspanel);
$(settingspanel)
.on("click", ".reset-button", () => {this.resetAll();});
return settingspanel;
}
//legacy
load () {}
start () {
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();});
}
initialize () {
if (typeof BDFDB === "object") {
BDFDB.loadMessage(this);
this.GuildStore = BDFDB.WebModules.findByProperties(["getGuild"]);
this.ChannelStore = BDFDB.WebModules.findByProperties(["getChannel"]);
this.UserStore = BDFDB.WebModules.findByProperties(["getUser"]);
this.MemberStore = BDFDB.WebModules.findByProperties(["getMember"]);
this.IconUtils = BDFDB.WebModules.findByProperties(["getUserAvatarURL"]);
this.HistoryUtils = BDFDB.WebModules.findByProperties(["transitionTo", "replaceWith", "getHistory"]);
this.MainDiscord = BDFDB.WebModules.findByProperties(["ActionTypes"]);
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-personalpins")) {
$(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.getName(), BDFDB.dotCN.optionpopoutbutton).off("contextmenu." + this.getName(), BDFDB.dotCN.message)
.on("click." + this.getName(), BDFDB.dotCN.optionpopoutbutton, (e) => {
this.getMessageData($(BDFDB.dotCN.message).has(e.currentTarget)[0]);
})
.on("contextmenu." + this.getName(), BDFDB.dotCN.message, (e) => {
this.getMessageData(e.currentTarget);
});
document.querySelectorAll(BDFDB.dotCNS.messagegroup + BDFDB.dotCN.message).forEach(message => {this.addOptionButton(message);});
this.addNotesButton();
}
else {
console.error(this.getName() + ": Fatal Error: Could not load BD functions!");
}
}
stop () {
if (typeof BDFDB === "object") {
$(document).off("click." + this.getName(), BDFDB.dotCN.optionpopoutbutton).off("contextmenu." + this.getName(), BDFDB.dotCN.message);
$(".btn-personalpins, .notesButton").remove();
BDFDB.unloadMessage(this);
}
}
onSwitch () {
if (typeof BDFDB === "object") {
BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver"}, {childList:true, subtree:true});
document.querySelectorAll(BDFDB.dotCNS.messages + BDFDB.dotCN.message).forEach(message => {this.addOptionButton(message);});
setTimeout(() => {
this.addNotesButton();
},1);
}
}
// begin of own functions
resetAll () {
if (confirm("Are you sure you want to delete all pinned notes?")) {
BDFDB.removeAllData(this, "pins");
}
}
changeLanguageStrings () {
this.messageContextEntryMarkup = this.messageContextEntryMarkup.replace("REPLACE_context_noteoption_text", this.labels.context_noteoption_text);
this.notesPopoutMarkup = this.notesPopoutMarkup.replace("REPLACE_popout_note_text", this.labels.popout_note_text);
this.notesPopoutMarkup = this.notesPopoutMarkup.replace("REPLACE_popout_channel_text", this.labels.popout_channel_text);
this.notesPopoutMarkup = this.notesPopoutMarkup.replace("REPLACE_popout_server_text", this.labels.popout_server_text);
this.notesPopoutMarkup = this.notesPopoutMarkup.replace("REPLACE_popout_allservers_text", this.labels.popout_allservers_text);
this.notesPopoutMarkup = this.notesPopoutMarkup.replace("REPLACE_popout_sort_text", this.labels.popout_sort_text);
this.notesPopoutMarkup = this.notesPopoutMarkup.replace("REPLACE_popout_messagesort_text", this.labels.popout_messagesort_text);
this.messageMarkupCozy = this.messageMarkupCozy.replace("REPLACE_popout_jump_text", this.labels.popout_jump_text);
this.messageMarkupCozy = this.messageMarkupCozy.replace("REPLACE_popout_copy_text", this.labels.popout_copy_text);
this.sortPopoutMarkup = this.sortPopoutMarkup.replace("REPLACE_popout_messagesort_text", this.labels.popout_messagesort_text);
this.sortPopoutMarkup = this.sortPopoutMarkup.replace("REPLACE_popout_datesort_text", this.labels.popout_datesort_text);
this.popoutEntryMarkup = this.popoutEntryMarkup.replace("REPLACE_popout_noteoption_text", this.labels.popout_noteoption_text);
}
onContextMenu (context) {
if (!context || !context.tagName || !context.parentElement || context.querySelector(".personalpin-item")) return;
for (let group of context.querySelectorAll(BDFDB.dotCN.contextmenuitemgroup)) {
if (BDFDB.getKeyInformation({"node":group, "key":"displayName", "value":"MessagePinItem"})) {
$(this.messageContextEntryMarkup).insertAfter(group)
.on("click", ".personalpin-item", () => {
$(context).hide();
this.addMessageToNotes();
});
BDFDB.updateContextPosition(context);
break;
}
}
}
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) {
if (div && !div.querySelector(BDFDB.dotCN.messagesystem)) {
var messagegroup = this.getMessageGroup(div);
var pos = Array.from(messagegroup.querySelectorAll(BDFDB.dotCN.message)).indexOf(div);
var instance = BDFDB.getReactInstance(messagegroup);
if (!instance) return;
var info = instance.return.stateNode.props.messages;
if (info && pos > -1) this.message = Object.assign({},info[pos],{"div":div, "group":messagegroup, "pos":pos});
}
else {
this.message = null;
}
}
addNotesButton () {
$(".notesButton").remove();
$(this.notesButton)
.insertBefore(BDFDB.dotCNS.channelheadertitle + BDFDB.dotCN.channelheadersearch)
.on("click." + this.getName(), (e) => {
this.openNotesPopout(e);
})
.on("mouseenter." + this.getName(), (e) => {
BDFDB.createTooltip(this.labels.popout_note_text, e.currentTarget, {type:"bottom",selector:"note-button-tooltip"});
});
}
addOptionButton (message) {
if (!message.querySelector(BDFDB.dotCN.optionpopoutbutton) && !message.querySelector(BDFDB.dotCN.messagesystem) && !message.querySelector(BDFDB.dotCN.messageuploadcancel)) {
$(this.optionButtonMarkup).appendTo(message.querySelector(BDFDB.dotCN.messagebuttoncontainer));
$(message).off("click." + this.getName()).on("click." + this.getName(), ".btn-personalpins", (e) => {
this.openOptionPopout(e);
});
}
}
openNotesPopout (e) {
var wrapper = e.currentTarget;
if (wrapper.classList.contains("popout-open")) return;
wrapper.classList.add("popout-open");
var popout = $(this.notesPopoutMarkup);
BDFDB.initElements(popout);
var wrappersize = wrapper.getBoundingClientRect();
popout
.appendTo(BDFDB.dotCN.popouts)
.css("left", wrappersize.width/2 + wrappersize.left + "px")
.css("top", wrappersize.height + wrappersize.top + "px")
.on("click", ".tab:not(.selected)", () => {
this.addNotes(popout[0]);
})
.on("keyup." + this.getName(), BDFDB.dotCN.searchbarinput, () => {
clearTimeout(popout.searchTimeout);
popout.searchTimeout = setTimeout(() => {this.addNotes(popout[0]);},1000);
})
.on("click." + this.getName(), BDFDB.dotCN.searchbarclear + BDFDB.dotCN.searchbarvisible, () => {
clearTimeout(popout.searchTimeout);
popout.searchTimeout = setTimeout(() => {this.addNotes(popout[0]);},1000);
})
.on("click", BDFDB.dotCN.quickselectclick, (e2) => {
this.openSortPopout(e2, popout[0]);
});
$(document).on("mousedown.notepopout" + this.getName(), (e2) => {
if (popout.has(e2.target).length == 0 && $(".personalpins-sort-popout").has(e2.target).length == 0) {
$(document).off("mousedown.notepopout" + this.getName());
popout.remove();
setTimeout(() => {wrapper.classList.remove("popout-open");},300);
}
});
this.addNotes(popout[0]);
}
openSortPopout (e, notespopout) {
var wrapper = e.currentTarget;
if (wrapper.classList.contains("popout-open")) return;
wrapper.classList.add("popout-open");
var value = $(wrapper).find(BDFDB.dotCN.quickselectvalue);
var popout = $(this.sortPopoutMarkup);
$(BDFDB.dotCN.popouts).append(popout)
.off("click", BDFDB.dotCN.contextmenuitem)
.on("click", BDFDB.dotCN.contextmenuitem, (e2) => {
value.text($(e2.currentTarget).text());
value.attr("option", $(e2.currentTarget).attr("option"));
$(document).off("mousedown.sortpopout" + this.getName());
popout.remove();
setTimeout(() => {wrapper.classList.remove("popout-open");},300);
this.addNotes(notespopout);
});
popout
.css("left", $(e.currentTarget).offset().left + $(e.currentTarget).outerWidth() + "px")
.css("top", $(e.currentTarget).offset().top + value.outerHeight() + "px")
.find(BDFDB.dotCN.contextmenu).addClass(BDFDB.getDiscordTheme());
$(document).on("mousedown.sortpopout" + this.getName(), (e2) => {
if (popout.has(e2.target).length == 0) {
$(document).off("mousedown.sortpopout" + this.getName());
popout.remove();
setTimeout(() => {wrapper.classList.remove("popout-open");},300);
}
});
}
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.getName(), (e2) => {
if (popout.has(e2.target).length == 0) {
$(document).off("mousedown.optionpopout" + this.getName());
popout.remove();
setTimeout(() => {wrapper.classList.remove(BDFDB.disCN.optionpopoutopen);},300);
}
});
}
addClickListener (popout) {
$(popout)
.off("click." + this.getName(), ".btn-item-personalpins")
.on("click." + this.getName(), ".btn-item-personalpins", (e) => {
$(BDFDB.dotCN.popout).has(BDFDB.dotCN.optionpopout).hide();
this.addMessageToNotes();
var popoutbutton = document.querySelector(BDFDB.dotCN.optionpopoutbutton + BDFDB.dotCN.optionpopoutopen);
if (popoutbutton) popoutbutton.classList.remove(BDFDB.disCN.optionpopoutopen);
});
}
addMessageToNotes () {
if (!this.message) return;
var channelObj = BDFDB.getSelectedChannel();
var serverObj = BDFDB.getSelectedServer() || {};
if (this.message && channelObj) {
var author = this.message.author;
var channelID = channelObj.id;
var serverID = serverObj.id ? serverObj.id : "@me";
var pins = BDFDB.loadAllData(this, "pins");
pins[serverID] = pins[serverID] ? pins[serverID] : {}
pins[serverID][channelID] = pins[serverID][channelID] ? pins[serverID][channelID] : {}
var messageID = this.message.id;
var position = this.message.pos;
var channelname = channelObj.name;
if (!channelname && channelObj.recipients.length > 0) {
for (let dmmemberID of channelObj.recipients) {
channelname = channelname ? channelname + ", @" : channelname;
channelname = channelname + this.UserStore.getUser(dmmemberID).username;
}
}
var markup = this.message.div.querySelector(BDFDB.dotCN.messagemarkup).cloneNode(true);
markup.querySelectorAll(BDFDB.dotCN.messageheadercompact).forEach(h2 => {h2.remove();});
var message = {
"serverID": serverID,
"serverName": serverObj.name ? serverObj.name : "Direct Messages",
"channelID": channelID,
"channelName": channelname,
"id": messageID,
"pos": position,
"timestamp": this.message.timestamp._i.getTime(),
"addedat": new Date().getTime(),
"color": this.message.colorString,
"authorID": author.id,
"authorName": author.username,
"avatar": this.IconUtils.getUserAvatarURL(author),
"content": this.message.content,
"markup": markup.innerHTML,
"accessory": this.message.div.querySelector(BDFDB.dotCN.messageaccessory).innerHTML
};
pins[serverID][channelID][messageID + "_" + position] = message;
BDFDB.saveAllData(pins, this, "pins");
BDFDB.showToast(this.labels.toast_noteadd_text, {type:"success"});
}
this.message = null;
}
addNotes (notespopout) {
notespopout.querySelectorAll(BDFDB.dotCN.messagegroupwrapper).forEach(message => {message.remove();});
var channelObj = BDFDB.getSelectedChannel();
if (channelObj) {
var serverID = channelObj.guild_id ? channelObj.guild_id : "@me";
var channelID = channelObj.id;
var pins = BDFDB.loadAllData(this, "pins");
if (!BDFDB.isObjectEmpty(pins)) {
var language = BDFDB.getDiscordLanguage().id;
var container = notespopout.querySelector(BDFDB.dotCN.messagespopout);
var placeholder = notespopout.querySelector(BDFDB.dotCN.messagespopoutemptyplaceholder);
var messages = {};
switch (notespopout.querySelector(".tab.selected").getAttribute("tab")) {
case "channel":
messages = pins[serverID] && pins[serverID][channelID] ? pins[serverID][channelID] : {};
break;
case "server":
if (pins[serverID]) for (let channel in pins[serverID]) messages = Object.assign(messages, pins[serverID][channel]);
break;
case "allservers":
for (let server in pins) if (pins[server]) for (let channel in pins[server]) messages = Object.assign(messages, pins[server][channel]);
break;
}
var messageArray = [];
for (var id in messages) {
messageArray.push(messages[id]);
}
BDFDB.sortArrayByKey(messageArray, notespopout.querySelector(BDFDB.dotCN.quickselectvalue).getAttribute("option"));
var compact = BDFDB.getDiscordMode == "compact";
for (let messageData of messageArray) {
let message = $(this.messageMarkupCozy)[0];
let server = this.GuildStore.getGuild(messageData.serverID);
let channel = this.ChannelStore.getChannel(messageData.channelID);
let user = this.UserStore.getUser(messageData.authorID);
let member = this.MemberStore.getMember(messageData.serverID, messageData.authorID);
let date = new Date(messageData.timestamp);
container.insertBefore(message, container.firstChild);
message.querySelector(BDFDB.dotCN.avatarimage).style.backgroundImage =
user ? "url(" + this.IconUtils.getUserAvatarURL(user) + ")" : "url(" + messageData.avatar + ")";
message.querySelector(BDFDB.dotCN.messageusername).innerText = user ? user.username : messageData.authorName;
message.querySelector(BDFDB.dotCN.messageusername).style.color = member ? member.colorString : messageData.color;
message.querySelector(compact ? BDFDB.dotCN.messagetimestampcompact : BDFDB.dotCN.messagetimestampcozy).innerText = date.toLocaleString(language);
message.querySelector(".server-channel").innerText =
(server && server.name ? server.name : messageData.serverName) +
(messageData.serverID == "@me" ? " @" : " #") +
(channel && channel.name ? channel.name : messageData.channelName);
message.querySelector(BDFDB.dotCN.messagemarkup).innerHTML = messageData.markup;
message.querySelector(BDFDB.dotCN.messageaccessory).innerHTML = messageData.accessory;
if (messageData.accessory) {
let ytvideo = message.querySelector(BDFDB.dotCN.embed + " iframe[src*='https://www.youtube.com']");
if (ytvideo) {
let ytlink = ytvideo.parentElement.parentElement.querySelector(BDFDB.dotCN.embedtitle).href;
let wrapper = ytvideo.parentElement;
ytvideo.remove();
require("request")(ytlink, (error, response, result) => {
if (result) {
wrapper.innerHTML = `
`;
$(wrapper).on("click." + this.getName(), BDFDB.dotCN.iconplay, (e) => {
while (wrapper.firstChild) wrapper.firstChild.remove();
let width = 400;
let height = Math.round(width*(result.split('