diff --git a/configs.js b/configs.js index 49582a9..317becf 100644 --- a/configs.js +++ b/configs.js @@ -3,7 +3,7 @@ const configs = (function () { // settings const enableLimit = true; // true or false - const limit = 5; // integer + const limit = 10; // integer // animation const scrollSpeed = 30; // milliseconds (DO NOT PUT BELOW 5, COMPUTER MIGHT CRASH) the lower the value, the faster the scroll @@ -126,6 +126,20 @@ const configs = (function () { "!finished", ]; + // Unfinish task commands - please add commands in the exact format + const unfinishTaskCommands = [ + "!tasku", + "!taskunfinish", + "!utask", + "!unfinishtask", + "!taskud", + "!taskundone", + "!undonetask", + "!undone", + "!unfinish", + "!unfinished", + ]; + // Check task commands - please add commands in the exact format const checkCommands = [ "!taskc", @@ -187,7 +201,8 @@ const configs = (function () { const noTaskAdded = "Looks like you already hit the limit of incomplete tasks, {user}"; const noTaskContent = "Try using !task the-task-you-are-working-on {user}"; - const taskDeleted = 'Task "{task}" has been deleted successfully, {user}'; + const taskDeleted = + 'Task(s) "{task}" has been deleted successfully, {user}'; const specifyTaskIndex = "Try specifying the index of the task {user}"; const duplicateTask = @@ -198,6 +213,8 @@ const configs = (function () { const adminDeleteTasks = "All of {mentioned}'s tasks have been deleted"; const taskFinished = 'Good job on finishing the task "{task}", {user}!'; + const taskUnfinished = + 'Task(s) "{task}" has been unmarked as done, {user}!'; const taskEdited = "Task '{originalTask}' has been edited to '{task}' successfully, {user}"; const noTaskEdit = "Try doing !edit [index] [new task] {user}"; @@ -290,6 +307,7 @@ const configs = (function () { editTaskCommands, deleteTaskCommands, finishTaskCommands, + unfinishTaskCommands, helpCommands, checkCommands, clearMyDoneCommands, @@ -308,6 +326,7 @@ const configs = (function () { specifyTaskIndex, duplicateTask, taskFinished, + taskUnfinished, taskEdited, noTaskEdit, noTask, diff --git a/scripts/index.js b/scripts/index.js index 6c9dd3d..dcde33e 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -107,6 +107,27 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => { respond(finishedResponse, params); } + } else if (commands.unfinishTaskCommands.includes(command)) { + let unfinishStatus = markTaskUndone(user, message); + + if (unfinishStatus === 0) { + // user has no tasks + respond(responses.noTask, params); + } else if (unfinishStatus === 1) { + // invalid input + respond(responses.specifyTaskIndex, params); + } else { + // task unfinished + let unfinishedResponse = responses.taskUnfinished; + + params.task = unfinishStatus.markedTasks; + + if (unfinishStatus.failedTasks !== "") { + unfinishedResponse += ` | Failed to unfinish task(s): "${unfinishStatus.failedTasks}"`; + } + + respond(unfinishedResponse, params); + } } else if (commands.checkCommands.includes(command)) { if (message === "") { let response = checkTasks(user); diff --git a/scripts/taskList.js b/scripts/taskList.js index 6d6efa2..b09e7d5 100644 --- a/scripts/taskList.js +++ b/scripts/taskList.js @@ -264,7 +264,7 @@ function removeTask(username, task) { if (index === -1) { if (isInt(t)) { index = parseInt(t) - 1; // ACTUAL INDEX - } else if (incompleteTasks.length) { + } else if (incompleteTasks.length === 1) { index = tasks[username].todos.findIndex((t) => !t.done); tasksRemoved.push(tasks[username].todos[index].text); removedTaskIndex.push(index); @@ -314,7 +314,7 @@ function removeTask(username, task) { if (index === -1) { if (isInt(task)) { index = parseInt(task) - 1; // ACTUAL INDEX - } else if (incompleteTasks.length) { + } else if (incompleteTasks.length === 1) { index = tasks[username].todos.findIndex((t) => !t.done); } else { return 1; @@ -403,7 +403,7 @@ function markTaskDone(username, task) { if (index === -1) { if (isInt(t)) { index = parseInt(t) - 1; // ACTUAL INDEX - } else if (incompleteTasks.length) { + } else if (incompleteTasks.length === 1) { index = tasks[username].todos.findIndex((t) => !t.done); tasksMarkedComplete.push(tasks[username].todos[index].text); } else { @@ -443,7 +443,7 @@ function markTaskDone(username, task) { if (index === -1) { if (isInt(task)) { index = parseInt(task) - 1; // ACTUAL INDEX - } else if (incompleteTasks.length) { + } else if (incompleteTasks.length === 1) { index = tasks[username].todos.findIndex((t) => !t.done); } else { return 1; @@ -465,6 +465,98 @@ function markTaskDone(username, task) { } } +function markTaskUndone(username, task) { + const tasks = JSON.parse(localStorage.tasks); + + // user does not have any tasks + if (!tasks[username] || tasks[username].todos.length === 0) { + return 0; + } + + const completedTasks = tasks[username].todos.filter((t) => t.done); + + // match regex: integers separated by space e.g. '1 2 3 4' + if (task.match(/^(\d+ )*\d+$/)) { + // insert commas between integers + task = task.replace(/(\d+)/g, "$1,"); + // remove trailing comma + task = task.slice(0, -1); + } + + let tasksMarkedUndone = []; + let tasksFailedToMarkUndone = []; + + // check if there's a comma in the task (multiple tasks) + if (task.includes(",")) { + let tasksToMarkUndone = task.split(",").map((t) => t.trim()); + for (const t of tasksToMarkUndone) { + let index = tasks[username].todos.findIndex( + (task) => task.text.toLowerCase() === t.toLowerCase() + ); + + if (index === -1) { + // user input isn't the task name + if (isInt(t)) { + index = parseInt(t) - 1; // ACTUAL INDEX + } else { + tasksFailedToMarkUndone.push(t); + continue; + } + + if (index < 0 || index > tasks[username].todos.length - 1) { + tasksFailedToMarkUndone.push(t); + continue; + } else { + tasksMarkedUndone.push(tasks[username].todos[index].text); + } + } else { + tasksMarkedUndone.push(tasks[username].todos[index].text); + } + tasks[username].todos[index].done = false; + } + + if (tasksMarkedUndone.length === 0) { + return 1; + } + + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + if (!scrolling) { + renderTaskListToDOM(); + } + + return { + markedTasks: tasksMarkedUndone.join('", "'), + failedTasks: tasksFailedToMarkUndone.join('", "'), + }; + } else { + let index = tasks[username].todos.findIndex( + (t) => t.text.toLowerCase() === task.toLowerCase() + ); + + if (index === -1) { + if (isInt(task)) { + index = parseInt(task) - 1; // ACTUAL INDEX + } else if (completedTasks.length === 1) { + index = tasks[username].todos.findIndex((t) => t.done); + } else { + return 1; + } + + if (index < 0 || index > tasks[username].todos.length - 1) { + return 1; + } + + tasks[username].todos[index].done = false; + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + renderTaskListToDOM(); + return { + markedTasks: tasks[username].todos[index].text, + failedTasks: "", + }; + } + } +} + // 0: user has no tasks // 1: invalid input // [original task, new task]: succcess