Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Todo List Feature #322

Merged
merged 17 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,31 @@
</head>

<body>
<!----------------------- ToDo List Setup Starting ----------------------->
<!-- 9 Dot Icon -->
<div class="todoListCont" id="todoListCont">
<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="dot-icon" width="36" height="36" viewBox="0 0 32 32" xml:space="preserve">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" stroke="#CCCCCC" stroke-width="0.128"></g><g id="SVGRepo_iconCarrier"> <g> <path d="M11,30H5c-1.7,0-3-1.3-3-3v-6c0-1.7,1.3-3,3-3h6c1.7,0,3,1.3,3,3v6C14,28.7,12.7,30,11,30z"></path> </g> <g> <path d="M29,6H17c-0.6,0-1-0.4-1-1s0.4-1,1-1h12c0.6,0,1,0.4,1,1S29.6,6,29,6z"></path> </g> <g> <path d="M24,10h-7c-0.6,0-1-0.4-1-1s0.4-1,1-1h7c0.6,0,1,0.4,1,1S24.6,10,24,10z"></path> </g> <g> <path d="M29,22H17c-0.6,0-1-0.4-1-1s0.4-1,1-1h12c0.6,0,1,0.4,1,1S29.6,22,29,22z"></path> </g> <g> <path d="M24,26h-7c-0.6,0-1-0.4-1-1s0.4-1,1-1h7c0.6,0,1,0.4,1,1S24.6,26,24,26z"></path> </g> <path d="M11,2H5C3.3,2,2,3.3,2,5v6c0,1.7,1.3,3,3,3h6c1.7,0,3-1.3,3-3V5C14,3.3,12.7,2,11,2z M11.7,6.7l-3,3C8.5,9.9,8.3,10,8,10 S7.5,9.9,7.3,9.7l-2-2c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0L8,7.6l2.3-2.3c0.4-0.4,1-0.4,1.4,0S12.1,6.3,11.7,6.7z"></path> </g>
</svg>
<!-- Text to appear on hover -->
<span class="tooltip-text" id="todoListHover">ToDo List</span>
</div>

<!-- Centered Icon Container -->
<div id="todoContainer" class="todo-container" style="display: none;">
<h2 id="todoListHeading">To Do List</h2>
<div class="searchbar-content">
<input id="todoInput" placeholder="Type here..." type="text" autocomplete="off">
<div class="searchControls">
<!-- Add Button -->
<button id="todoAdd">+</button>
</div>
</div>
<ul class="todolist" id="todoullist">

</ul>
</div>

<!----------------------- Google App Menu Setup Starting ----------------------->
<!-- 9 Dot Icon -->
<div class="googleAppsCont" id="googleAppsCont">
Expand Down Expand Up @@ -960,6 +985,17 @@ <h1>Material You NewTab</h1>
<span class="toggle"></span>
</label>
</div>

