version 3.11

This commit is contained in:
liyunze 2024-10-13 20:49:50 +11:00
parent 6611765c38
commit 16899adee3
3 changed files with 166 additions and 220 deletions

View file

@ -17,6 +17,8 @@ const configs = (function () {
displayTaskCount: true, // true or false displayTaskCount: true, // true or false
enableTaskMaster: true, // true or false enableTaskMaster: true, // true or false
hideWhenNoTasks: true, // true or false hideWhenNoTasks: true, // true or false
taskCharacterLimit: 15, // integer
taskCharacterLimitEnabled: false, // true or false
}; };
const animation = { const animation = {

View file

@ -17,6 +17,8 @@ const defaultConfigs = (function () {
displayTaskCount: true, // true or false displayTaskCount: true, // true or false
enableTaskMaster: true, // true or false enableTaskMaster: true, // true or false
hideWhenNoTasks: true, // true or false hideWhenNoTasks: true, // true or false
taskCharacterLimit: 15, // integer
taskCharacterLimitEnabled: false, // true or false
}; };
const animation = { const animation = {

View file

@ -796,6 +796,34 @@ async function resetUsersCount() {
* @returns {Object} An object with a status and body. The status is 200 if successful, otherwise it indicates the error. The body contains the task text or an error message. * @returns {Object} An object with a status and body. The status is 200 if successful, otherwise it indicates the error. The body contains the task text or an error message.
*/ */
async function addTask(username, userColor, task) { async function addTask(username, userColor, task) {
let addTaskFunction = await _addTask(username, userColor, task);
if (addTaskFunction.status !== 200) {
return addTaskFunction;
}
let addedTaskIndices = addTaskFunction.body.addedTaskIndices;
let tasksFailedToAdd = addTaskFunction.body.tasksFailedToAdd;
if (!scrolling) {
await renderTaskListToDOM();
}
let displayedTasksAdded = addedTaskIndices.map((t) => {
return `(${t.index + 1}) ${t.task}`;
});
return {
status: 200,
body: {
task: displayedTasksAdded.join(`${closeQuote}, ${openQuote}`),
tasksFailedToAdd:
tasksFailedToAdd.join(`${closeQuote}, ${openQuote}`) || "",
},
};
}
async function _addTask(username, userColor, task, oneTaskOnly = false) {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username]) { if (!tasks[username]) {
tasks[username] = { tasks[username] = {
@ -804,18 +832,66 @@ async function addTask(username, userColor, task) {
userColor: userColor, userColor: userColor,
}; };
} }
let tasksFailedToAdd = [];
let addedTaskIndices = []; // new array to store indices of added tasks
if (taskSeparator.some((char) => task.includes(char))) {
if (oneTaskOnly) {
return createErrorResponse(
`@${username} cannot add multiple tasks with now`,
getResponse("noTaskContent")
);
}
const tasksToAdd = task
.split(taskSeparator.find((char) => task.includes(char)))
.map((t) => t.trim());
tasksToAdd.forEach((t) => {
if (
(t &&
!tasks[username].todos.find((task) => task.text === t) &&
!isInt(t) &&
!getSetting("taskCharacterLimitEnabled")) ||
t.length <= getSetting("taskCharacterLimit")
) {
tasks[username].todos.push({
text: t,
done: false,
focus: false,
});
let index = tasks[username].todos.length - 1;
addedTaskIndices.push({ index: index, task: t }); // store index of added task
taskListMemory.totalTaskCount++;
} else {
console.log(
!tasks[username].todos.find((task) => task.text === t)
);
console.log(!isInt(t));
console.log(!getSetting("taskCharacterLimitEnabled"));
console.log(task.length <= getSetting("taskCharacterLimit"));
tasksFailedToAdd.push(t);
}
});
await DBHandler.set("tasks", tasks);
} else {
const taskExists = tasks[username].todos.find( const taskExists = tasks[username].todos.find(
(t) => t.text.toLowerCase() === task.toLowerCase() (t) => t.text.toLowerCase() === task.toLowerCase()
); );
const taskIsInvalid = const taskIsInvalid =
!task || !task.trim() || task.toLowerCase() === "all" || isInt(task); !task ||
const taskLimit = getSetting("limit"); !task.trim() ||
const limitEnabled = getSetting("enableLimit"); task.toLowerCase() === "all" ||
isInt(task);
const taskTooLong =
getSetting("taskCharacterLimitEnabled") &&
task.length > getSetting("taskCharacterLimit");
let incompleteTaskCount = await incompleteTasksCount(username);
const userHasReachedTaskLimit = const userHasReachedTaskLimit =
incompleteTaskCount >= taskLimit && limitEnabled; (await incompleteTasksCount(username)) >= getSetting("limit") &&
getSetting("enableLimit");
if (taskExists) { if (taskExists) {
return createErrorResponse( return createErrorResponse(
@ -840,47 +916,34 @@ async function addTask(username, userColor, task) {
); );
} }
const tasksToAdd = taskSeparator.some((char) => task.includes(char)) if (taskTooLong) {
? task return createErrorResponse(
.split(taskSeparator.find((char) => task.includes(char))) `@${username}'s task is too long`,
.map((t) => t.trim()) getResponse("taskTooLong")
: [task]; );
let tasksFailedToAdd = [];
let addedTaskIndices = []; // new array to store indices of added tasks
tasksToAdd.forEach((t) => {
if (
t &&
!tasks[username].todos.find((task) => task.text === t) &&
!isInt(t) &&
!(incompleteTaskCount >= taskLimit && limitEnabled)
) {
tasks[username].todos.push({ text: t, done: false, focus: false });
let index = tasks[username].todos.length - 1;
addedTaskIndices.push({ index: index, task: t }); // store index of added task
taskListMemory.totalTaskCount++;
incompleteTaskCount++;
} else {
tasksFailedToAdd.push(t);
} }
addedTaskIndices = [
{
index: tasks[username].todos.length,
task: task,
},
];
tasks[username].todos.push({
text: task,
done: false,
focus: false,
}); });
await DBHandler.set("tasks", tasks); await DBHandler.set("tasks", tasks);
if (!scrolling) {
await renderTaskListToDOM();
} }
let displayedTasksAdded = addedTaskIndices.map((t) => {
return `(${t.index + 1}) ${t.task}`;
});
return { return {
status: 200, status: 200,
body: { body: {
task: displayedTasksAdded.join(`${closeQuote}, ${openQuote}`), addedTaskIndices: addedTaskIndices,
tasksFailedToAdd: tasksFailedToAdd: tasksFailedToAdd,
tasksFailedToAdd.join(`${closeQuote}, ${openQuote}`) || "",
}, },
}; };
} }
@ -905,70 +968,22 @@ function createErrorResponse(errorMessage, errorType) {
*/ */
async function nowTask(username, userColor, task) { async function nowTask(username, userColor, task) {
// if task is integer, return error // if task is integer, return error
if (isInt(task)) { let addTaskFunction = await _addTask(username, userColor, task, true);
return createErrorResponse(
`@${username} invalid input`, let addedTaskIndices = addTaskFunction.body.addedTaskIndices;
getResponse("noTaskContent") let addedTaskData = addedTaskIndices[0];
);
if (addTaskFunction.status !== 200) {
return addTaskFunction;
} }
const tasks = await DBHandler.get("tasks"); // focus on it
if (!tasks[username]) { let focusTaskFunction = await focusTask(username, addedTaskData.task);
tasks[username] = {
todos: [], if (focusTaskFunction.status !== 200) {
done: [], return focusTaskFunction;
userColor: userColor,
};
} }
const taskExists = tasks[username].todos.find(
(t) => t.text.toLowerCase() === task.toLowerCase()
);
const taskIsInvalid = !task || !task.trim() || task.toLowerCase() === "all";
const userHasReachedTaskLimit =
(await incompleteTasksCount(username)) >= getSetting("limit") &&
getSetting("enableLimit");
const taskHasSeparators = taskSeparator.some((char) => task.includes(char));
if (taskExists) {
return createErrorResponse(
`@${username} already has this task`,
getResponse("duplicateTask")
);
}
if (taskIsInvalid) {
return createErrorResponse(
`@${username} empty task or reserved keyword used`,
getResponse("noTaskContent")
);
}
if (userHasReachedTaskLimit) {
return createErrorResponse(
`@${username} has reached the limit of ${getSetting(
"limit"
)} tasks`,
getResponse("noTaskAdded")
);
}
if (taskHasSeparators) {
return createErrorResponse(
`@${username} cannot add multiple tasks with now`,
getResponse("noTaskContent")
);
}
tasks[username].todos.forEach((task) => {
task.focus = false;
});
tasks[username].todos.push({ text: task, done: false, focus: true });
let index = tasks[username].todos.length;
taskListMemory.totalTaskCount++;
await DBHandler.set("tasks", tasks);
if (!scrolling) { if (!scrolling) {
await renderTaskListToDOM(); await renderTaskListToDOM();
} }
@ -976,85 +991,7 @@ async function nowTask(username, userColor, task) {
return { return {
status: 200, status: 200,
body: { body: {
task: `(${index}) ${task}`, task: `(${addedTaskData.index + 1}) ${addedTaskData.task}`,
},
};
}
/**
* This function adds a new task to a user's task list and sets it as the currently focused task.
*
* @param {string} username - The name of the user for whom the task is being added.
* @param {string} userColor - The color associated with the user.
* @param {string} task - The text description of the task to be added.
*
* @returns {Object} - An object containing the status of the operation and a body with either the task added or an error message.
*/
async function nowTask(username, userColor, task) {
const tasks = await DBHandler.get("tasks");
if (!tasks[username]) {
tasks[username] = {
todos: [],
done: [],
userColor: userColor,
};
}
const taskExists = tasks[username].todos.find(
(t) => t.text.toLowerCase() === task.toLowerCase()
);
const taskIsInvalid = !task || !task.trim() || task.toLowerCase() === "all";
const userHasReachedTaskLimit =
(await incompleteTasksCount(username)) >= getSetting("limit") &&
getSetting("enableLimit");
const taskHasSeparators = taskSeparator.some((char) => task.includes(char));
if (taskExists) {
return createErrorResponse(
`@${username} already has this task`,
getResponse("duplicateTask")
);
}
if (taskIsInvalid) {
return createErrorResponse(
`@${username} empty task or reserved keyword used`,
getResponse("noTaskContent")
);
}
if (userHasReachedTaskLimit) {
return createErrorResponse(
`@${username} has reached the limit of ${getSetting(
"limit"
)} tasks`,
getResponse("noTaskAdded")
);
}
if (taskHasSeparators) {
return createErrorResponse(
`@${username} cannot add multiple tasks with now`,
getResponse("noTaskContent")
);
}
tasks[username].todos.forEach((task) => {
task.focus = false;
});
tasks[username].todos.push({ text: task, done: false, focus: true });
taskListMemory.totalTaskCount++;
await DBHandler.set("tasks", tasks);
if (!scrolling) {
await renderTaskListToDOM();
}
return {
status: 200,
body: {
task: task,
}, },
}; };
} }
@ -2377,7 +2314,7 @@ async function checkTasks(name, completed = false) {
} }
// 0: user has no tasks // 0: user has no tasks
async function listTasks(username) { async function listTasks(username, separator = ",") {
const tasks = await DBHandler.get("tasks"); const tasks = await DBHandler.get("tasks");
if (!tasks[username]) { if (!tasks[username]) {
return { return {
@ -2388,7 +2325,7 @@ async function listTasks(username) {
}, },
}; };
} }
// filter completed tasks // filter in incomplete tasks
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) {
@ -2402,23 +2339,28 @@ async function listTasks(username) {
} }
// format incomplete tasks into string: 1. task 1 | 2. task 2 | 3. task 3... // format incomplete tasks into string: 1. task 1 | 2. task 2 | 3. task 3...
let replies = [];
let reply = `@${username} `; let reply = `@${username} `;
let taskIndex;
for (let i = 0; i < incompleteTasks.length; i++) { for (let i = 0; i < incompleteTasks.length; i++) {
// get index of task by task name reply += `${incompleteTasks[i].text}${separator} `;
taskIndex =
tasks[username].todos.findIndex( // If 10 tasks have been added to the reply, push it to replies and start a new reply
(t) => if ((i + 1) % 10 === 0) {
t.text.toLowerCase() === replies.push(reply.slice(0, -2)); // Remove the trailing separator and space
incompleteTasks[i].text.toLowerCase() reply = `@${username} `;
) + 1;
reply += `${incompleteTasks[i].text}, `;
} }
reply = reply.slice(0, -2); }
// Push the remaining tasks if any
if (reply !== `@${username} `) {
replies.push(reply.slice(0, -2)); // Remove the trailing separator and space
}
return { return {
status: 200, status: 200,
body: { body: {
reply: reply, replies: replies,
}, },
}; };
} }