您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A simple, persistent notepad and to-do list in a slide-out panel for Torn PDA.
// ==UserScript== // @name BJ's Torn PDA - Notes & To-Do List // @namespace http://tampermonkey.net/ // @version 1.0 // @description A simple, persistent notepad and to-do list in a slide-out panel for Torn PDA. // @author BazookaJoe // @match https://www.torn.com/* // @require https://code.jquery.com/jquery-3.7.1.min.js // ==/UserScript== /* globals jQuery, $ */ (function() { 'use-strict'; // --- 1. CONFIGURATION & STORAGE KEYS --- const STORAGE_KEYS = { PANEL_OPEN: 'pda_notes_panel_isOpen', NOTES_CONTENT: 'pda_notes_content_v1', TODO_LIST: 'pda_todo_list_v1' }; let todoItems = []; // This will hold our list of to-do objects // --- 2. STYLING --- function addStyles() { const styles = ` #pda-notes-container { position: fixed; top: 70px; /* Position it high on the page */ right: -320px; /* Start off-screen */ width: 320px; z-index: 10005; transition: right 0.3s ease-in-out; font-family: Arial, sans-serif; color: #333; } #pda-notes-container.expanded { right: 0; } #pda-notes-panel { background: #f7f7f7; border: 2px solid #6c757d; /* Grey theme */ border-right: none; padding: 0; border-top-left-radius: 8px; border-bottom-left-radius: 8px; box-shadow: -2px 2px 10px rgba(0,0,0,0.4); height: calc(100vh - 90px); display: flex; flex-direction: column; } #pda-notes-panel h4 { margin: 0; padding: 10px; font-size: 16px; background-color: #e9ecef; border-bottom: 1px solid #dee2e6; flex-shrink: 0; } .pda-notes-section { padding: 10px; border-bottom: 1px solid #dee2e6; } #pda-notes-textarea { width: 100%; height: 150px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; padding: 8px; font-size: 14px; resize: vertical; } #pda-todo-list { flex-grow: 1; overflow-y: auto; min-height: 100px; background: #fff; border: 1px solid #ccc; padding: 5px; margin-bottom: 10px; } .pda-todo-item { display: flex; align-items: center; padding: 6px; border-bottom: 1px solid #eee; } .pda-todo-item:last-child { border-bottom: none; } .pda-todo-item input[type="checkbox"] { margin-right: 10px; } .pda-todo-item.completed span { text-decoration: line-through; color: #888; } #pda-todo-input-area { display: flex; gap: 5px; margin-bottom: 10px; } #pda-todo-new-item { flex-grow: 1; padding: 5px; border: 1px solid #ccc; border-radius: 3px; } .pda-notes-button { padding: 5px 10px; border: 1px solid #999; background-color: #ddd; border-radius: 3px; cursor: pointer; } #pda-notes-toggle { position: fixed; top: 70px; /* Match panel top */ right: 0; width: 35px; height: 50px; background-color: #6c757d; color: white; border: 2px solid #6c757d; border-right: none; border-top-left-radius: 8px; border-bottom-left-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 16px; z-index: 10006; } `; const styleEl = document.createElement('style'); styleEl.textContent = styles; document.head.appendChild(styleEl); } // --- 3. CORE LOGIC --- function loadData() { // Load panel state if (localStorage.getItem(STORAGE_KEYS.PANEL_OPEN) === 'true') { $('#pda-notes-container').addClass('expanded'); $('#pda-notes-toggle').text('»'); } // Load notes const savedNotes = localStorage.getItem(STORAGE_KEYS.NOTES_CONTENT); if (savedNotes) { $('#pda-notes-textarea').val(savedNotes); } // Load To-Do list const savedTodos = localStorage.getItem(STORAGE_KEYS.TODO_LIST); todoItems = savedTodos ? JSON.parse(savedTodos) : []; renderTodoList(); } function renderTodoList() { const listContainer = $('#pda-todo-list'); listContainer.empty(); // Clear existing items before re-rendering if (todoItems.length === 0) { listContainer.html('<div style="color: #888; text-align: center; padding: 20px;">No to-do items yet.</div>'); return; } todoItems.forEach((item, index) => { const itemEl = $(` <div class="pda-todo-item ${item.completed ? 'completed' : ''}" data-index="${index}"> <input type="checkbox" ${item.completed ? 'checked' : ''}> <span></span> </div> `); itemEl.find('span').text(item.text); // Use .text() to prevent HTML injection listContainer.append(itemEl); }); } function saveTodoList() { localStorage.setItem(STORAGE_KEYS.TODO_LIST, JSON.stringify(todoItems)); } // --- 4. UI CREATION & EVENT HANDLERS --- function createPanel() { if (document.getElementById('pda-notes-container')) return; const panelHTML = ` <div id="pda-notes-container"> <div id="pda-notes-panel"> <div class="pda-notes-section"> <h4>Notes</h4> <textarea id="pda-notes-textarea" placeholder="Your notes here..."></textarea> </div> <div class="pda-notes-section" style="display:flex; flex-direction:column; flex-grow: 1;"> <h4>To-Do List</h4> <div id="pda-todo-list"></div> <div id="pda-todo-input-area"> <input type="text" id="pda-todo-new-item" placeholder="Add a new task..."> <button id="pda-todo-add-btn" class="pda-notes-button">Add</button> </div> <button id="pda-todo-clear-btn" class="pda-notes-button">Clear Checked Items</button> </div> </div> </div> `; const toggleButtonHTML = `<div id="pda-notes-toggle">N</div>`; $('body').append(panelHTML).append(toggleButtonHTML); // --- Event Handlers --- // Toggle panel visibility $('#pda-notes-toggle').on('click', function() { const container = $('#pda-notes-container'); const isOpen = container.toggleClass('expanded').hasClass('expanded'); $(this).text(isOpen ? '»' : 'N'); localStorage.setItem(STORAGE_KEYS.PANEL_OPEN, isOpen); }); // Save notes on input $('#pda-notes-textarea').on('input', function() { localStorage.setItem(STORAGE_KEYS.NOTES_CONTENT, $(this).val()); }); // Add a to-do item $('#pda-todo-add-btn').on('click', function() { const inputEl = $('#pda-todo-new-item'); const newText = inputEl.val().trim(); if (newText) { todoItems.push({ text: newText, completed: false }); saveTodoList(); renderTodoList(); inputEl.val('').focus(); } }); // Allow adding with Enter key $('#pda-todo-new-item').on('keypress', function(e) { if (e.which === 13) { // Enter key $('#pda-todo-add-btn').click(); } }); // Toggle completion status of a to-do item $('#pda-todo-list').on('change', 'input[type="checkbox"]', function() { const itemDiv = $(this).closest('.pda-todo-item'); const itemIndex = itemDiv.data('index'); if (typeof itemIndex !== 'undefined' && todoItems[itemIndex]) { todoItems[itemIndex].completed = this.checked; itemDiv.toggleClass('completed', this.checked); saveTodoList(); } }); // Clear checked items $('#pda-todo-clear-btn').on('click', function() { todoItems = todoItems.filter(item => !item.completed); saveTodoList(); renderTodoList(); }); } // --- 5. INITIALIZATION --- function main() { addStyles(); createPanel(); loadData(); } // Use a timeout to ensure the Torn page is fully loaded before the script runs setTimeout(main, 500); })();