<div class="ttcont">
<div class="texts">
<div class="bigText" id="todoListText">To Do List</div>
<div class="infoText" id="todoListInfo">Show a Daily To Do List</div>
</div>
<label class="switch">
<input id="todoListCheckbox" type="checkbox">
<span class="toggle"></span>
</label>
</div>
<!-- ---🟡--- -->
<div class="ttcont">
<div class="texts">
Expand Down
13 changes: 13 additions & 0 deletions languages.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const translations = {
"enable_ai_tools": "Show shortcuts for AI tools",
"googleAppsMenuText": "Google Apps",
"googleAppsMenuInfo": "Show shortcuts for Google Apps",
"todoListText": "To Do List",
"todoListInfo": "Show a Daily To Do List",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todoListHeading and todoInput missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no need to write the same thing twice so I did this

image

Added the todoPlaceholder in my recent commit

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad, didn't noticed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this new person is better than prem 😄

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe.. I always miss something when checking from mobile

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol no, I am not better
I'm still learning from other great people
Before yesterday I didn't even knew what XSS was
so you have my thanks @prem-k-r

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah we are just friends. Just making some fun. Thats all. 🙃
Don't worry.

// Digital Clock
"digitalclocktittle": "Digital Clock",
"digitalclockinfo": "Switch to the digital clock",
Expand Down Expand Up @@ -83,10 +85,12 @@ const translations = {
"enterBtn": "Search",
"searchPlaceholder": "Type here...",
"listenPlaceholder": "Listening...",
"todoPlaceholder": "Add task...",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed wrong

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh lol, I'll fix this in a min

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 👍

"searchWithHint": "Search With",
"ai_tools": "AI Tools",
"userText": "Click here to edit",
"googleAppsHover": "Google Apps", // Keep this untranslated if string width is much longer
"todoListHover": "ToDo List", // Keep this untranslated if string width is much longer
// End of Body and New Tab Items

// Greeting
Expand Down Expand Up @@ -345,6 +349,8 @@ const translations = {
"enable_ai_tools": "AI उपकरणों के शॉर्टकट्स प्रदर्शित करें",
"googleAppsMenuText": "गूगल ऐप्स",
"googleAppsMenuInfo": "गूगल ऐप्स के शॉर्टकट्स प्रदर्शित करें",
"todoListText": "कार्य सूची",
"todoListInfo": "अपनी दैनिक कार्य सूची देखें और व्यवस्थित रहें",
// Digital Clock
"digitalclocktittle": "डिजिटल घड़ी",
"digitalclockinfo": "डिजिटल घड़ी पर स्विच करें",
Expand Down Expand Up @@ -402,6 +408,7 @@ const translations = {
"enterBtn": "खोजें",
"searchPlaceholder": "यहाँ लिखें...",
"listenPlaceholder": "सुन रहे हैं...",
"todoPlaceholder": "कार्य जोड़ें...",
"searchWithHint": "खोज माध्यम",
"ai_tools": "AI उपकरण",
"userText": "यहाँ अपना टेक्स्ट लिखें",
Expand All @@ -427,6 +434,7 @@ const translations = {
"firefly": "एडोबी फायरफ्लाई",
"github": "गिटहब",
"googleAppsHover": "गूगल ऐप्स",
"todoListHover": "कार्य सूची",

// Wallpaper and alerts
"uploadWallpaperText": "वॉलपेपर अपलोड करें",
Expand Down Expand Up @@ -1858,6 +1866,9 @@ function applyLanguage(lang) {
{ id: 'enable_ai_tools', key: 'enable_ai_tools' },
{ id: 'googleAppsMenuText', key: 'googleAppsMenuText' },
{ id: 'googleAppsMenuInfo', key: 'googleAppsMenuInfo' },
{ id: 'todoListHeading', key: 'todoListText' },
{ id: 'todoListText', key: 'todoListText' },
{ id: 'todoListInfo', key: 'todoListInfo' },
{ id: 'fahrenheitCelsiusCheckbox', key: 'fahrenheitCelsiusCheckbox' },
{ id: 'fahrenheitCelsiusText', key: 'fahrenheitCelsiusText' },
{ id: 'micIconTitle', key: 'micIconTitle' },
Expand Down Expand Up @@ -1893,6 +1904,7 @@ function applyLanguage(lang) {
{ id: 'conditionText', key: 'conditionText' },
{ id: 'enterBtn', key: 'enterBtn' },
{ id: 'searchQ', key: 'searchPlaceholder', isPlaceholder: true },
{ id: 'todoInput', key: 'todoPlaceholder', isPlaceholder: true },
{ id: 'searchWithHint', key: 'searchWithHint' },
{ id: 'ai_tools', key: 'ai_tools' },
{ id: 'humidityLevel', key: 'humidityLevel' },
Expand All @@ -1916,6 +1928,7 @@ function applyLanguage(lang) {
{ id: 'metaAI', key: 'metaAI'},
{ id: 'github', key: 'github' },
{ id: 'googleAppsHover', key: 'googleAppsHover' },
{ id: 'todoListHover', key: 'todoListHover' },
{ id: 'uploadWallpaperText', key: 'uploadWallpaperText' },
{ id: 'backupText', key: 'backupText' },
{ id: 'restoreText', key: 'restoreText' },
Expand Down
147 changes: 147 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,139 @@ document.addEventListener("click", function (event) {
}
});
// ------------------------End of Google App Menu Setup-----------------------------------
// ----------------------------------- To Do List ----------------------------------------

// DOM Variables
const todoContainer = document.getElementById("todoContainer");
const todoListCont = document.getElementById("todoListCont");
const todoulList = document.getElementById("todoullist");
const todoAdd = document.getElementById("todoAdd");
const todoInput = document.getElementById("todoInput");
let todoList = {}; // Initialize todoList JSON

// Add event listeners for Add button click or Enter key press
todoAdd.addEventListener("click", addtodoItem);
todoInput.addEventListener("keypress", (event) => {
if (event.key === "Enter") {
addtodoItem();
}
});

// Utility function to sanitize input
function sanitizeInput(input) {
const div = document.createElement('div');
div.textContent = input;
return div.innerHTML;
}

// Function to add items to the TODO list
function addtodoItem() {
const inputText = todoInput.value.trim(); // Remove useless whitespaces
if (inputText === '') {
return; // Return the function when the input is empty
}
const t = "t" + Date.now(); // Generate a Unique ID
const rawText = inputText;
todoList[t] = { title: rawText, status: "pending" }; // Add data to the JSON variable
const li = createTodoItemDOM(t, rawText, "pending"); // Create List item
todoulList.appendChild(li); // Append the new item to the DOM immediately
todoInput.value = ''; // Clear Input
SaveToDoData(); // Save changes
}

function createTodoItemDOM(id, title, status) {
let li = document.createElement('li');
li.innerHTML = sanitizeInput(title); // Sanitize before rendering in DOM
const span = document.createElement("span"); // Create the Cross Icon
span.setAttribute("class", "todoremovebtn");
span.textContent = "\u00d7";
li.appendChild(span); // Add the cross icon to the LI tag
li.setAttribute("class", "todolistitem");
if (status === 'completed') {
li.classList.add("checked");
}
li.setAttribute("data-todoitem", id); // Set a data attribute to the li so that we can uniquely identify which li has been modified or deleted
return li; // Return the created `li` element
}

// Event delegation for task check and remove
todoulList.addEventListener("click", (event) => {
if (event.target.tagName === "LI"){
event.target.classList.toggle("checked"); // Check the clicked LI tag
let id = event.target.dataset.todoitem;
todoList[id].status = ((todoList[id].status === "completed")? "pending" : "completed"); // Update status
SaveToDoData(); // Save Changes
} else if (event.target.tagName === "SPAN"){
let id = event.target.parentElement.dataset.todoitem;
event.target.parentElement.remove(); // Remove the clicked LI tag
delete todoList[id]; // Remove the deleted List item data
SaveToDoData(); // Save Changes
}
});

// Save JSON to local Storage
function SaveToDoData(){
localStorage.setItem("todoList", JSON.stringify(todoList));
}
// Fetch saved JSON and create list items using it
function ShowToDoList() {
try {
todoList = JSON.parse(localStorage.getItem("todoList")) || {}; // Parse stored data or initialize empty
const fragment = document.createDocumentFragment(); // Create a DocumentFragment
for (let id in todoList) {
const todo = todoList[id];
const li = createTodoItemDOM(id, todo.title, todo.status); // Create `li` elements
fragment.appendChild(li); // Add `li` to the fragment
}
todoulList.appendChild(fragment); // Append all `li` to the `ul` at once
} catch (error) {
console.error("Error loading from localStorage:", error);
localStorage.setItem("todoList", '{}'); // Reset corrupted data
}
}

// Code to reset the List on the Next Day
let todoLastUpdateDate = localStorage.getItem("todoLastUpdateDate"); // Get the date of last update
let todoCurrentDate = new Date().toLocaleDateString(); // Get current date
if (todoLastUpdateDate===todoCurrentDate){
ShowToDoList();
} else {
// Reset the list when last update date and the current date does not match
localStorage.setItem("todoLastUpdateDate",todoCurrentDate);
localStorage.setItem("todoList",'{}');
ShowToDoList();
}

// Toggle menu and tooltip visibility
todoListCont.addEventListener("click", function (event) {
const isMenuVisible = todoContainer.style.display === 'grid';

// Toggle menu visibility
todoContainer.style.display = isMenuVisible ? 'none' : 'grid';

// Add or remove the class to hide the tooltip
if (!isMenuVisible) {
todoListCont.classList.add('menu-open'); // Hide tooltip
todoInput.focus(); // Auto focus on input box
} else {
todoListCont.classList.remove('menu-open'); // Restore tooltip
}
});

// Close menu when clicking outside
document.addEventListener("click", function (event) {
const isClickInside =
todoContainer.contains(event.target) || todoListCont.contains(event.target) || event.target.classList.contains('todoremovebtn');

if (!isClickInside && todoContainer.style.display === 'grid') {
todoContainer.style.display = 'none'; // Hide menu
todoListCont.classList.remove('menu-open'); // Restore tooltip
}

event.stopPropagation();
});

// ------------------------------- End of To Do List -------------------------------------

// Retrieve current time and calculate initial angles
var currentTime = new Date();
Expand Down Expand Up @@ -2313,6 +2446,7 @@ document.addEventListener("DOMContentLoaded", function () {
const adaptiveIconToggle = document.getElementById("adaptiveIconToggle");
const aiToolsCheckbox = document.getElementById("aiToolsCheckbox");
const googleAppsCheckbox = document.getElementById("googleAppsCheckbox");
const todoListCheckbox = document.getElementById("todoListCheckbox");
const timeformatField = document.getElementById("timeformatField");
const hourcheckbox = document.getElementById("12hourcheckbox");
const digitalCheckbox = document.getElementById("digitalCheckbox");
Expand Down Expand Up @@ -2977,6 +3111,17 @@ document.addEventListener("DOMContentLoaded", function () {
}
});

todoListCheckbox.addEventListener("change", function () {
saveCheckboxState("todoListCheckboxState", todoListCheckbox);
if (todoListCheckbox.checked) {
todoListCont.style.display = "flex";
saveDisplayStatus("todoListDisplayStatus", "flex");
} else {
todoListCont.style.display = "none";
saveDisplayStatus("todoListDisplayStatus", "none");
}
});

fahrenheitCheckbox.addEventListener("change", function () {
saveCheckboxState("fahrenheitCheckboxState", fahrenheitCheckbox);
});
Expand Down Expand Up @@ -3050,9 +3195,11 @@ document.addEventListener("DOMContentLoaded", function () {
loadActiveStatus("proxybypassField", proxybypassField);
loadCheckboxState("aiToolsCheckboxState", aiToolsCheckbox);
loadCheckboxState("googleAppsCheckboxState", googleAppsCheckbox);
loadCheckboxState("todoListCheckboxState", todoListCheckbox);
loadDisplayStatus("shortcutsDisplayStatus", shortcuts);
loadDisplayStatus("aiToolsDisplayStatus", aiToolsCont);
loadDisplayStatus("googleAppsDisplayStatus", googleAppsCont);
loadDisplayStatus("todoListDisplayStatus", todoListCont);
loadCheckboxState("fahrenheitCheckboxState", fahrenheitCheckbox);
loadShortcuts();
});
Loading