To-Do list globale, scura, con spunta verde fissa e allineata per compiti completati
当前为
// ==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';
}
});
})();