updated javascript codebase

This commit is contained in:
liyunze 2026-08-06 22:30:41 +10:00
parent 14612e281e
commit 6efe723361
6 changed files with 166 additions and 244 deletions

View file

@ -10,11 +10,11 @@
<script src="./auth.js"></script> <script src="./auth.js"></script>
<script src="./configs.js"></script> <script src="./configs.js"></script>
<script defer src="./scripts/defaultConfigs.js"></script> <script defer src="./scripts/defaultConfigs.js"></script>
<script defer src="./scripts/constants.js"></script>
<script defer src="./scripts/functions.js"></script> <script defer src="./scripts/functions.js"></script>
<script defer src="./scripts/processCommand.js"></script> <script defer src="./scripts/processCommand.js"></script>
<script defer src="./scripts/index.js"></script> <script defer src="./scripts/index.js"></script>
<script defer src="./scripts/taskList.js"></script> <script defer src="./scripts/taskList.js"></script>
<script defer src="./scripts/extraScripts.js"></script>
<link rel="stylesheet" type="text/css" href="./styles/taskList.css" /> <link rel="stylesheet" type="text/css" href="./styles/taskList.css" />
<link <link

38
scripts/constants.js Normal file
View file

@ -0,0 +1,38 @@
const STATUS = Object.freeze({
ERROR: 0,
INVALID_INPUT: 1,
ALREADY_COMPLETED: 2,
SUCCESS: 200,
});
const DB_CONFIG = Object.freeze({
NAME: "tasksDB",
VERSION: 1,
STORE: "tasks",
KEY_TASKS: "tasks",
KEY_COUNTS: "counts",
KEY_TASKMASTER: "taskmaster",
});
const PAGINATION = Object.freeze({
SIZE: 10,
SLEEP_MS: 200,
});
const ANIMATION = Object.freeze({
TITLE_FADE_IN_MS: 500,
TITLE_FADE_OUT_MS: 100,
TITLE_CYCLE_INTERVAL_MS: 8000,
});
const TEST_CONFIG = Object.freeze({
RANDOM_TASK_MAX: 10,
TASK_DELAY_MS: 1000,
USER_COUNT: 7,
RANDOM_TASK_COUNT_MIN: 1,
RANDOM_TASK_COUNT_MAX: 5,
});
const RESERVED_KEYS = Object.freeze({
ID: "id",
});

View file

