organised js
This commit is contained in:
parent
6efe723361
commit
9b9e301076
16 changed files with 1201 additions and 1315 deletions
21
index.html
21
index.html
|
|
@ -9,12 +9,21 @@
|
|||
|
||||
<script src="./auth.js"></script>
|
||||
<script src="./configs.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/processCommand.js"></script>
|
||||
<script defer src="./scripts/index.js"></script>
|
||||
<script defer src="./scripts/taskList.js"></script>
|
||||
<script defer src="./scripts/core/defaultConfigs.js"></script>
|
||||
<script defer src="./scripts/core/constants.js"></script>
|
||||
<script defer src="./scripts/core/functions.js"></script>
|
||||
<script defer src="./scripts/core/db.js"></script>
|
||||
<script defer src="./scripts/core/utils.js"></script>
|
||||
<script defer src="./scripts/ui/styles.js"></script>
|
||||
<script defer src="./scripts/tasks/taskMaster.js"></script>
|
||||
<script defer src="./scripts/tasks/counts.js"></script>
|
||||
<script defer src="./scripts/ui/renderer.js"></script>
|
||||
<script defer src="./scripts/tasks/taskCleanup.js"></script>
|
||||
<script defer src="./scripts/tasks/taskCore.js"></script>
|
||||
<script defer src="./scripts/testing/tests.js"></script>
|
||||
<script defer src="./scripts/chat/processCommand.js"></script>
|
||||
<script defer src="./scripts/chat/index.js"></script>
|
||||
<script defer src="./scripts/ui/taskList.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="./styles/taskList.css" />
|
||||
<link
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
const commands = configs.commands;
|
||||
const openQuote = getSetting("openQuote");
|
||||
const closeQuote = getSetting("closeQuote");
|
||||
|
||||
async function processCommand(user, command, message, flags, extra) {
|
||||
params = {
|
||||
|
|
@ -124,7 +122,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// task unfinished
|
||||
let unfinishedResponse = getResponse("taskUnfinished");
|
||||
|
||||
params.task = `${openQuote}${unfinishRequest.body.markedTasks}${closeQuote}`;
|
||||
|
|
@ -143,7 +140,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// task next
|
||||
let nextResponse = getResponse("taskNext");
|
||||
|
||||
params.oldTask = `${openQuote}${nextRequest.body.oldTask}${closeQuote}`;
|
||||
|
|
@ -158,7 +154,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// task logged
|
||||
let loggedResponse = await getResponse("taskLogged");
|
||||
|
||||
params.task = `${openQuote}${logRequest.body.task}${closeQuote}`;
|
||||
|
|
@ -179,7 +174,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// task focused
|
||||
let focusedResponse = getResponse("nowTask");
|
||||
|
||||
params.task = `${openQuote}${focusRequest.body.focusedTask}${closeQuote}`;
|
||||
|
|
@ -193,7 +187,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// task focused
|
||||
let focusedResponse = getResponse("focusedTask");
|
||||
|
||||
params.task = `${openQuote}${focusedRequest.body.focusedTask}${closeQuote}`;
|
||||
|
|
@ -207,7 +200,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// task unfocused
|
||||
let unfocusedResponse = getResponse("clearFocused");
|
||||
|
||||
respond(unfocusedResponse, params, extra.id);
|
||||
|
|
@ -220,15 +212,12 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
if (message === "") {
|
||||
let checkRequest = await checkTasks(user, completed);
|
||||
if (checkRequest.status !== 200) {
|
||||
// no tasks
|
||||
respond(checkRequest.body.error, params, extra.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// array of filtered tasks
|
||||
let filteredTasks = checkRequest.body.reply.split(" | ");
|
||||
|
||||
// respond every 10 tasks
|
||||
for (let i = 0; i < filteredTasks.length; i += 10) {
|
||||
let tasks = filteredTasks.slice(i, i + 10);
|
||||
params.tasks = tasks
|
||||
|
|
@ -251,17 +240,14 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
|
||||
let checkRequest = await checkTasks(mentioned, completed);
|
||||
|
||||
// array of incomplete tasks
|
||||
let filteredTasks = checkRequest.body.reply.split(" | ");
|
||||
|
||||
if (checkRequest.status !== 200) {
|
||||
// no tasks
|
||||
respond(getResponse("noTaskA"), params, extra.id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// respond every 10 tasks
|
||||
for (let i = 0; i < filteredTasks.length; i += 10) {
|
||||
let tasks = filteredTasks.slice(i, i + 10);
|
||||
params.tasks = tasks
|
||||
|
|
@ -293,7 +279,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
params.mentioned = mentioned;
|
||||
|
||||
if (clearUserTaskResponse.status === 0) {
|
||||
// no tasks
|
||||
respond(getResponse("noTaskA"), params, extra.id);
|
||||
return;
|
||||
}
|
||||
|
|
@ -322,7 +307,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
let clearOwnDoneResponse = await clearOwnDoneTasks(user);
|
||||
|
||||
if (clearOwnDoneResponse.status !== 200) {
|
||||
// no tasks
|
||||
respond(getResponse("noTask"), params, extra.id);
|
||||
return;
|
||||
}
|
||||
|
|
@ -352,7 +336,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
let listTaskResponse = await listTasks(user);
|
||||
|
||||
if (listTaskResponse.status !== 200) {
|
||||
// no tasks
|
||||
respond(listTaskResponse.body.error, params, extra.id);
|
||||
return;
|
||||
}
|
||||
|
|
@ -367,26 +350,20 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
let args = message.split(" ");
|
||||
let anotherUser = true;
|
||||
|
||||
// separate separator from mentioned user
|
||||
if (args[0].length === 1) {
|
||||
// args[0] is separator
|
||||
separator = args[0];
|
||||
args.shift();
|
||||
} else if (args[1] && args[1].length === 1) {
|
||||
// args[1] is separator
|
||||
separator = args[1];
|
||||
args.splice(1, 1);
|
||||
} else {
|
||||
// default, no separator specified
|
||||
}
|
||||
|
||||
let mentioned = args.join(" ").replace("@", "");
|
||||
|
||||
if (args.length === 0) {
|
||||
// no user specified
|
||||
mentioned = user;
|
||||
anotherUser = false;
|
||||
// noTaskA
|
||||
}
|
||||
|
||||
if (mentioned.toLowerCase() === "id") {
|
||||
|
|
@ -397,7 +374,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
let listTaskResponse = await listTasks(mentioned, separator);
|
||||
|
||||
if (listTaskResponse.status !== 200 && anotherUser) {
|
||||
// no tasks
|
||||
respond(getResponse("noTaskA"), params, extra.id);
|
||||
return;
|
||||
} else if (listTaskResponse.status !== 200 && !anotherUser) {
|
||||
|
|
@ -612,7 +588,6 @@ async function processCommand(user, command, message, flags, extra) {
|
|||
return;
|
||||
}
|
||||
|
||||
// check if message is a number using regex
|
||||
if (!/^\d+$/.test(message)) {
|
||||
respond(getResponse("invalidNumber"), params, extra.id);
|
||||
return;
|
||||
165
scripts/core/db.js
Normal file
165
scripts/core/db.js
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
DB structure:
|
||||
|
||||
- tasks
|
||||
- [username]:
|
||||
- todos (array)
|
||||
- [{text, done, focus}, {text, done, focus}]
|
||||
- userColor
|
||||
- counts
|
||||
- users
|
||||
- [username]:
|
||||
- completeCount
|
||||
- points
|
||||
- totalCompleteCount
|
||||
|
||||
- taskmaster
|
||||
- users
|
||||
- [username]:
|
||||
- taskMasterCompleteCount
|
||||
- startDate
|
||||
*/
|
||||
|
||||
let taskListMemory = {
|
||||
doneTaskCount: 0,
|
||||
totalTaskCount: 0,
|
||||
};
|
||||
|
||||
const DBHandler = {
|
||||
db: null,
|
||||
open: function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
let request = indexedDB.open("tasksDB", 1);
|
||||
|
||||
request.onupgradeneeded = function (e) {
|
||||
let db = e.target.result;
|
||||
if (!db.objectStoreNames.contains("tasks")) {
|
||||
db.createObjectStore("tasks", { autoIncrement: true });
|
||||
}
|
||||
};
|
||||
|
||||
request.onsuccess = function (e) {
|
||||
DBHandler.db = e.target.result;
|
||||
resolve();
|
||||
};
|
||||
|
||||
request.onerror = function (e) {
|
||||
console.log("Error opening db", e);
|
||||
reject(e);
|
||||
};
|
||||
});
|
||||
},
|
||||
get: function (key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let transaction = DBHandler.db.transaction(["tasks"], "readonly");
|
||||
let store = transaction.objectStore("tasks");
|
||||
let request = store.get(key);
|
||||
|
||||
request.onsuccess = function (e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
|
||||
request.onerror = function (e) {
|
||||
reject("Error getting item", e);
|
||||
};
|
||||
});
|
||||
},
|
||||
set: function (key, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let transaction = DBHandler.db.transaction(["tasks"], "readwrite");
|
||||
let store = transaction.objectStore("tasks");
|
||||
let request = store.put(value, key);
|
||||
|
||||
request.onsuccess = function (e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
|
||||
request.onerror = function (e) {
|
||||
reject("Error setting item", e);
|
||||
};
|
||||
});
|
||||
},
|
||||
remove: function (key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let transaction = DBHandler.db.transaction(["tasks"], "readwrite");
|
||||
let store = transaction.objectStore("tasks");
|
||||
let request = store.delete(key);
|
||||
|
||||
request.onsuccess = function (e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
|
||||
request.onerror = function (e) {
|
||||
reject("Error removing item", e);
|
||||
};
|
||||
});
|
||||
},
|
||||
clear: function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
let transaction = DBHandler.db.transaction(["tasks"], "readwrite");
|
||||
let store = transaction.objectStore("tasks");
|
||||
let request = store.clear();
|
||||
|
||||
request.onsuccess = function (e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
|
||||
request.onerror = function (e) {
|
||||
reject("Error clearing store", e);
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
async function transferLocalStorageToIndexedDB() {
|
||||
let keys = Object.keys(localStorage);
|
||||
|
||||
for (let key of keys) {
|
||||
let value = JSON.parse(localStorage.getItem(key));
|
||||
await DBHandler.set(key, value);
|
||||
}
|
||||
|
||||
console.log("Transfer complete");
|
||||
|
||||
await renderTaskListToDOM();
|
||||
}
|
||||
|
||||
function clearLocalStorage() {
|
||||
localStorage.removeItem("tasks");
|
||||
localStorage.removeItem("counts");
|
||||
}
|
||||
|
||||
async function resetDB() {
|
||||
await DBHandler.clear();
|
||||
await setupDB();
|
||||
}
|
||||
|
||||
async function setupDB() {
|
||||
const keys = ["tasks", "counts", "taskmaster"];
|
||||
const defaultValues = [
|
||||
{},
|
||||
{ users: {} },
|
||||
{
|
||||
users: {},
|
||||
startDate: new Date(),
|
||||
taskMasterCompleteCount: 0,
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let value = await DBHandler.get(keys[i]);
|
||||
if (!value) {
|
||||
value = defaultValues[i];
|
||||
}
|
||||
await DBHandler.set(keys[i], value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function clearMemory() {
|
||||
taskListMemory = {
|
||||
doneTaskCount: 0,
|
||||
totalTaskCount: 0,
|
||||
};
|
||||
}
|
||||
68
scripts/core/utils.js
Normal file
68
scripts/core/utils.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
function isInt(value) {
|
||||
return (
|
||||
!isNaN(value) &&
|
||||
parseInt(Number(value)) === value &&
|
||||
!isNaN(parseInt(value, 10))
|
||||
);
|
||||
}
|
||||
|
||||
function createErrorResponse(errorMessage, errorType, status = 0) {
|
||||
return {
|
||||
status: status,
|
||||
body: {
|
||||
"error message": errorMessage,
|
||||
error: errorType,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a camelCase string to a CSS variable format.
|
||||
*
|
||||
* @param {string} name - The camelCase string to convert.
|
||||
* @returns {string} The converted string in CSS variable format.
|
||||
*/
|
||||
function convertToCSSVar(name) {
|
||||
let cssVar = name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
||||
return `--${cssVar}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a hexadecimal color value to its RGB equivalent.
|
||||
*
|
||||
* @param {string} hex - The hexadecimal color value. Can be 3 or 6 digits, with or without a leading '#'.
|
||||
* @returns {string} The RGB color value as a string in the format 'r, g, b'.
|
||||
*/
|
||||
function hexToRgb(hex) {
|
||||
// remove # if present
|
||||
if (hex[0] === "#") {
|
||||
hex = hex.slice(1);
|
||||
}
|
||||
|
||||
let r = 0,
|
||||
g = 0,
|
||||
b = 0;
|
||||
|
||||
if (hex.length == 3) {
|
||||
// 3 digits
|
||||
r = "0x" + hex[0] + hex[0];
|
||||
g = "0x" + hex[1] + hex[1];
|
||||
b = "0x" + hex[2] + hex[2];
|
||||
} else if (hex.length == 6) {
|
||||
// 6 digits
|
||||
r = "0x" + hex[0] + hex[1];
|
||||
g = "0x" + hex[2] + hex[3];
|
||||
b = "0x" + hex[4] + hex[5];
|
||||
}
|
||||
|
||||
// integer value of rgb
|
||||
r = +r;
|
||||
g = +g;
|
||||
b = +b;
|
||||
|
||||
return `${r}, ${g}, ${b}`;
|
||||
}
|
||||
402
scripts/tasks/counts.js
Normal file
402
scripts/tasks/counts.js
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
/**
|
||||
* Counts the number of incomplete tasks for a given user.
|
||||
*
|
||||
* @param {string} username - The name of the user whose tasks are to be counted.
|
||||
* @returns {number} The number of incomplete tasks for the user.
|
||||
*/
|
||||
async function incompleteTasksCount(username) {
|
||||
const tasks = await DBHandler.get("tasks");
|
||||
if (!tasks[username]) {
|
||||
return 0;
|
||||
}
|
||||
return tasks[username].todos.filter((t) => !t.done).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of completed tasks for a given user.
|
||||
*
|
||||
* @param {string} username - The name of the user whose tasks are to be counted.
|
||||
* @returns {number} The number of completed tasks for the user.
|
||||
*/
|
||||
async function completedTasksCount(username) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
return 0;
|
||||
}
|
||||
return counts.users[username.toLowerCase()].completeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of tasks for a given user.
|
||||
*
|
||||
* @param {string} username - The name of the user whose tasks are to be counted.
|
||||
* @returns {number} The total number of tasks for the user.
|
||||
*/
|
||||
async function getUserTotalTaskCount(username) {
|
||||
return (
|
||||
(await incompleteTasksCount(username)) +
|
||||
(await completedTasksCount(username))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total points for a given user based on the number of completed tasks and the points per task setting.
|
||||
*
|
||||
* @param {string} username - The name of the user whose points are to be calculated.
|
||||
* @returns {number} The total points for the user.
|
||||
*/
|
||||
async function calculatePoints(username) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (
|
||||
counts.users[username.toLowerCase()].completeCount *
|
||||
getSetting("pointsPerTask")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the points of a specific user from local storage.
|
||||
*
|
||||
* @param {string} username - The name of the user.
|
||||
* @returns {number} The points of the user. If the user does not exist, returns 0.
|
||||
*/
|
||||
async function getUserPoints(username) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return counts.users[username.toLowerCase()].points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a specified value to the completed task count for a given user and the total completed task count.
|
||||
*
|
||||
* @param {string} username - The name of the user whose completed task count is to be incremented.
|
||||
* @param {number} value - The value to be added to the completed task count.
|
||||
*/
|
||||
async function addDoneCount(username, value) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
counts.users[username.toLowerCase()] = {
|
||||
completeCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (!counts.totalCompleteCount) {
|
||||
counts.totalCompleteCount = 0;
|
||||
}
|
||||
|
||||
counts.users[username.toLowerCase()].completeCount += value;
|
||||
counts.totalCompleteCount += value;
|
||||
taskListMemory.doneTaskCount += value;
|
||||
|
||||
// check if user has points
|
||||
if (!counts.users[username.toLowerCase()].points) {
|
||||
counts.users[username.toLowerCase()].points = 0;
|
||||
}
|
||||
|
||||
// add to points
|
||||
counts.users[username.toLowerCase()].points +=
|
||||
value * getSetting("pointsPerTask");
|
||||
|
||||
// add to taskmaster
|
||||
addCountToTaskMasterUser(username, value);
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the completed task count for a given user.
|
||||
*
|
||||
* @param {string} username
|
||||
* @param {int} value
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains a success message.
|
||||
*/
|
||||
async function setUserCompleteCount(username, value) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
counts.users[username.toLowerCase()] = {
|
||||
completeCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
counts.users[username.toLowerCase()].completeCount = parseInt(value);
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: `Successfully set ${username}'s complete count to ${value}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total count of completed tasks in local storage.
|
||||
*
|
||||
* @param {number} value - The new total count of completed tasks.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains a success message.
|
||||
*/
|
||||
async function setTotalCompleteCount(value) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
counts.totalCompleteCount = parseInt(value);
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: `Successfully set total complete count to ${value}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a specified number of points to a user's total in local storage.
|
||||
*
|
||||
* @param {string} username - The name of the user.
|
||||
* @param {number} value - The number of points to add.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains a success message.
|
||||
*/
|
||||
async function addPoints(username, value) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
counts.users[username.toLowerCase()] = {
|
||||
points: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (!counts.users[username.toLowerCase()].points) {
|
||||
counts.users[username.toLowerCase()].points = 0;
|
||||
}
|
||||
|
||||
counts.users[username.toLowerCase()].points += value;
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: `Successfully added ${value} points to ${username}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the points for a specific user in local storage.
|
||||
*
|
||||
* @param {string} username - The name of the user.
|
||||
* @param {number} pointsCount - The new points count for the user.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains a success message.
|
||||
*/
|
||||
async function setUserPoints(username, pointsCount) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
counts.users[username.toLowerCase()] = {
|
||||
points: 0,
|
||||
};
|
||||
}
|
||||
|
||||
counts.users[username.toLowerCase()].points = pointsCount;
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: `Successfully set ${username}'s points to ${pointsCount}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces a specified number of points from a user's total in local storage.
|
||||
*
|
||||
* @param {string} username - The name of the user.
|
||||
* @param {number} value - The number of points to reduce.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains a success message.
|
||||
*/
|
||||
async function reducePoints(username, value) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
counts.users[username.toLowerCase()] = {
|
||||
points: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (!counts.users[username.toLowerCase()].points) {
|
||||
counts.users[username.toLowerCase()].points = 0;
|
||||
}
|
||||
|
||||
counts.users[username.toLowerCase()].points -= parseInt(value);
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: `Successfully reduced ${username}'s points by ${value}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the total count of tasks from the board.
|
||||
*
|
||||
* @returns {number} The total count of tasks. If no tasks are found, returns 0.
|
||||
*/
|
||||
async function getBoardTotalTaskCount() {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.totalCompleteCount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return counts.totalCompleteCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the task count for a specific user in local storage and returns a success message.
|
||||
*
|
||||
* @param {string} username - The name of the user.
|
||||
* @param {number} value - The new task count for the user.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains a success message.
|
||||
*/
|
||||
async function setUserTaskCount(username, value) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
if (!counts.users[username.toLowerCase()]) {
|
||||
counts.users[username.toLowerCase()] = {
|
||||
completeCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (!counts.users[username.toLowerCase()].completeCount) {
|
||||
counts.users[username.toLowerCase()].completeCount = 0;
|
||||
}
|
||||
|
||||
counts.users[username.toLowerCase()].completeCount = parseInt(value);
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: `Successfully set ${username}'s task count to ${value}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes the points of each user with their task count in local storage. After the synchronization, the function returns an object with a status of 200 and a success message.
|
||||
*
|
||||
* @returns {Object} An object with a status and body. The status is 200 if the synchronization is successful, and the body contains a success message.
|
||||
*/
|
||||
async function syncPointsToCount() {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
for (const user in counts.users) {
|
||||
counts.users[user].points = calculatePoints(user);
|
||||
}
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: "Successfully synced counts to points",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the leaderboard of users based on task count.
|
||||
*
|
||||
* @param {number} limit - The maximum number of users to include in the leaderboard.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if successful, and the body contains an array of user objects, each with a username and task count, sorted in descending order of task count.
|
||||
*/
|
||||
async function leaderboardTaskCount(limit) {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
let leaderboardArray = [];
|
||||
|
||||
for (const user in counts.users) {
|
||||
let userTaskCount = await completedTasksCount(user);
|
||||
|
||||
leaderboardArray.push({
|
||||
username: user,
|
||||
taskCount: userTaskCount,
|
||||
});
|
||||
}
|
||||
|
||||
leaderboardArray.sort((a, b) => b.taskCount - a.taskCount);
|
||||
|
||||
// shorten to limit
|
||||
leaderboardArray = leaderboardArray.slice(0, limit);
|
||||
|
||||
let leaderboardstring = "";
|
||||
|
||||
leaderboardArray.map((user, index) => {
|
||||
leaderboardstring += `${index + 1}. @${user.username} : ${
|
||||
user.taskCount
|
||||
} | `;
|
||||
});
|
||||
|
||||
leaderboardstring = leaderboardstring.slice(0, -3);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
leaderboard: leaderboardstring,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the total count of completed tasks in the board to zero.
|
||||
*/
|
||||
async function resetBoardCount() {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
counts.totalCompleteCount = 0;
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: "Successfully reset board count",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task count for all users.
|
||||
*/
|
||||
async function resetUsersCount() {
|
||||
const counts = await DBHandler.get("counts");
|
||||
|
||||
counts.users = {};
|
||||
|
||||
await DBHandler.set("counts", counts);
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: "Successfully reset users count",
|
||||
},
|
||||
};
|
||||
}
|
||||
140
scripts/tasks/taskCleanup.js
Normal file
140
scripts/tasks/taskCleanup.js
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/**
|
||||
* Clears all completed tasks for a given user. If the tasks are successfully cleared, the function returns an object with a status of 200. If the tasks are not cleared due to the user having no tasks, the function returns an object with a status indicating the error and an error message.
|
||||
*
|
||||
* @param {string} username - The name of the user whose completed tasks are to be cleared.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if the tasks are successfully cleared. If the tasks are not cleared, the status indicates the error and the body contains an error message.
|
||||
*/
|
||||
async function clearOwnDoneTasks(username) {
|
||||
const tasks = await DBHandler.get("tasks");
|
||||
|
||||
if (!tasks[username] || tasks[username].todos.length === 0) {
|
||||
return createErrorResponse(
|
||||
`@${username} has no tasks`,
|
||||
getResponse("noTask")
|
||||
);
|
||||
}
|
||||
|
||||
let incompleteUserTasks = tasks[username].todos.filter((t) => !t.done);
|
||||
|
||||
// replace user's task with incomplete tasks
|
||||
tasks[username].todos = incompleteUserTasks;
|
||||
|
||||
await DBHandler.set("tasks", tasks);
|
||||
if (!scrolling) {
|
||||
await renderTaskListToDOM();
|
||||
}
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all tasks for a given user. If the tasks are successfully cleared, the function returns an object with a status of 200.
|
||||
* If the tasks are not cleared due to the user having no tasks, the function returns an object with a status indicating the error and an error message.
|
||||
*
|
||||
* @param {string} username - The name of the user whose tasks are to be cleared.
|
||||
* @returns {Object} An object with a status and body. The status is 200 if the tasks are successfully cleared. If the tasks are not cleared, the status indicates the error and the body contains an error message.
|
||||
*/
|
||||
async function clearUserTasks(username) {
|
||||
const tasks = await DBHandler.get("tasks");
|
||||
// find username where lowercase matches username
|
||||
username = Object.keys(tasks).find(
|
||||
(user) => user.toLowerCase() === username.toLowerCase()
|
||||
);
|
||||
|
||||
if (!username) {
|
||||
return {
|
||||
status: 0,
|
||||
body: {
|
||||
"error message": `@${username} has no tasks`,
|
||||
error: getResponse("noTask"),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
tasks[username].todos = [];
|
||||
|
||||
await DBHandler.set("tasks", tasks);
|
||||
|
||||
if (!scrolling) {
|
||||
await renderTaskListToDOM();
|
||||
}
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all completed tasks for all users. If the tasks are successfully cleared, the function returns an object with a status of 200. If there are no tasks to clear, the function still returns an object with a status of 200 as it's considered a successful operation.
|
||||
*
|
||||
* @returns {Object} An object with a status. The status is 200 if the tasks are successfully cleared.
|
||||
*/
|
||||
async function clearAllDoneTasks() {
|
||||
const tasks = await DBHandler.get("tasks");
|
||||
for (const user in tasks) {
|
||||
if (!tasks[user].todos) continue;
|
||||
if (user.toLowerCase() === "id") continue;
|
||||
tasks[user].todos = tasks[user].todos.filter((t) => !t.done);
|
||||
}
|
||||
cancelAnimation();
|
||||
await DBHandler.set("tasks", tasks);
|
||||
await renderTaskListToDOM();
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
|
||||
async function clearAllTasks() {
|
||||
await DBHandler.set("tasks", {});
|
||||
await setupDB();
|
||||
cancelAnimation();
|
||||
await renderTaskListToDOM();
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
|
||||
async function clearAll() {
|
||||
await resetDB();
|
||||
cancelAnimation();
|
||||
checkToAnimate();
|
||||
await renderTaskListToDOM();
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all tasks from the local storage except for those belonging to specified streamer usernames.
|
||||
* After clearing, it also clears all done tasks, cancels any ongoing animation and re-renders the task list to the DOM.
|
||||
*
|
||||
* @param {string[]} streamerUsername - An array of streamer usernames whose tasks should not be cleared.
|
||||
* @returns {Object} An object with a status property indicating the success of the operation (200 for success).
|
||||
*/
|
||||
async function clearAllExceptStreamer(streamerUsername) {
|
||||
const tasks = await DBHandler.get("tasks");
|
||||
|
||||
for (const user in tasks) {
|
||||
if (user.toLowerCase() === "id") continue;
|
||||
if (user.toLowerCase() !== streamerUsername.toLowerCase()) {
|
||||
tasks[user].todos = [];
|
||||
}
|
||||
}
|
||||
|
||||
await DBHandler.set("tasks", tasks);
|
||||
|
||||
await clearAllDoneTasks();
|
||||
|
||||
cancelAnimation();
|
||||
|
||||
await renderTaskListToDOM();
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
72
scripts/tasks/taskMaster.js
Normal file
72
scripts/tasks/taskMaster.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* adds a count to user for 'taskmaster'
|
||||
*
|
||||
* @param {string} username
|
||||
*/
|
||||
async function addCountToTaskMasterUser(username, count) {
|
||||
const taskmaster = await DBHandler.get("taskmaster");
|
||||
|
||||
if (!taskmaster.users[username.toLowerCase()]) {
|
||||
taskmaster.users[username.toLowerCase()] = {
|
||||
taskMasterCompleteCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
taskmaster.users[username.toLowerCase()].taskMasterCompleteCount +=
|
||||
parseInt(count);
|
||||
|
||||
await DBHandler.set("taskmaster", taskmaster);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the count of a user from 'taskmaster'
|
||||
*
|
||||
* @param {string} username
|
||||
* @returns {number} the count of the user
|
||||
*/
|
||||
async function getUserTaskMasterCount(username) {
|
||||
const taskmaster = await DBHandler.get("taskmaster");
|
||||
|
||||
if (!taskmaster.users[username.toLowerCase()]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return taskmaster.users[username.toLowerCase()].taskMasterCompleteCount;
|
||||
}
|
||||
|
||||
async function getTaskMasterChampion() {
|
||||
const taskmaster = await DBHandler.get("taskmaster");
|
||||
|
||||
if (!taskmaster.users) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let champion = {
|
||||
username: "",
|
||||
count: 0,
|
||||
};
|
||||
|
||||
for (const user in taskmaster.users) {
|
||||
if (
|
||||
user.toLowerCase() !== auth.channel.toLowerCase() &&
|
||||
taskmaster.users[user].taskMasterCompleteCount > champion.count
|
||||
) {
|
||||
champion.username = user;
|
||||
champion.count = taskmaster.users[user].taskMasterCompleteCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (champion.count === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return champion;
|
||||
}
|
||||
|
||||
async function resetTaskMaster() {
|
||||
await DBHandler.set("taskmaster", {
|
||||
users: {},
|
||||
startDate: new Date(),
|
||||
totalCompleteCount: 0,
|
||||
});
|
||||
}
|
||||
27
scripts/testing/tests.js
Normal file
27
scripts/testing/tests.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
function randomTasks(num) {
|
||||
let tasks = [];
|
||||
for (let i = 0; i < num; i++) {
|
||||
tasks.push(`task ${i + 1}`);
|
||||
}
|
||||
|
||||
return tasks.join(", ");
|
||||
}
|
||||
|
||||
async function tests() {
|
||||
let listOfStreamers = [
|
||||
`followRythonDev1`,
|
||||
`followRythonDev2`,
|
||||
`followRythonDev3`,
|
||||
`followRythonDev4`,
|
||||
`followRythonDev5`,
|
||||
`followRythonDev6`,
|
||||
`followRythonDev7`,
|
||||
];
|
||||
|
||||
for (let i = 0; i < listOfStreamers.length; i++) {
|
||||
let randomNum = Math.floor(Math.random() * 10) + 1;
|
||||
|
||||
addTask(listOfStreamers[i], "#ffc0cb", randomTasks(randomNum));
|
||||
await sleep(1000);
|
||||
}
|
||||
}
|
||||
180
scripts/ui/renderer.js
Normal file
180
scripts/ui/renderer.js
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
async function renderTaskListToDOM() {
|
||||
const tasks = await DBHandler.get("tasks");
|
||||
|
||||
const taskContainers = document.querySelectorAll(".task-container");
|
||||
|
||||
let hasTasks = false;
|
||||
|
||||
taskContainers.forEach((taskList) => {
|
||||
taskList.innerHTML = "";
|
||||
|
||||
let totalTaskCount = 0;
|
||||
let completedTasksCount = 0;
|
||||
|
||||
for (const user in tasks) {
|
||||
if (user.toLowerCase() === "id") continue;
|
||||
if (!tasks[user].todos) continue;
|
||||
|
||||
const userTasks = tasks[user];
|
||||
|
||||
if (userTasks.todos.length === 0) {
|
||||
// remove user from tasks
|
||||
delete tasks[user];
|
||||
continue;
|
||||
}
|
||||
|
||||
const userColor = userTasks.userColor;
|
||||
|
||||
const taskDiv = document.createElement("div");
|
||||
taskDiv.classList.add("task");
|
||||
taskList.appendChild(taskDiv);
|
||||
|
||||
const usernameDiv = document.createElement("div");
|
||||
usernameDiv.classList.add("username");
|
||||
usernameDiv.innerText = user;
|
||||
|
||||
if (styles.usernameColor === "") {
|
||||
usernameDiv.style.color = userColor;
|
||||
} else {
|
||||
usernameDiv.style.color = styles.usernameColor;
|
||||
}
|
||||
|
||||
taskDiv.appendChild(usernameDiv);
|
||||
|
||||
const olListDiv = document.createElement("ol");
|
||||
olListDiv.classList.add("user-tasks");
|
||||
taskDiv.appendChild(olListDiv);
|
||||
|
||||
for (const task of userTasks.todos) {
|
||||
const taskElement = document.createElement("li");
|
||||
taskElement.classList.add("todo");
|
||||
|
||||
totalTaskCount++;
|
||||
|
||||
if (task.done) {
|
||||
taskElement.classList.add("done");
|
||||
completedTasksCount++;
|
||||
} else if (task.focus) {
|
||||
taskElement.classList.add("focus");
|
||||
}
|
||||
|
||||
const taskContent = document.createElement("div");
|
||||
taskContent.classList.add("content");
|
||||
|
||||
taskContent.innerText = task.text;
|
||||
|
||||
taskElement.appendChild(taskContent);
|
||||
olListDiv.appendChild(taskElement);
|
||||
|
||||
hasTasks = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (taskListMemory.doneTaskCount > completedTasksCount) {
|
||||
completedTasksCount = taskListMemory.doneTaskCount;
|
||||
totalTaskCount = taskListMemory.totalTaskCount;
|
||||
}
|
||||
|
||||
if (totalTaskCount < completedTasksCount) {
|
||||
totalTaskCount = completedTasksCount;
|
||||
}
|
||||
|
||||
document.querySelector(
|
||||
".task-count"
|
||||
).innerText = `${completedTasksCount}/${totalTaskCount}`;
|
||||
|
||||
taskListMemory.doneTaskCount = completedTasksCount;
|
||||
taskListMemory.totalTaskCount = totalTaskCount;
|
||||
});
|
||||
|
||||
if (getSetting("hideWhenNoTasks") && !hasTasks) {
|
||||
document.querySelector("#main-container").style.opacity = "0";
|
||||
visible = false;
|
||||
} else if (getSetting("hideWhenNoTasks") && hasTasks && !visible) {
|
||||
document.querySelector("#main-container").style.opacity = "1";
|
||||
visible = true;
|
||||
}
|
||||
|
||||
await DBHandler.set("tasks", tasks);
|
||||
|
||||
checkToAnimate();
|
||||
}
|
||||
|
||||
async function checkToAnimate() {
|
||||
let taskContainer = document.querySelector(".task-container");
|
||||
let taskContainerHeight = taskContainer.scrollHeight;
|
||||
|
||||
let taskWrapper = document.querySelector(".task-wrapper");
|
||||
let taskWrapperHeight = taskWrapper.clientHeight;
|
||||
|
||||
let secondary = document.querySelector(".secondary");
|
||||
|
||||
if (taskContainerHeight > taskWrapperHeight && !scrolling) {
|
||||
if (!scrolling) {
|
||||
secondary.style.display = "flex";
|
||||
|
||||
let finalHeight =
|
||||
taskContainerHeight + configs.animation.gapBetweenScrolls;
|
||||
|
||||
let keyframes = [
|
||||
{ transform: `translateY(0)` },
|
||||
{ transform: `translateY(-${finalHeight}px)` },
|
||||
];
|
||||
let scrollingSpeed = (finalHeight / scrollSpeed) * 1000;
|
||||
|
||||
let options = {
|
||||
duration: scrollingSpeed,
|
||||
iterations: 1,
|
||||
easing: "linear",
|
||||
};
|
||||
|
||||
primaryAnimation = document
|
||||
.querySelector(".primary")
|
||||
.animate(keyframes, options);
|
||||
|
||||
secondaryAnimation = document
|
||||
.querySelector(".secondary")
|
||||
.animate(keyframes, options);
|
||||
|
||||
primaryAnimation.play();
|
||||
secondaryAnimation.play();
|
||||
|
||||
scrolling = true;
|
||||
|
||||
addAnimationListeners();
|
||||
}
|
||||
} else if (!scrolling) {
|
||||
secondary.style.display = "none";
|
||||
|
||||
if (primaryAnimation) {
|
||||
primaryAnimation.cancel();
|
||||
}
|
||||
if (secondaryAnimation) {
|
||||
secondaryAnimation.cancel();
|
||||
}
|
||||
scrolling = false;
|
||||
}
|
||||
}
|
||||
|
||||
function addAnimationListeners() {
|
||||
if (primaryAnimation) {
|
||||
primaryAnimation.addEventListener("finish", animationFinished);
|
||||
primaryAnimation.addEventListener("cancel", animationFinished);
|
||||
}
|
||||
}
|
||||
|
||||
async function animationFinished() {
|
||||
scrolling = false;
|
||||
await renderTaskListToDOM();
|
||||
checkToAnimate();
|
||||
}
|
||||
|
||||
function cancelAnimation() {
|
||||
if (primaryAnimation) {
|
||||
primaryAnimation.cancel();
|
||||
}
|
||||
if (secondaryAnimation) {
|
||||
secondaryAnimation.cancel();
|
||||
}
|
||||
scrolling = false;
|
||||
}
|
||||
94
scripts/ui/styles.js
Normal file
94
scripts/ui/styles.js
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
function loadGoogleFont(font) {
|
||||
WebFont.load({
|
||||
google: {
|
||||
families: [font],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* import styles from configs
|
||||
*/
|
||||
function importStyles() {
|
||||
const styles = configs.styles;
|
||||
|
||||
// fonts
|
||||
if (getSetting("headerGoogleFont")) {
|
||||
loadGoogleFont(styles.headerFontFamily);
|
||||
}
|
||||
if (getSetting("taskGoogleFont")) {
|
||||
loadGoogleFont(styles.taskFontFamily);
|
||||
}
|
||||
|
||||
document.documentElement.style.setProperty(
|
||||
"--gap-between-scrolls",
|
||||
`${configs.animation.gapBetweenScrolls}px` ?? "0px"
|
||||
);
|
||||
|
||||
const stylesToImport = Object.keys(styles).filter((style) => {
|
||||
return !style.includes("Background");
|
||||
});
|
||||
|
||||
stylesToImport.forEach((style) => {
|
||||
document.documentElement.style.setProperty(
|
||||
convertToCSSVar(style),
|
||||
styles[style]
|
||||
);
|
||||
});
|
||||
|
||||
let backgroundStyles = Object.keys(styles).filter((style) => {
|
||||
return style.includes("Background");
|
||||
});
|
||||
|
||||
// use regex to filter out after "Background"
|
||||
backgroundStyles = backgroundStyles.map((style) => {
|
||||
return style.replace(/Background.*/, "");
|
||||
});
|
||||
|
||||
// loop through backgroundstyles
|
||||
backgroundStyles.forEach((style) => {
|
||||
// get background color and opacity
|
||||
let backgroundColor = styles[`${style}BackgroundColor`];
|
||||
let backgroundOpacity = styles[`${style}BackgroundOpacity`];
|
||||
|
||||
let cssStyle = convertToCSSVar(style);
|
||||
|
||||
// set background color
|
||||
document.documentElement.style.setProperty(
|
||||
`${cssStyle}-background-color`,
|
||||
`rgba(${hexToRgb(backgroundColor)}, ${backgroundOpacity})`
|
||||
);
|
||||
});
|
||||
|
||||
if (!getSetting("displayTaskCount")) {
|
||||
document.querySelector(".task-count").style.display = "none";
|
||||
}
|
||||
|
||||
let currentTitle = 0;
|
||||
// interval the task title
|
||||
setInterval(async () => {
|
||||
let taskTitle = document.querySelector(".title");
|
||||
|
||||
// cycle through a list of titles
|
||||
let titles = configs.animation.titles;
|
||||
|
||||
// if current title is the last title, set it to the first title
|
||||
if (currentTitle === titles.length - 1) {
|
||||
currentTitle = 0;
|
||||
} else {
|
||||
currentTitle++;
|
||||
}
|
||||
|
||||
// on change title, add fade animation
|
||||
taskTitle.classList.add("fade");
|
||||
await sleep(500);
|
||||
|
||||
// set new title
|
||||
taskTitle.innerText = titles[currentTitle];
|
||||
|
||||
await sleep(100);
|
||||
|
||||
// remove fade animation
|
||||
taskTitle.classList.remove("fade");
|
||||
}, 8000);
|
||||
}
|
||||
23
scripts/ui/taskList.js
Normal file
23
scripts/ui/taskList.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
const styles = configs.styles;
|
||||
const scrollSpeed = configs.animation.scrollSpeed;
|
||||
let openQuote = getSetting("openQuote");
|
||||
let closeQuote = getSetting("closeQuote");
|
||||
let visible = false;
|
||||
let scrolling = false;
|
||||
let primaryAnimation, secondaryAnimation;
|
||||
const taskSeparator = getSetting("taskSeparator");
|
||||
|
||||
DBHandler.open()
|
||||
.then(async () => {
|
||||
await setupDB();
|
||||
importStyles();
|
||||
if (getSetting("testTasks")) {
|
||||
await resetDB();
|
||||
await tests();
|
||||
}
|
||||
|
||||
await renderTaskListToDOM();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error opening database:", error);
|
||||
});
|
||||
Loading…
Reference in a new issue