FlatMMO+ Notepad

Ingame notepad

Terá de instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Terá de instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Terá de instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Terá de instalar uma extensão como Tampermonkey para instalar este script.

Terá de instalar uma extensão de gestão de scripts de utilizador para instalar este script.

(Já tenho um gestor de scripts de utilizador, deixe-me instalá-lo!)

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

(Já tenho um gestor de estilos de utilizador, deixe-me instalá-lo!)

// ==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);
 
})();