Greasy Fork 支持简体中文。

hipda-ID笔记

来自地板带着爱,记录上网冲浪的美好瞬间

目前為 2021-12-07 提交的版本,檢視 最新版本

// ==UserScript==
// @name         hipda-ID笔记
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  来自地板带着爱,记录上网冲浪的美好瞬间
// @author       屋大维
// @license      MIT
// @match        https://www.hi-pda.com/forum/viewthread.php?tid*
// @resource     IMPORTED_CSS https://code.jquery.com/ui/1.13.0/themes/base/jquery-ui.css
// @require      https://code.jquery.com/jquery-3.4.1.min.js
// @require      https://code.jquery.com/ui/1.13.0/jquery-ui.js
// @icon         https://icons.iconarchive.com/icons/iconshock/real-vista-project-managment/64/task-notes-icon.png
// @grant        GM.setValue
// @grant        GM.getValue
// @grant        GM.deleteValue
// @grant        GM_getResourceText
// @grant        GM_addStyle
// ==/UserScript==

(async function() {
    'use strict';
    // CSS
    const my_css = GM_getResourceText("IMPORTED_CSS");
    GM_addStyle(my_css);
    GM_addStyle(".no-close .ui-dialog-titlebar-close{display:none} textarea{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}");

    // Your code here...
    class Notebook {
        constructor(user_uid) {
            // initialization
            this._name = "hipda-notebook";
            this._user_uid = user_uid;
            this._notebook = {};
            return (async () => {
                this.loadFromLocalStorage();
                return this;
            })();
        }

        async loadFromLocalStorage() {
            console.log("load ID Notebook from Local Storage");
            let data = await GM.getValue(this._name, null);
            if (data !== null) {
                this._notebook = JSON.parse(data);
            }
            console.log("loaded");
        }

        async saveToLocalStorage() {
            console.log("save ID Notebook to Local Storage");
            await GM.setValue(this._name, JSON.stringify(this._notebook));
        }

        put(uid, userName, note) {
            // we need userName here, so user can analyze notes even after export
            this._notebook[uid] = {uid, userName, note};
            this.saveToLocalStorage();
        }

        get(uid) {
            if (uid in this._notebook) {
                return this._notebook[uid].note;
            }
            return "";
        }

        delete(uid) {
            if (uid in this._notebook) {
                delete this._notebook[uid];
                this.saveToLocalStorage();
            }
        }

        exportNotebook() {
            // can add meta data here
            let output = {
                notebook: this._notebook,
                version: "0.1",
                timestamp: + new Date()
            };
            return JSON.stringify(output);
        }

        importNotebook(input) {
            let attrs = ['notebook', 'version', 'timestamp'];
            for (let i=0; i<attrs.legnth; i++) {
                if (!(attrs[i] in input)) {
                    throw(`bad format: ${attrs[i]} does not exist`);
                }
            }
            this._notebook = {...input.notebook};
            this.saveToLocalStorage();
        }

        resetNotebook() {
            this._notebook = {};
            this.saveToLocalStorage();
        }

        renderManagementUI() {
            var that = this;
            var button = htmlToElement(`
              <button id="noteButton_management">
                <span><img src="https://icons.iconarchive.com/icons/iconshock/real-vista-project-managment/32/task-notes-icon.png"></img></span>
              </button>
            `);

            // create dialog
            let dialog = htmlToElement(`
              <div id="noteDialog_management" style="display: none;">
                <h3>hipda-ID笔记 v0.1</h3>
                <p style="margin: 10px auto 10px auto;">来自地板带着爱</p>
                <div>
                  <button id="noteButton_import">导入</button>
                  <button id="noteButton_export">导出</button>
                  <button id="noteButton_reset">重置</button>
                </div>
              </div>
            `);
            $("body").append(dialog);

            $(document).ready( function () {
                $(document).on ("click", "#noteButton_import", function() {
                    let r = confirm("确定要导入ID笔记吗?现有笔记将会被覆盖!");
                    if (!r) {
                      return;
                    }

                    // prompt cannot handle large file, extend it in the future
                    let data = prompt("请将 id笔记.json 中的文本复制粘贴入文本框:");
                    if (data !== null) {
                        // try to load
                        try {
                            let j = JSON.parse(data);
                            that.importNotebook(j);
                        } catch(err) {
                            alert("格式错误!" + err);
                            return;
                        }
                        alert("导入成功!");
                    }
                });
                $(document).on ("click", "#noteButton_export", function() {
                    let r = confirm("确定要导出ID笔记吗?");
                    if (!r) {
                        return;
                    }
                    let a = document.createElement("a");
                    a.href = "data:text," + that.exportNotebook();
                    a.download = "id笔记.json";
                    a.click();
                });
                $(document).on ("click", "#noteButton_reset", function() {
                    let r = confirm("确定要清空ID笔记吗?");
                    if (!r) {
                        return;
                    }
                    that.resetNotebook();
                    alert("ID笔记已经清空!");
                });
                $(document).on ("click", `#noteButton_management`, function () {
                    console.log("open notebook management dialog");
                    $(`#noteDialog_management`).dialog({
                        title: "ID笔记:管理面板",
                        height: 150,
                        width: 300,
                        closeOnEscape: true,
                    });
                });
            });
            return button;
        }

        renderUI(uid, index, userName) {
            var that = this;
            // create an UI element which contains data and hooks
            // button
            let button = htmlToElement(`
              <button id="noteButton_${index}" style="color:grey; margin-left:20px;">
                ID笔记
              </button>
            `);
            // note dialog
            let dialog = htmlToElement(`
              <div id="noteDialog_${index}" style="display: none;">
                <textarea rows="10" wrap="hard" placeholder="暂时没有笔记">
              </div>
            `);
            $("body").append(dialog);

            // add event to button
            $(document).ready( function () {
                $(document).on ("click", `#noteButton_${index}`, function () {
                    console.log("open note for", userName);
                    // freshly fetched from DB
                    $(`#noteDialog_${index}`).find('textarea').first().val(that.get(uid));
                    $(`#noteDialog_${index}`).dialog({
                        title: `ID笔记:${userName}`,
                        dialogClass: "no-close",
                        closeText: "hide",
                        closeOnEscape: true,
                        height: 350,
                        width: 600,
                        buttons: [
                            {
                                text: "确认",
                                click: function() {
                                    // save the new note before close
                                    let newNote = $(`#noteDialog_${index}`).find('textarea').first().val();
                                    that.put(uid, userName, newNote);
                                    $(this).dialog( "close" );
                                }
                            },
                            {
                                text: "取消",
                                click: function() {
                                    // close without saving
                                    $(this).dialog( "close" );
                                }
                            }
                        ]
                    });
                });
            });

            return button;

        }
    }

    // helpers
    function htmlToElement(html) {
        var template = document.createElement('template');
        html = html.trim(); // Never return a text node of whitespace as the result
        template.innerHTML = html;
        return template.content.firstChild;
    }

    // get tid and uid; uid for future extension
    var tid = location.href.match(/tid=(\d+)/) ? parseInt(location.href.match(/tid=(\d+)/)[1]) : -999;
    var uid = parseInt($("cite > a").attr("href").split("uid=")[1]);

    var notebook = await new Notebook(uid);

    // render UI below
    $("td.modaction").last().append(notebook.renderManagementUI());

    $("td[rowspan='2'].postauthor").each((index, element) => {
        let uid = parseInt($(element).find("a").first().attr("href").split("uid=")[1]);
        let userName = $(element).find("a").first().text();
        element.appendChild(notebook.renderUI(uid, index, userName));
    });


})();