Ingame notepad
// ==UserScript==
// @name FlatMMO+ Notepad
// @namespace com.dounford.flatmmo.notepad
// @version 1.1.0
// @description Ingame notepad
// @author Dounford
// @license MIT
// @match *://flatmmo.com/play.php*
// @grant none
// @require https://update.greasyfork.org/scripts/544062/FlatMMOPlus.js
// ==/UserScript==
(function() {
'use strict';
class NotepadPlugin extends FlatMMOPlusPlugin {
constructor() {
super("notepad", {
about: {
name: GM_info.script.name,
version: GM_info.script.version,
author: GM_info.script.author,
description: GM_info.script.description
},
});
this.notes = {}
//this.notes = [];
this.userNotes = {};
this.currentTab = '82f91393-49a7-4cda-b080-18763ed21fd3';
this.currentUser = "";
}
onLogin() {
this.notes = JSON.parse(localStorage.getItem("flatNotes")) || {'82f91393-49a7-4cda-b080-18763ed21fd3':{name:"New Tab", content:""}};
this.userNotes = JSON.parse(localStorage.getItem("flatUserNotes")) || {};
this.addStyle();
this.addUI();
this.switchTab(Object.keys(this.notes)[0]);
}
onMessageReceived(data) {
if(data.startsWith("PLAYER_LOOKUP")) {
const space = data.indexOf("~");
const username = data.substring(14, space);
this.currentUser = username;
if(username in this.userNotes) {
document.getElementById("flatNotes-playerNotes").value = this.userNotes[username];
} else {
document.getElementById("flatNotes-playerNotes").value = "";
}
}
}
addStyle() {
const style = document.createElement("style");
style.innerHTML = `
#flatNotes-tabs{
div {
border: black 3px solid;
padding: 3px;
display: inline-flex;
align-items: center;
margin-right: 5px;
gap: 8px;
justify-content: flex-end;
align-items: center;
&:hover {
filter: brightness(75%);
}
span {
outline: none;
}
}
}
.flatNotes-close {
align-self: flex-start;
font-size: 1.3rem;
}
.flatNotes-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
h1 {
margin-top: 0;
}
}
.flatNotes-currentTab {
background-color: var(--fmp-ui-element-active-bg, darkgray);
}
`
document.head.appendChild(style);
}
addUI() {
//Button to open global notes bellow inventory
const openBtn = `<div id="openFlatNotes" onclick="open_modal('flatNotes')" class="bank-btn hover">Open Notepad</div>`;
document.getElementById("bank-all-btn").insertAdjacentHTML("afterend", openBtn);
//Player's notes
const playerTextArea = `<br><textarea id="flatNotes-playerNotes" style="height: 50vh;width: -webkit-fill-available;"></textarea><br>`
document.querySelector("#player-lookup-modal br").insertAdjacentHTML("afterend", playerTextArea)
document.getElementById("flatNotes-playerNotes").onchange = function() {
FlatMMOPlus.plugins.notepad.userNotes[FlatMMOPlus.plugins.notepad.currentUser] = this.value;
FlatMMOPlus.plugins.notepad.saveUserNotes();
}
//Notes
const flatNotes = `<div id="flatNotes" class="modal">
<div class="modal-content modal-content-lg">
<div class="flatNotes-header"">
<h1>Notepad</h1>
<span onclick="FlatMMOPlus.plugins.notepad.closeNotes()" class="close">×</span>
</div>
<div id="flatNotes-tabs" style="display: flex;gap: 5px;">
<button id="flatNotes-newTab" class="hover" onclick="FlatMMOPlus.plugins.notepad.newTab()">+</button>
</div>
<textarea id="flatNotes-textArea" style="width: -webkit-fill-available;height: 500px;"></textarea>
</div>
</div>`
document.getElementById("player-lookup-modal").insertAdjacentHTML("afterend", flatNotes);
document.getElementById("flatNotes-textArea").onchange = function() {
FlatMMOPlus.plugins.notepad.notes[FlatMMOPlus.plugins.notepad.currentTab].content = this.value;
FlatMMOPlus.plugins.notepad.saveNotes();
}
//Create tabs
Object.keys(this.notes).forEach(id=>this.newTab(this.notes[id].name, id));
}
closeNotes() {
document.getElementById("flatNotes").style.display = "none";
}
newTab(name, id) {
id = id || crypto.randomUUID();
if (name === undefined) {
name = "New Tab";
this.notes[id] = {
name,
content: ""
};
}
const tab = document.createElement("div");
const nameSpan = document.createElement("span");
const closeBtn = document.createElement("span");
tab.setAttribute("data-noteid", id);
nameSpan.innerText = name;
nameSpan.contentEditable = "false";
tab.addEventListener("click", function(e) {
if(e.target.className === "close") return;
FlatMMOPlus.plugins.notepad.switchTab(id)
});
tab.addEventListener("contextmenu", function(e) {
e.preventDefault();
const span = this.querySelector("span");
span.contentEditable = true;
span.focus();
});
nameSpan.addEventListener("focusout", function(e) {
this.contentEditable = "false";
FlatMMOPlus.plugins.notepad.renameTab(id)
});
closeBtn.innerText = "×"
closeBtn.className = "flatNotes-close hover";
closeBtn.addEventListener("click", function(e) {
FlatMMOPlus.plugins.notepad.closeTab(id)
});
tab.appendChild(nameSpan);
tab.appendChild(closeBtn);
document.getElementById("flatNotes-newTab").insertAdjacentElement("beforebegin", tab);
this.switchTab(id);
}
closeTab(id) {
const tab = document.querySelector(`[data-noteid="${id}"]`)
tab.remove();
delete this.notes[id];
//At least one tab should always exist
if(Object.keys(this.notes).length === 0) {
this.newTab();
}
if(this.currentTab === id) {
this.switchTab(Object.keys(this.notes)[0]);
}
this.saveNotes();
}
switchTab(id) {
document.querySelector(".flatNotes-currentTab")?.classList.remove("flatNotes-currentTab");
this.currentTab = id;
document.querySelector(`[data-noteid="${id}"]`)?.classList.add("flatNotes-currentTab");
document.getElementById("flatNotes-textArea").value = this.notes[id]?.content || "";
this.saveNotes();
}
renameTab(id) {
const tab = document.querySelector(`[data-noteid="${id}"] span`);
this.notes[id].name = tab?.innerText || "New Tab";
this.saveNotes();
}
saveNotes() {
localStorage.setItem("flatNotes", JSON.stringify(this.notes));
}
saveUserNotes() {
localStorage.setItem("flatUserNotes", JSON.stringify(this.userNotes));
}
}
const plugin = new NotepadPlugin();
FlatMMOPlus.registerPlugin(plugin);
})();