diff --git a/Plugins/LastMessageData/LastMessageDate.plugin.js b/Plugins/LastMessageData/LastMessageDate.plugin.js
new file mode 100644
index 0000000000..281accc167
--- /dev/null
+++ b/Plugins/LastMessageData/LastMessageDate.plugin.js
@@ -0,0 +1,325 @@
+//META{"name":"LastMessageDate","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/LastMessageDate","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/LastMessageDate/LastMessageDate.plugin.js"}*//
+
+class LastMessageDate {
+ getName () {return "LastMessageDate";}
+
+ getVersion () {return "1.0.0";}
+
+ getAuthor () {return "DevilBro";}
+
+ getDescription () {return "Displays the Date of the last sent Message of a Member for the current Server in the UserPopout and UserModal.";}
+
+ initConstructor () {
+ this.labels = {};
+
+ this.patchModules = {
+ "UserPopout":"componentDidMount",
+ "UserProfile":"componentDidMount"
+ };
+
+ this.languages;
+
+ this.loadedusers = {};
+
+ this.css = `
+ ${BDFDB.dotCNS.userpopout + BDFDB.dotCN.nametag} {
+ margin-bottom: 4px;
+ }
+ ${BDFDB.dotCN.userprofile} .lastMessageDate {
+ margin-right: 20px;
+ }
+ ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userpopoutheadernormal} .lastMessageDate {
+ color: #b9bbbe;
+ }
+ ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userpopoutheader + BDFDB.notCN.userpopoutheadernormal} .lastMessageDate,
+ ${BDFDB.dotCNS.themedark + BDFDB.dotCN.userpopoutheader} .lastMessageDate {
+ color: hsla(0,0%,100%,.6);
+ }
+ ${BDFDB.dotCNS.themelight + BDFDB.dotCN.userprofiletopsectionnormal} .lastMessageDate {
+ color: hsla(216,4%,74%,.6);
+ }
+ ${BDFDB.dotCN.themelight} [class*='topSection']${BDFDB.notCN.userprofiletopsectionnormal} .lastMessageDate,
+ ${BDFDB.dotCN.themedark} [class*='topSection'] .lastMessageDate {
+ color: hsla(0,0%,100%,.6);
+ }`;
+
+
+ this.defaults = {
+ settings: {
+ addInUserPopout: {value:true, description:"Add in User Popouts:"},
+ addInUserProfil: {value:true, description:"Add in User Profil Modal:"},
+ addJoinedAtTime: {value:true, description:"Display the Time when the User Joined:"},
+ forceZeros: {value:false, description:"Force leading Zeros:"}
+ },
+ choices: {
+ lastMessageDateLang: {value:"$discord", description:"Joined At Date Format:"}
+ }
+ };
+ }
+
+ getSettingsPanel () {
+ 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 += `
`;
+ }
+ for (let key in choices) {
+ settingshtml += `
${this.defaults.choices[key].description}
${this.languages[choices[key]].name}
${this.getLastMessageTime(this.languages[choices[key]].id)}
`;
+ }
+ settingshtml += `
`;
+
+ let settingspanel = BDFDB.htmlToElement(settingshtml);
+
+ 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.getLastMessageTime(this.languages[choices[key]].id);
+ });
+ BDFDB.addEventListener(this, settingspanel, "click", BDFDB.dotCN.selectcontrol, e => {this.openDropdownMenu(e);});
+ return settingspanel;
+ }
+
+ //legacy
+ load () {}
+
+ start () {
+ if (!global.BDFDB) global.BDFDB = {myPlugins:{}};
+ if (global.BDFDB && global.BDFDB.myPlugins && typeof global.BDFDB.myPlugins == "object") global.BDFDB.myPlugins[this.getName()] = this;
+ 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", () => {if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) 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) {
+ if (this.started) return;
+ BDFDB.loadMessage(this);
+
+ this.CurrentGuildStore = BDFDB.WebModules.findByProperties("getLastSelectedGuildId");
+ this.APIModule = BDFDB.WebModules.findByProperties("getAPIBaseURL");
+ this.DiscordConstants = BDFDB.WebModules.findByProperties("Permissions", "ActivityTypes", "StatusTypes");
+
+ this.languages = Object.assign({},BDFDB.languages);
+
+ BDFDB.WebModules.forceAllUpdates(this);
+ }
+ else {
+ console.error(`%c[${this.getName()}]%c`, 'color: #3a71c1; font-weight: 700;', '', 'Fatal Error: Could not load BD functions!');
+ }
+ }
+
+
+ stop () {
+ if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
+ BDFDB.removeEles(".lastMessageDate");
+ BDFDB.unloadMessage(this);
+ }
+ }
+
+
+ // begin of own functions
+
+ openDropdownMenu (e) {
+ let selectControl = e.currentTarget;
+ let selectWrap = selectControl.parentElement;
+ let plugincard = BDFDB.getParentEle("li", selectWrap);
+
+ if (!plugincard || BDFDB.containsClass(selectWrap, BDFDB.disCN.selectisopen)) return;
+
+ BDFDB.addClass(selectWrap, BDFDB.disCN.selectisopen);
+ plugincard.style.setProperty("overflow", "visible", "important");
+
+ let type = selectWrap.getAttribute("type");
+ let selectMenu = this.createDropdownMenu(selectWrap.getAttribute("value"), type);
+ selectWrap.appendChild(selectMenu);
+
+ 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.getLastMessageTime(language);
+ BDFDB.saveData(type, language, this, "choices");
+ });
+
+ 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) {
+ let menuhtml = ``;
+ return BDFDB.htmlToElement(menuhtml);
+ }
+
+ processUserPopout (instance, wrapper) {
+ if (instance.props && instance.props.user && BDFDB.getData("addInUserPopout", this, "settings")) {
+ this.addLastMessageDate(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.addLastMessageDate(instance.props.user, wrapper.querySelector(BDFDB.dotCN.userprofileheaderinfo), null);
+ }
+ }
+
+ addLastMessageDate (info, container, popout) {
+ if (!info || !container || container.querySelector(".lastMessageDate")) return;
+ let guildid = this.CurrentGuildStore.getGuildId();
+ if (guildid) {
+ if (!this.loadedusers[guildid]) this.loadedusers[guildid] = {};
+ let timestamp, addTimestamp = (timestamp) => {
+ if (document.contains(container)) {
+ let choice = BDFDB.getData("lastMessageDateLang", this, "choices");
+ let nametag = container.querySelector(BDFDB.dotCN.nametag);
+ let joinedAtDate = container.querySelector(".joinedAtDate");
+ container.insertBefore(BDFDB.htmlToElement(`${this.labels.lastmessage_text + " " + this.getLastMessageTime(this.languages[choice].id, timestamp)}
`), 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");
+ }
+ }
+ };
+ if (this.loadedusers[guildid][info.id]) addTimestamp(this.loadedusers[guildid][info.id]);
+ else this.APIModule.get(this.DiscordConstants.Endpoints.SEARCH_GUILD(guildid) + "?author_id=" + info.id).then(result => {
+ if (result && result.body) for (let message of result.body.messages[0]) if (message.hit && message.author.id == info.id) {
+ timestamp = new Date(message.timestamp);
+ this.loadedusers[guildid][info.id] = timestamp;
+ addTimestamp(timestamp);
+ }
+ });
+ }
+ }
+
+ getLastMessageTime (languageid, timestamp = new Date()) {
+ let settings = BDFDB.getAllData(this, "settings");
+ let timestring = settings.addJoinedAtTime ? timestamp.toLocaleString(languageid) : timestamp.toLocaleDateString(languageid);
+ if (timestring && settings.forceZeros) timestring = this.addLeadingZeros(timestring);
+ return timestring;
+ }
+
+ addLeadingZeros (timestring) {
+ 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("");
+ }
+
+ setLabelsByLanguage () {
+ switch (BDFDB.getDiscordLanguage().id) {
+ case "hr": //croatian
+ return {
+ lastmessage_text: "Posljednja poruka dana"
+ };
+ case "da": //danish
+ return {
+ lastmessage_text: "Sidste besked den"
+ };
+ case "de": //german
+ return {
+ lastmessage_text: "Letzte Nachricht am"
+ };
+ case "es": //spanish
+ return {
+ lastmessage_text: "Último mensaje el"
+ };
+ case "fr": //french
+ return {
+ lastmessage_text: "Dernier message le"
+ };
+ case "it": //italian
+ return {
+ lastmessage_text: "Ultimo messaggio il"
+ };
+ case "nl": //dutch
+ return {
+ lastmessage_text: "Laatste bericht op"
+ };
+ case "no": //norwegian
+ return {
+ lastmessage_text: "Siste melding på"
+ };
+ case "pl": //polish
+ return {
+ lastmessage_text: "Ostatnia wiadomość z"
+ };
+ case "pt-BR": //portuguese (brazil)
+ return {
+ lastmessage_text: "Última mensagem em"
+ };
+ case "fi": //finnish
+ return {
+ lastmessage_text: "Viimeisin viesti"
+ };
+ case "sv": //swedish
+ return {
+ lastmessage_text: "Senaste meddelandet den"
+ };
+ case "tr": //turkish
+ return {
+ lastmessage_text: "Son mesajı"
+ };
+ case "cs": //czech
+ return {
+ lastmessage_text: "Poslední zpráva dne"
+ };
+ case "bg": //bulgarian
+ return {
+ lastmessage_text: "Последно съобщение на"
+ };
+ case "ru": //russian
+ return {
+ lastmessage_text: "Последнее сообщение"
+ };
+ case "uk": //ukrainian
+ return {
+ lastmessage_text: "Останнє повідомлення"
+ };
+ case "ja": //japanese
+ return {
+ lastmessage_text: "最後のメッセージ"
+ };
+ case "zh-TW": //chinese (traditional)
+ return {
+ lastmessage_text: "最後消息於"
+ };
+ case "ko": //korean
+ return {
+ lastmessage_text: "마지막 메시지"
+ };
+ default: //default: english
+ return {
+ lastmessage_text: "Last message on"
+ };
+ }
+ }
+}
diff --git a/Plugins/LastMessageData/README.md b/Plugins/LastMessageData/README.md
new file mode 100644
index 0000000000..8f7512a7dd
--- /dev/null
+++ b/Plugins/LastMessageData/README.md
@@ -0,0 +1,3 @@
+# Last Message Date - [Download](https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/LastMessageDate/LastMessageDate.plugin.js)
+
+Displays the Date of the last sent Message of a Member for the current Server in the UserPopout and UserModal.
diff --git a/Plugins/PluginRepo/res/PluginList.txt b/Plugins/PluginRepo/res/PluginList.txt
index 95070e0fb1..baa3dcd5a3 100644
--- a/Plugins/PluginRepo/res/PluginList.txt
+++ b/Plugins/PluginRepo/res/PluginList.txt
@@ -130,6 +130,7 @@ https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/G
https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/GoogleTranslateOption/GoogleTranslateOption.plugin.js
https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/ImageGallery/ImageGallery.plugin.js
https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/JoinedAtDate/JoinedAtDate.plugin.js
+https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/LastMessageDate/LastMessageDate.plugin.js
https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/MessageUtilities/MessageUtilities.plugin.js
https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/MoveablePopups/MoveablePopups.plugin.js
https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/NotificationSounds/NotificationSounds.plugin.js
diff --git a/Plugins/README.md b/Plugins/README.md
index c9faf78694..2a80812b6a 100644
--- a/Plugins/README.md
+++ b/Plugins/README.md
@@ -19,6 +19,7 @@
- [Google Translate Option](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/GoogleTranslateOption) - Adds a Google Translate option to your context menu, which will open the selected text in Google Translate.
- [Image Gallery](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ImageGallery) - Allows the user to browse through images sent inside the same message.
- [Joined At Date](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/JoinedAtDate) - Displays the Joined At Date of a Member in the UserPopout and UserModal.
+ - [Last Message Date](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/LastMessageDate) - Displays the Date of the last sent Message of a Member for the current Server in the UserPopout and UserModal.
- [Message Utilities](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/MessageUtilities) - Offers a number of useful message options.
- [Moveable Popups](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/MoveablePopups) - Adds the feature to move all popups and modals around like on a normal desktop. Ctrl + drag with your left mousebutton to drag element.
- [Notification Sounds](https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/NotificationSounds) - Allows you to replace the native sounds of Discord with your own.