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 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         To-Do List Globale Dark (Spunta Verde Fissa e Allineata)
// @namespace    http://tampermonkey.net/
// @version      2.1
// @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 = () => {
            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';
        }
    });
})();