To-Do List Globale Dark (Spunta Verde Fissa e Allineata)

To-Do list globale, scura, con spunta verde fissa e allineata per compiti completati

当前为 2025-11-28 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         To-Do List Globale Dark (Spunta Verde Fissa e Allineata)
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  To-Do list globale, scura, con spunta verde fissa e allineata per compiti completati
// @author       *Ace*
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Carica i dati salvati globalmente
    const savedTodos = JSON.parse(GM_getValue('todos', '[]'));
    const savedPosition = GM_getValue('popupPosition', 'bottom-right');

    // Crea il pulsante
    const button = document.createElement('button');
    button.textContent = '✓';
    button.style.position = 'fixed';
    button.style.zIndex = '9999';
    button.style.width = '40px';
    button.style.height = '40px';
    button.style.backgroundColor = '#6a5acd';
    button.style.color = 'white';
    button.style.border = 'none';
    button.style.borderRadius = '50%';
    button.style.cursor = 'pointer';
    button.style.fontSize = '16px';
    button.style.boxShadow = '0 2px 5px rgba(0,0,0,0.3)';

    // Crea il pop-up
    const popup = document.createElement('div');
    popup.style.position = 'fixed';
    popup.style.zIndex = '9999';
    popup.style.width = '280px';
    popup.style.backgroundColor = '#2d2d3a';
    popup.style.border = '1px solid #6a5acd';
    popup.style.borderRadius = '8px';
    popup.style.padding = '10px';
    popup.style.boxShadow = '0 2px 10px rgba(0,0,0,0.3)';
    popup.style.color = '#e0e0e0';
    popup.style.display = 'none';
    popup.style.fontFamily = 'Arial, sans-serif';

    // Imposta posizione iniziale
    updatePopupPosition();

    // Titolo + Icona Ingranaggio
    const titleContainer = document.createElement('div');
    titleContainer.style.display = 'flex';
    titleContainer.style.justifyContent = 'space-between';
    titleContainer.style.alignItems = 'center';
    titleContainer.style.margin = '0 0 10px 0';

    const title = document.createElement('div');
    title.textContent = 'To-Do List';
    title.style.fontSize = '16px';
    title.style.fontWeight = 'bold';
    title.style.color = '#d0b0ff';
    title.style.borderBottom = '1px solid #6a5acd';
    title.style.paddingBottom = '5px';
    title.style.flexGrow = '1';

    const settingsIcon = document.createElement('button');
    settingsIcon.textContent = '⚙';
    settingsIcon.style.background = 'none';
    settingsIcon.style.border = 'none';
    settingsIcon.style.color = '#d0b0ff';
    settingsIcon.style.cursor = 'pointer';
    settingsIcon.style.fontSize = '16px';
    settingsIcon.style.marginLeft = '10px';

    titleContainer.appendChild(title);
    titleContainer.appendChild(settingsIcon);
    popup.appendChild(titleContainer);

    // Menù posizione (inizialmente nascosto)
    const positionMenu = document.createElement('div');
    positionMenu.style.margin = '10px 0';
    positionMenu.style.display = 'none';
    positionMenu.style.padding = '5px';
    positionMenu.style.border = '1px solid #6a5acd';
    positionMenu.style.borderRadius = '4px';
    positionMenu.style.backgroundColor = '#3a3a4a';

    const positionLabel = document.createElement('label');
    positionLabel.textContent = 'Posizione:';
    positionLabel.style.color = '#d0b0ff';
    positionLabel.style.fontSize = '12px';
    positionLabel.style.display = 'block';
    positionLabel.style.marginBottom = '5px';

    const positionSelect = document.createElement('select');
    positionSelect.style.padding = '5px';
    positionSelect.style.border = '1px solid #6a5acd';
    positionSelect.style.borderRadius = '4px';
    positionSelect.style.backgroundColor = '#3a3a4a';
    positionSelect.style.color = '#e0e0e0';
    positionSelect.style.width = '100%';

    positionSelect.innerHTML = `
        <option value="top-left" ${savedPosition === 'top-left' ? 'selected' : ''}>Alto a Sinistra</option>
        <option value="top-right" ${savedPosition === 'top-right' ? 'selected' : ''}>Alto a Destra</option>
        <option value="bottom-left" ${savedPosition === 'bottom-left' ? 'selected' : ''}>Basso a Sinistra</option>
        <option value="bottom-right" ${savedPosition === 'bottom-right' ? 'selected' : ''}>Basso a Destra</option>
    `;

    positionSelect.addEventListener('change', () => {
        GM_setValue('popupPosition', positionSelect.value);
        updatePopupPosition();
    });

    positionMenu.appendChild(positionLabel);
    positionMenu.appendChild(positionSelect);
    popup.appendChild(positionMenu);

    // Toggle menù impostazioni
    settingsIcon.onclick = () => {
        positionMenu.style.display = positionMenu.style.display === 'none' ? 'block' : 'none';
    };

    // Lista
    const list = document.createElement('div');
    list.id = 'todo-list';
    list.style.maxHeight = '200px';
    list.style.overflowY = 'auto';
    list.style.marginBottom = '10px';
    popup.appendChild(list);

    // Input e pulsanti
    const inputContainer = document.createElement('div');
    inputContainer.style.display = 'flex';
    inputContainer.style.flexDirection = 'column';
    inputContainer.style.gap = '5px';

    const textContainer = document.createElement('div');
    textContainer.style.display = 'flex';
    textContainer.style.gap = '5px';

    const inputText = document.createElement('input');
    inputText.type = 'text';
    inputText.placeholder = 'Nuova voce...';
    inputText.style.flexGrow = '1';
    inputText.style.padding = '5px';
    inputText.style.border = '1px solid #6a5acd';
    inputText.style.borderRadius = '4px';
    inputText.style.backgroundColor = '#3a3a4a';
    inputText.style.color = '#e0e0e0';

    textContainer.appendChild(inputText);

    const addButton = document.createElement('button');
    addButton.textContent = '+';
    addButton.style.padding = '5px 10px';
    addButton.style.backgroundColor = '#6a5acd';
    addButton.style.color = 'white';
    addButton.style.border = 'none';
    addButton.style.borderRadius = '4px';
    addButton.style.cursor = 'pointer';

    textContainer.appendChild(addButton);
    inputContainer.appendChild(textContainer);

    const inputDate = document.createElement('input');
    inputDate.type = 'date';
    inputDate.style.padding = '5px';
    inputDate.style.border = '1px solid #6a5acd';
    inputDate.style.borderRadius = '4px';
    inputDate.style.backgroundColor = '#3a3a4a';
    inputDate.style.color = '#e0e0e0';
    inputDate.style.width = '120px';

    inputContainer.appendChild(inputDate);
    popup.appendChild(inputContainer);

    // Pulsante per cancellare tutto
    const clearButton = document.createElement('button');
    clearButton.textContent = 'Cancella tutto';
    clearButton.style.marginTop = '10px';
    clearButton.style.padding = '5px';
    clearButton.style.width = '100%';
    clearButton.style.backgroundColor = '#6a5acd';
    clearButton.style.color = 'white';
    clearButton.style.border = 'none';
    clearButton.style.borderRadius = '4px';
    clearButton.style.cursor = 'pointer';

    clearButton.onclick = () => {
        if (confirm('Sei sicuro di voler cancellare tutto?')) {
            GM_deleteValue('todos');
            list.innerHTML = '';
        }
    };

    popup.appendChild(clearButton);

    // Aggiungi il pulsante e il pop-up al body
    document.body.appendChild(button);
    document.body.appendChild(popup);

    // Aggiorna posizione popup e pulsante
    function updatePopupPosition() {
        const position = GM_getValue('popupPosition', 'bottom-right');
        switch(position) {
            case 'top-left':
                popup.style.top = '20px';
                popup.style.left = '20px';
                popup.style.bottom = 'auto';
                popup.style.right = 'auto';
                button.style.top = '70px';
                button.style.left = '20px';
                button.style.bottom = 'auto';
                button.style.right = 'auto';
                break;
            case 'top-right':
                popup.style.top = '20px';
                popup.style.right = '20px';
                popup.style.bottom = 'auto';
                popup.style.left = 'auto';
                button.style.top = '70px';
                button.style.right = '20px';
                button.style.bottom = 'auto';
                button.style.left = 'auto';
                break;
            case 'bottom-left':
                popup.style.bottom = '70px';
                popup.style.left = '20px';
                popup.style.top = 'auto';
                popup.style.right = 'auto';
                button.style.bottom = '20px';
                button.style.left = '20px';
                button.style.top = 'auto';
                button.style.right = 'auto';
                break;
            case 'bottom-right':
                popup.style.bottom = '70px';
                popup.style.right = '20px';
                popup.style.top = 'auto';
                popup.style.left = 'auto';
                button.style.bottom = '20px';
                button.style.right = '20px';
                button.style.top = 'auto';
                button.style.left = 'auto';
                break;
        }
    }

    // Carica i todo salvati
    function loadTodos() {
        list.innerHTML = '';
        savedTodos.forEach((todo, index) => {
            addTodoToList(todo.text, todo.date, index, todo.completed || false);
        });
    }

    // Aggiungi un todo alla lista
    function addTodoToList(text, date, index, completed) {
        const todoItem = document.createElement('div');
        todoItem.style.display = 'flex';
        todoItem.style.alignItems = 'center';
        todoItem.style.padding = '8px';
        todoItem.style.borderBottom = '1px solid #6a5acd';
        todoItem.style.backgroundColor = index % 2 === 0 ? '#3a3a4a' : '#2d2d3a';

        // Pulsante completamento (quadrato fisso 20x20px)
        const doneButton = document.createElement('button');
        doneButton.style.width = '15px';
        doneButton.style.height = '15px';
        doneButton.style.minWidth = '15px';
        doneButton.style.minHeight = '15px';
        doneButton.style.backgroundColor = completed ? '#4CAF50' : 'transparent';
        doneButton.style.color = 'white';
        doneButton.style.border = '1px solid #6a5acd';
        doneButton.style.borderRadius = '4px';
        doneButton.style.cursor = 'pointer';
        doneButton.style.fontSize = '12px';
        doneButton.style.marginRight = '8px';
        doneButton.style.display = 'flex';
        doneButton.style.alignItems = 'center';
        doneButton.style.justifyContent = 'center';
        doneButton.textContent = completed ? '✓' : '';

        doneButton.onclick = (e) => {
            e.stopPropagation();
            const index = savedTodos.findIndex(t => t.text === text && t.date === date);
            if (index > -1) {
                savedTodos[index].completed = !savedTodos[index].completed;
                GM_setValue('todos', JSON.stringify(savedTodos));
                todoItem.remove();
                addTodoToList(text, date, index, savedTodos[index].completed);
            }
        };

        // Contenitore testo + data
        const todoTextContainer = document.createElement('div');
        todoTextContainer.style.flexGrow = '1';
        todoTextContainer.style.display = 'flex';
        todoTextContainer.style.alignItems = 'center';

        const todoText = document.createElement('span');
        todoText.textContent = text;
        todoText.style.color = '#e0e0e0';
        todoText.style.flexGrow = '1';
        if (completed) {
            todoText.style.textDecoration = 'line-through';
            todoText.style.opacity = '0.7';
        }

        const todoDate = document.createElement('small');
        todoDate.textContent = date ? ` (${date})` : '';
        todoDate.style.color = '#d0b0ff';
        todoDate.style.marginLeft = '5px';

        todoTextContainer.appendChild(todoText);
        todoTextContainer.appendChild(todoDate);

        // Pulsante elimina
        const deleteButton = document.createElement('button');
        deleteButton.textContent = '✕';
        deleteButton.style.background = 'none';
        deleteButton.style.border = 'none';
        deleteButton.style.color = '#ff8888';
        deleteButton.style.cursor = 'pointer';
        deleteButton.style.fontSize = '12px';
        deleteButton.style.marginLeft = '8px';

        deleteButton.onclick = (e) => {
            e.stopPropagation(); // <-- Qui è la correzione
            const index = savedTodos.findIndex(t => t.text === text && t.date === date);
            if (index > -1) {
                savedTodos.splice(index, 1);
                GM_setValue('todos', JSON.stringify(savedTodos));
            }
            todoItem.remove();
        };

        todoItem.appendChild(doneButton);
        todoItem.appendChild(todoTextContainer);
        todoItem.appendChild(deleteButton);

        list.appendChild(todoItem);
    }

    // Aggiungi un nuovo todo
    function addTodo() {
        const text = inputText.value.trim();
        const date = inputDate.value;
        if (text) {
            savedTodos.push({ text, date, completed: false });
            GM_setValue('todos', JSON.stringify(savedTodos));
            addTodoToList(text, date, savedTodos.length - 1, false);
            inputText.value = '';
            inputDate.value = '';
        }
    }

    addButton.onclick = addTodo;
    inputText.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') addTodo();
    });

    // Toggle pop-up
    button.onclick = () => {
        popup.style.display = popup.style.display === 'none' ? 'block' : 'none';
        if (popup.style.display === 'block') loadTodos();
    };

    // Chiudi il pop-up cliccando fuori
    document.addEventListener('click', (e) => {
        if (!popup.contains(e.target) && e.target !== button && popup.style.display === 'block') {
            popup.style.display = 'none';
        }
    });
})();