@ -1,6 +1,6 @@
var commands = configs.commands; const commands = configs.commands;
var openQuote = getSetting("openQuote"); const openQuote = getSetting("openQuote");
var closeQuote = getSetting("closeQuote"); const closeQuote = getSetting("closeQuote");
async function processCommand(user, command, message, flags, extra) { async function processCommand(user, command, message, flags, extra) {
params = { params = {
@ -235,7 +235,7 @@ async function processCommand(user, command, message, flags, extra) {
.join(" | ") .join(" | ")
.replaceAll("{taskName}", getSetting("taskName")); .replaceAll("{taskName}", getSetting("taskName"));
var checkingUser = user; const checkingUser = user;
params.checkingUser = checkingUser; params.checkingUser = checkingUser;
await respond(`{tasks}`, params, extra.id); await respond(`{tasks}`, params, extra.id);
@ -268,7 +268,7 @@ async function processCommand(user, command, message, flags, extra) {
.join(" | ") .join(" | ")
.replaceAll("{taskName}", getSetting("taskName")); .replaceAll("{taskName}", getSetting("taskName"));
var checkingUser = user; const checkingUser = user;
params.checkingUser = checkingUser; params.checkingUser = checkingUser;

View file

@ -22,14 +22,14 @@ DB structure:
const styles = configs.styles; const styles = configs.styles;
const scrollSpeed = configs.animation.scrollSpeed; const scrollSpeed = configs.animation.scrollSpeed;
var openQuote = getSetting("openQuote"); let openQuote = getSetting("openQuote");
var closeQuote = getSetting("closeQuote"); let closeQuote = getSetting("closeQuote");
let visible = false; let visible = false;
let scrolling = false; let scrolling = false;
let primaryAnimation, secondaryAnimation; let primaryAnimation, secondaryAnimation;
const taskSeparator = getSetting("taskSeparator"); const taskSeparator = getSetting("taskSeparator");
var taskListMemory = { let taskListMemory = {
doneTaskCount: 0, doneTaskCount: 0,
totalTaskCount: 0, totalTaskCount: 0,
}; };
@ -855,7 +855,7 @@ async function _addTask(username, userColor, task, oneTaskOnly = false) {
if ( if (
t && t &&
!tasks[username].todos.find( !tasks[username].todos.find(
(task) => task.text === t && !task.completed (task) => task.text === t && !task.done
) && ) &&
!isInt(t) && !isInt(t) &&
t.trim() !== "" && t.trim() !== "" &&
@ -951,9 +951,9 @@ async function _addTask(username, userColor, task, oneTaskOnly = false) {
}; };
} }
function createErrorResponse(errorMessage, errorType) { function createErrorResponse(errorMessage, errorType, status = 0) {
return { return {
status: 0, status: status,
body: { body: {
"error message": errorMessage, "error message": errorMessage,
error: errorType, error: errorType,
@ -1127,13 +1127,10 @@ async function unfocusTask(username) {
async function removeTask(username, task) { async function removeTask(username, task) {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
const incompleteTasks = tasks[username].todos.filter((t) => !t.done); const incompleteTasks = tasks[username].todos.filter((t) => !t.done);
@ -1188,13 +1185,11 @@ async function removeTask(username, task) {
} }
if (tasksRemoved.length === 0) { if (tasksRemoved.length === 0) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
// sort removedTaskIndex in descending order // sort removedTaskIndex in descending order
@ -1241,23 +1236,19 @@ async function removeTask(username, task) {
t.text.toLowerCase() === focusedTask.text.toLowerCase() t.text.toLowerCase() === focusedTask.text.toLowerCase()
); );
} else { } else {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
if (index < 0 || index > tasks[username].todos.length - 1) { if (index < 0 || index > tasks[username].todos.length - 1) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
} }
@ -1277,50 +1268,14 @@ async function removeTask(username, task) {
} }
} }
async function getFocusedTask(username) {
const tasks = await DBHandler.get("tasks");
if (!tasks[username] || tasks[username].todos.length === 0) {
return {
status: 0,
body: {
"error message": `@${username} has no tasks`,
error: getResponse("noTask"),
},
};
}
let focusedTask = tasks[username].todos.find((t) => t.focus);
if (!focusedTask) {
return {
status: 0,
body: {
"error message": `@${username} has no focused task`,
error: getResponse("noFocusedTask"),
},
};
}
return {
status: 200,
body: {
focusedTask: focusedTask.text,
},
};
}
async function checkIfTaskExists(username, task) { async function checkIfTaskExists(username, task) {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
let taskExistsBasedOnText = tasks[username].todos.find( let taskExistsBasedOnText = tasks[username].todos.find(
@ -1345,14 +1300,6 @@ async function checkIfTaskExists(username, task) {
}; };
} }
/**
* This function marks the current task of a user as complete and adds a new task to the user's task list.
*
* @param {string} username - The name of the user who is completing the current task and adding a new one.
* @param {string} task - The text description of the new task to be added.
*
* @returns {Object} - An object containing the status of the operation and a body with either the old and new task or an error message.
*/
/** /**
* This function marks the current task of a user as complete and adds a new task to the user's task list. * This function marks the current task of a user as complete and adds a new task to the user's task list.
* *
@ -1364,23 +1311,18 @@ async function checkIfTaskExists(username, task) {
async function nextTask(username, task) { async function nextTask(username, task) {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
if (task === "") { if (task === "") {
return { return createErrorResponse(
status: 1, `@${username} empty task`,
body: { getResponse("nextNoContent"),
"error message": `@${username} empty task`, 1
error: getResponse("nextNoContent"), );
},
};
} }
const incompleteTasks = tasks[username].todos.filter((t) => !t.done); const incompleteTasks = tasks[username].todos.filter((t) => !t.done);
@ -1392,13 +1334,10 @@ async function nextTask(username, task) {
// check if there's a focused task // check if there's a focused task
if (!focusedTaskExists && incompleteTasks.length > 1) { if (!focusedTaskExists && incompleteTasks.length > 1) {
return { return createErrorResponse(
status: 0, `@${username} does not have a focused task`,
body: { getResponse("noFocusedTask")
"error message": `@${username} does not have a focused task`, );
error: getResponse("noFocusedTask"),
},
};
} else if (textTaskExists || indexTaskExists) { } else if (textTaskExists || indexTaskExists) {
let index = tasks[username].todos.findIndex((t) => t.focus); let index = tasks[username].todos.findIndex((t) => t.focus);
let oldTask = tasks[username].todos[index].text; let oldTask = tasks[username].todos[index].text;
@ -1549,7 +1488,7 @@ async function nextTask(username, task) {
function isInt(value) { function isInt(value) {
return ( return (
!isNaN(value) && !isNaN(value) &&
parseInt(Number(value)) == value && parseInt(Number(value)) === value &&
!isNaN(parseInt(value, 10)) !isNaN(parseInt(value, 10))
); );
} }
@ -1571,13 +1510,10 @@ async function clearOwnDoneTasks(username) {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
let incompleteUserTasks = tasks[username].todos.filter((t) => !t.done); let incompleteUserTasks = tasks[username].todos.filter((t) => !t.done);
@ -1607,25 +1543,19 @@ async function markTaskDone(username, task) {
// user does not have any tasks // user does not have any tasks
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
const incompleteTasks = tasks[username].todos.filter((t) => !t.done); const incompleteTasks = tasks[username].todos.filter((t) => !t.done);
if (incompleteTasks.length === 0) { if (incompleteTasks.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no incomplete tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no incomplete tasks`, );
error: getResponse("noTask"),
},
};
} }
// match regex: integers separated by space e.g. '1 2 3 4' // match regex: integers separated by space e.g. '1 2 3 4'
@ -1687,13 +1617,11 @@ async function markTaskDone(username, task) {
} }
if (tasksMarkedComplete.length === 0) { if (tasksMarkedComplete.length === 0) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
await DBHandler.set("tasks", tasks); await DBHandler.set("tasks", tasks);
@ -1736,24 +1664,20 @@ async function markTaskDone(username, task) {
// index is the first incomplete task // index is the first incomplete task
index = tasks[username].todos.findIndex((t) => !t.done); index = tasks[username].todos.findIndex((t) => !t.done);
} else { } else {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
// index out of range // index out of range
if (index < 0 || index > tasks[username].todos.length - 1) { if (index < 0 || index > tasks[username].todos.length - 1) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
} }
@ -1800,13 +1724,10 @@ async function markAllTasksAsDone(username) {
// user does not have any tasks // user does not have any tasks
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
for (const task of tasks[username].todos) { for (const task of tasks[username].todos) {
@ -1835,13 +1756,10 @@ async function markTaskUndone(username, task) {
// user does not have any tasks // user does not have any tasks
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
const completedTasks = tasks[username].todos.filter((t) => t.done); const completedTasks = tasks[username].todos.filter((t) => t.done);
@ -1895,13 +1813,11 @@ async function markTaskUndone(username, task) {
} }
if (tasksMarkedUndone.length === 0) { if (tasksMarkedUndone.length === 0) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
await DBHandler.set("tasks", tasks); await DBHandler.set("tasks", tasks);
@ -1931,23 +1847,19 @@ async function markTaskUndone(username, task) {
} else if (completedTasks.length === 1) { } else if (completedTasks.length === 1) {
index = tasks[username].todos.findIndex((t) => t.done); index = tasks[username].todos.findIndex((t) => t.done);
} else { } else {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
if (index < 0 || index > tasks[username].todos.length - 1) { if (index < 0 || index > tasks[username].todos.length - 1) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
tasks[username].todos[index].done = false; tasks[username].todos[index].done = false;
@ -1983,7 +1895,6 @@ async function markTaskUndone(username, task) {
}; };
} }
} }
}
/** /**
* Edits a specified task for a given user. If the task is successfully edited, the function returns an object with a status of 200, the original task, and the new task. * Edits a specified task for a given user. If the task is successfully edited, the function returns an object with a status of 200, the original task, and the new task.
@ -1999,13 +1910,10 @@ async function editTask(username, message) {
let noSpecifiedIndex = false; let noSpecifiedIndex = false;
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
let focusedTask = tasks[username].todos.find((t) => t.focus && !t.done); let focusedTask = tasks[username].todos.find((t) => t.focus && !t.done);
@ -2033,13 +1941,11 @@ async function editTask(username, message) {
} }
if (isNaN(index)) { if (isNaN(index)) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
let newTask = message.split(" ").slice(1).join(" "); let newTask = message.split(" ").slice(1).join(" ");
@ -2050,23 +1956,19 @@ async function editTask(username, message) {
// if newTask is empty or whitespace, return 1 // if newTask is empty or whitespace, return 1
if (!newTask || !newTask.trim()) { if (!newTask || !newTask.trim()) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("noTaskContent"),
"error message": `@${username} invalid input`, 1
error: getResponse("noTaskContent"), );
},
};
} }
if (index < 0 || index > tasks[username].todos.length - 1) { if (index < 0 || index > tasks[username].todos.length - 1) {
return { return createErrorResponse(
status: 1, `@${username} invalid input`,
body: { getResponse("specifyTaskIndex"),
"error message": `@${username} invalid input`, 1
error: getResponse("specifyTaskIndex"), );
},
};
} }
let originalTask = tasks[username].todos[index].text; let originalTask = tasks[username].todos[index].text;
@ -2101,13 +2003,10 @@ async function focusedTask(username) {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username] || tasks[username].todos.length === 0) { if (!tasks[username] || tasks[username].todos.length === 0) {
return { return createErrorResponse(
status: 0, `@${username} has no tasks`,
body: { getResponse("noTask")
"error message": `@${username} has no tasks`, );
error: getResponse("noTask"),
},
};
} }
let focusedTask = tasks[username].todos.find((t) => t.focus); let focusedTask = tasks[username].todos.find((t) => t.focus);
@ -2116,13 +2015,10 @@ async function focusedTask(username) {
let index = tasks[username].todos.findIndex((t) => t.focus); let index = tasks[username].todos.findIndex((t) => t.focus);
if (!focusedTask) { if (!focusedTask) {
return { return createErrorResponse(
status: 0, `@${username} has no focused task`,
body: { getResponse("noFocusedTask")
"error message": `@${username} has no focused task`, );
error: getResponse("noFocusedTask"),
},
};
} }
return { return {
@ -2228,12 +2124,6 @@ async function logTask(username, userColor, task) {
}; };
} }
/**
* Checks the tasks of a given user. If the user has tasks, the function returns an object with a status of 200 and a formatted string of the user's tasks. If the user has no tasks, the function returns an object with a status indicating the error and an error message.
*
* @param {string} name - The name of the user whose tasks are to be checked.
* @returns {Object} An object with a status and body. The status is 200 if the user has tasks, and the body contains a formatted string of the user's tasks. If the user has no tasks, the status indicates the error and the body contains an error message.
*/
/** /**
* Checks the tasks of a given user. If the user has tasks, the function returns an object with a status of 200 and a formatted string of the user's tasks. If the user has no tasks, the function returns an object with a status indicating the error and an error message. * Checks the tasks of a given user. If the user has tasks, the function returns an object with a status of 200 and a formatted string of the user's tasks. If the user has no tasks, the function returns an object with a status indicating the error and an error message.
* *

View file

@ -1,9 +1,3 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main-container { #main-container {
width: 100%; width: 100%;
height: 100vh; height: 100vh;