upgraded commands, new command, fixed bugs
- finish / remove multiple tasks in 1 command - fixed add task to satisfy incomplete task limit - "!clearns" clears all tasks except streamer's incomplete tasks - animations will cancel and restart upon any "clear" commands except clearmydone
This commit is contained in:
parent
b5b2d9d7e2
commit
971e41502f
3 changed files with 283 additions and 91 deletions
19
configs.js
19
configs.js
|
|
@ -3,7 +3,7 @@ const configs = (function () {
|
|||
|
||||
// settings
|
||||
const enableLimit = true; // true or false
|
||||
const limit = 20; // integer
|
||||
const limit = 5; // integer
|
||||
|
||||
// animation
|
||||
const scrollSpeed = 30; // milliseconds (DO NOT PUT BELOW 5, COMPUTER MIGHT CRASH) the lower the value, the faster the scroll
|
||||
|
|
@ -149,6 +149,14 @@ const configs = (function () {
|
|||
"!help",
|
||||
];
|
||||
|
||||
// Admin clear all except streamer - please add commands following the exact format
|
||||
const adminClearNotStreamerCommands = [
|
||||
"!clearnotstreamer",
|
||||
"!aclearnotstreamer",
|
||||
"!adminclearnotstreamer",
|
||||
"!clearns",
|
||||
];
|
||||
|
||||
// Admin delete - please add commands following the exact format
|
||||
const adminDeleteCommands = [
|
||||
"!taskadel",
|
||||
|
|
@ -179,14 +187,17 @@ 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 "{task}" has been deleted successfully, {user}';
|
||||
const specifyTaskIndex = "Try specifying the index of the task {user}";
|
||||
|
||||
const duplicateTask =
|
||||
"Looks like you already have the task '{message}' up there {user}!";
|
||||
|
||||
const clearTasksExceptBroadcaster =
|
||||
"All tasks have been cleared except for the streamer's, {user}!";
|
||||
|
||||
const adminDeleteTasks = "All of {mentioned}'s tasks have been deleted";
|
||||
const taskFinished = "Good job on finishing the task '{task}', {user}!";
|
||||
const taskFinished = 'Good job on finishing the task "{task}", {user}!';
|
||||
const taskEdited =
|
||||
"Task '{originalTask}' has been edited to '{task}' successfully, {user}";
|
||||
const noTaskEdit = "Try doing !edit [index] [new task] {user}";
|
||||
|
|
@ -283,6 +294,7 @@ const configs = (function () {
|
|||
checkCommands,
|
||||
clearMyDoneCommands,
|
||||
adminDeleteCommands,
|
||||
adminClearNotStreamerCommands,
|
||||
adminClearDoneCommands,
|
||||
adminClearAllCommands,
|
||||
additionalCommands,
|
||||
|
|
@ -302,6 +314,7 @@ const configs = (function () {
|
|||
noTaskA,
|
||||
notMod,
|
||||
help,
|
||||
clearTasksExceptBroadcaster,
|
||||
adminDeleteTasks,
|
||||
clearedMyDone,
|
||||
clearedAll,
|
||||
|
|
|
|||
|
|
@ -42,9 +42,15 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => {
|
|||
// task has no content
|
||||
respond(responses.noTaskContent, params);
|
||||
} else {
|
||||
params.task = addStatus;
|
||||
let addResponse = responses.taskAdded;
|
||||
params.task = addStatus.task;
|
||||
|
||||
if (addStatus.tasksFailedToAdd !== "") {
|
||||
addResponse += ` | Failed to add task(s): "${addStatus.tasksFailedToAdd}"`;
|
||||
}
|
||||
|
||||
// task added
|
||||
respond(responses.taskAdded, params);
|
||||
respond(addResponse, params);
|
||||
}
|
||||
} else if (commands.editTaskCommands.includes(command)) {
|
||||
let editStatus = editTask(user, message);
|
||||
|
|
@ -71,8 +77,14 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => {
|
|||
respond(responses.specifyTaskIndex, params);
|
||||
} else {
|
||||
// task deleted
|
||||
params.task = removeStatus;
|
||||
respond(responses.taskDeleted, params);
|
||||
let deletedResponse = responses.taskDeleted;
|
||||
params.task = removeStatus.removedTasks;
|
||||
|
||||
if (removeStatus.failedTasks !== "") {
|
||||
deletedResponse += ` | Failed to delete task(s): "${removeStatus.failedTasks}"`;
|
||||
}
|
||||
|
||||
respond(deletedResponse, params);
|
||||
}
|
||||
} else if (commands.finishTaskCommands.includes(command)) {
|
||||
let finishStatus = markTaskDone(user, message);
|
||||
|
|
@ -85,8 +97,15 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => {
|
|||
respond(responses.specifyTaskIndex, params);
|
||||
} else {
|
||||
// task finished
|
||||
params.task = finishStatus;
|
||||
respond(responses.taskFinished, params);
|
||||
let finishedResponse = responses.taskFinished;
|
||||
|
||||
params.task = finishStatus.markedTasks;
|
||||
|
||||
if (finishStatus.failedTasks !== "") {
|
||||
finishedResponse += ` | Failed to finish task(s): "${finishStatus.failedTasks}"`;
|
||||
}
|
||||
|
||||
respond(finishedResponse, params);
|
||||
}
|
||||
} else if (commands.checkCommands.includes(command)) {
|
||||
if (message === "") {
|
||||
|
|
@ -137,7 +156,7 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => {
|
|||
respond(responses.clearedAll, params);
|
||||
}
|
||||
} else if (commands.clearMyDoneCommands.includes(command)) {
|
||||
let response = markOwnTaskDone(user);
|
||||
let response = clearOwnDoneTasks(user);
|
||||
|
||||
if (response === 0) {
|
||||
// no tasks
|
||||
|
|
@ -146,6 +165,9 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => {
|
|||
}
|
||||
|
||||
respond(responses.clearedMyDone, params);
|
||||
} else if (commands.adminClearNotStreamerCommands.includes(command)) {
|
||||
clearAllExceptStreamer(auth.channel);
|
||||
respond(responses.clearTasksExceptBroadcaster, params);
|
||||
} else if (commands.helpCommands.includes(command)) {
|
||||
respond(responses.help, params);
|
||||
} else if (commands.additionalCommands[command]) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const settings = configs.settings;
|
|||
const styles = configs.styles;
|
||||
const scrollSpeed = configs.animation.scrollSpeed;
|
||||
let scrolling = false;
|
||||
let primaryAnimation, secondaryAnimation;
|
||||
|
||||
function loadGoogleFont(font) {
|
||||
WebFont.load({
|
||||
|
|
@ -183,22 +184,47 @@ function addTask(username, userColor, task) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
let tasksFailedToAdd = [];
|
||||
|
||||
// if task has commas
|
||||
if (task.includes(",")) {
|
||||
let tasksToAdd = task.split(",").map((t) => t.trim());
|
||||
|
||||
if (
|
||||
incompleteTasksCount(username) + tasksToAdd.length >
|
||||
settings.limit &&
|
||||
settings.enableLimit
|
||||
) {
|
||||
tasksFailedToAdd = tasksToAdd.slice(
|
||||
settings.limit - incompleteTasksCount(username),
|
||||
tasksToAdd.length
|
||||
);
|
||||
|
||||
tasksToAdd = tasksToAdd.slice(
|
||||
0,
|
||||
settings.limit - incompleteTasksCount(username)
|
||||
);
|
||||
}
|
||||
|
||||
for (const t of tasksToAdd) {
|
||||
tasks[username].todos.push({ text: t, done: false });
|
||||
}
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
return tasksToAdd.join('", "');
|
||||
return {
|
||||
task: tasksToAdd.join('", "'),
|
||||
tasksFailedToAdd: tasksFailedToAdd.join('", "') || "",
|
||||
};
|
||||
}
|
||||
|
||||
tasks[username].todos.push({ text: task, done: false });
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
|
||||
return task;
|
||||
return {
|
||||
task: task,
|
||||
tasksFailedToAdd: "",
|
||||
};
|
||||
}
|
||||
|
||||
// 0: user has no tasks
|
||||
|
|
@ -206,32 +232,103 @@ function addTask(username, userColor, task) {
|
|||
// removed task: success
|
||||
function removeTask(username, task) {
|
||||
const tasks = JSON.parse(localStorage.tasks);
|
||||
const incompleteTasks = tasks[username].todos.filter((t) => !t.done);
|
||||
|
||||
if (!tasks[username] || tasks[username].todos.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
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 (tasks[username].todos.length === 1) {
|
||||
index = 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (index < 0 || index > tasks[username].todos.length - 1) {
|
||||
return 1;
|
||||
}
|
||||
// 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 removedTask = tasks[username].todos[index].text;
|
||||
let removedTaskIndex = [];
|
||||
let tasksRemoved = [];
|
||||
let tasksFailedToRemove = [];
|
||||
|
||||
tasks[username].todos.splice(index, 1);
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
// check if there's a comma in the task (multiple tasks)
|
||||
if (task.includes(",")) {
|
||||
let tasksToRemove = task.split(",").map((t) => t.trim());
|
||||
for (const t of tasksToRemove) {
|
||||
let index = tasks[username].todos.findIndex(
|
||||
(task) => task.text.toLowerCase() === t.toLowerCase()
|
||||
);
|
||||
|
||||
return removedTask;
|
||||
if (index === -1) {
|
||||
if (isInt(t)) {
|
||||
index = parseInt(t) - 1; // ACTUAL INDEX
|
||||
} else if (incompleteTasks.length) {
|
||||
index = tasks[username].todos.findIndex((t) => !t.done);
|
||||
tasksRemoved.push(tasks[username].todos[index].text);
|
||||
removedTaskIndex.push(index);
|
||||
} else {
|
||||
tasksFailedToRemove.push(t);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index < 0 || index > tasks[username].todos.length - 1) {
|
||||
tasksFailedToRemove.push(t);
|
||||
continue;
|
||||
} else {
|
||||
tasksRemoved.push(tasks[username].todos[index].text);
|
||||
removedTaskIndex.push(index);
|
||||
}
|
||||
} else {
|
||||
tasksRemoved.push(tasks[username].todos[index].text);
|
||||
removedTaskIndex.push(index);
|
||||
}
|
||||
}
|
||||
|
||||
if (tasksRemoved.length === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sort removedTaskIndex in descending order
|
||||
removedTaskIndex.sort((a, b) => b - a);
|
||||
|
||||
// remove tasks from tasks array
|
||||
for (const index of removedTaskIndex) {
|
||||
tasks[username].todos.splice(index, 1);
|
||||
}
|
||||
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
return {
|
||||
removedTasks: tasksRemoved.join('", "'),
|
||||
failedTasks: tasksFailedToRemove.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 (incompleteTasks.length) {
|
||||
index = tasks[username].todos.findIndex((t) => !t.done);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (index < 0 || index > tasks[username].todos.length - 1) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
task = tasks[username].todos[index].text;
|
||||
|
||||
tasks[username].todos.splice(index, 1);
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
return {
|
||||
removedTasks: task,
|
||||
failedTasks: "",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// function to determine if string is integer
|
||||
|
|
@ -245,7 +342,7 @@ function isInt(value) {
|
|||
|
||||
// 0: user has no tasks
|
||||
// 1: success
|
||||
function markOwnTaskDone(username) {
|
||||
function clearOwnDoneTasks(username) {
|
||||
const tasks = JSON.parse(localStorage.tasks);
|
||||
|
||||
if (!tasks[username] || tasks[username].todos.length === 0) {
|
||||
|
|
@ -268,42 +365,93 @@ function markOwnTaskDone(username) {
|
|||
// task: succcess
|
||||
function markTaskDone(username, task) {
|
||||
const tasks = JSON.parse(localStorage.tasks);
|
||||
const incompleteTasks = tasks[username].todos.filter((t) => !t.done);
|
||||
|
||||
// user does not have any tasks
|
||||
if (!tasks[username] || tasks[username].todos.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
let index = tasks[username].todos.findIndex(
|
||||
(t) => t.text.toLowerCase() === task.toLowerCase()
|
||||
);
|
||||
|
||||
// filter by t.done is false
|
||||
let incompleteTaskCount = tasks[username].todos.filter(
|
||||
(t) => !t.done
|
||||
).length;
|
||||
if (incompleteTaskCount === 1) {
|
||||
index = tasks[username].todos.findIndex((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);
|
||||
}
|
||||
|
||||
if (index === -1) {
|
||||
if (isInt(task)) {
|
||||
index = parseInt(task) - 1; // ACTUAL INDEX
|
||||
} else {
|
||||
let tasksMarkedComplete = [];
|
||||
let tasksFailedToComplete = [];
|
||||
|
||||
// check if there's a comma in the task (multiple tasks)
|
||||
if (task.includes(",")) {
|
||||
let tasksToMarkDone = task.split(",").map((t) => t.trim());
|
||||
for (const t of tasksToMarkDone) {
|
||||
let index = tasks[username].todos.findIndex(
|
||||
(task) => task.text.toLowerCase() === t.toLowerCase()
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
if (isInt(t)) {
|
||||
index = parseInt(t) - 1; // ACTUAL INDEX
|
||||
} else if (incompleteTasks.length) {
|
||||
index = tasks[username].todos.findIndex((t) => !t.done);
|
||||
tasksMarkedComplete.push(tasks[username].todos[index].text);
|
||||
} else {
|
||||
tasksFailedToComplete.push(t);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index < 0 || index > tasks[username].todos.length - 1) {
|
||||
tasksFailedToComplete.push(t);
|
||||
continue;
|
||||
} else {
|
||||
tasksMarkedComplete.push(tasks[username].todos[index].text);
|
||||
}
|
||||
} else {
|
||||
tasksMarkedComplete.push(tasks[username].todos[index].text);
|
||||
}
|
||||
tasks[username].todos[index].done = true;
|
||||
}
|
||||
|
||||
if (tasksMarkedComplete.length === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (index < 0 || index > tasks[username].todos.length - 1) {
|
||||
return 1;
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
return {
|
||||
markedTasks: tasksMarkedComplete.join('", "'),
|
||||
failedTasks: tasksFailedToComplete.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 (incompleteTasks.length) {
|
||||
index = tasks[username].todos.findIndex((t) => !t.done);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (index < 0 || index > tasks[username].todos.length - 1) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
task = tasks[username].todos[index].text;
|
||||
tasks[username].todos[index].done = true;
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
return {
|
||||
markedTasks: task,
|
||||
failedTasks: "",
|
||||
};
|
||||
}
|
||||
|
||||
let completedTask = tasks[username].todos[index].text;
|
||||
|
||||
tasks[username].todos[index].done = true;
|
||||
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
|
||||
return completedTask;
|
||||
}
|
||||
|
||||
// 0: user has no tasks
|
||||
|
|
@ -406,13 +554,7 @@ function incompleteTasksCount(username) {
|
|||
if (!tasks[username]) {
|
||||
return 0;
|
||||
}
|
||||
let count = 0;
|
||||
for (const task of tasks[username].todos) {
|
||||
if (!task.done) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
return tasks[username].todos.filter((t) => !t.done).length;
|
||||
}
|
||||
|
||||
function clearUserTasks(username) {
|
||||
|
|
@ -421,6 +563,7 @@ function clearUserTasks(username) {
|
|||
return;
|
||||
}
|
||||
tasks[username].todos = [];
|
||||
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
}
|
||||
|
|
@ -430,16 +573,22 @@ function clearAllDoneTasks() {
|
|||
for (const user in tasks) {
|
||||
tasks[user].todos = tasks[user].todos.filter((t) => !t.done);
|
||||
}
|
||||
cancelAnimation();
|
||||
scrolling = false;
|
||||
checkToAnimate();
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
renderTaskListToDOM();
|
||||
}
|
||||
|
||||
function clearAllTasks() {
|
||||
resetDB();
|
||||
cancelAnimation();
|
||||
scrolling = false;
|
||||
checkToAnimate();
|
||||
renderTaskListToDOM();
|
||||
}
|
||||
|
||||
function smutOnly(streamer) {
|
||||
function clearAllExceptStreamer(streamer) {
|
||||
// clear all tasks except for broadcasters
|
||||
const tasks = JSON.parse(localStorage.tasks);
|
||||
for (const user in tasks) {
|
||||
|
|
@ -449,7 +598,13 @@ function smutOnly(streamer) {
|
|||
}
|
||||
|
||||
localStorage.setItem(`tasks`, JSON.stringify(tasks));
|
||||
|
||||
clearAllDoneTasks();
|
||||
|
||||
cancelAnimation();
|
||||
scrolling = false;
|
||||
checkToAnimate();
|
||||
|
||||
renderTaskListToDOM();
|
||||
}
|
||||
|
||||
|
|
@ -522,30 +677,30 @@ function tests1() {
|
|||
let listOfStreamers = [
|
||||
`cloudydayzzz`,
|
||||
`berryspace`,
|
||||
`MohFocus`,
|
||||
`xeno_hiraeth`,
|
||||
`euphie___`,
|
||||
`unknownnie`,
|
||||
`theyolotato`,
|
||||
`charliosaurus`,
|
||||
`jutstreams`,
|
||||
`mikewhatwhere`,
|
||||
`studypaws`,
|
||||
`pcc_lanezzz`,
|
||||
`workwithjandj`,
|
||||
`studylena`,
|
||||
// `MohFocus`,
|
||||
// `xeno_hiraeth`,
|
||||
// `euphie___`,
|
||||
// `unknownnie`,
|
||||
// `theyolotato`,
|
||||
// `charliosaurus`,
|
||||
// `jutstreams`,
|
||||
// `mikewhatwhere`,
|
||||
// `studypaws`,
|
||||
// `pcc_lanezzz`,
|
||||
// `workwithjandj`,
|
||||
// `studylena`,
|
||||
];
|
||||
|
||||
for (let i = 0; i < listOfStreamers.length; i++) {
|
||||
addTask(listOfStreamers[i], "#ffc0cb", `task ${i + 1}`);
|
||||
addTask(listOfStreamers[i], "#ffc0cb", `another task ${i + 1}`);
|
||||
addTask(
|
||||
listOfStreamers[i],
|
||||
"#ffc0cb",
|
||||
`task 1, task 2, task 3, task 4, task 5`
|
||||
);
|
||||
markTaskDone(listOfStreamers[i], `1, 2, 3, 4, 5`);
|
||||
}
|
||||
}
|
||||
|
||||
function tests2() {
|
||||
smutOnly("theyolotato");
|
||||
}
|
||||
|
||||
async function checkToAnimate() {
|
||||
// compare task container height and task wrapper height
|
||||
|
||||
|
|
@ -580,11 +735,11 @@ async function checkToAnimate() {
|
|||
easing: "linear",
|
||||
};
|
||||
|
||||
let primaryAnimation = document
|
||||
primaryAnimation = document
|
||||
.querySelector(".primary")
|
||||
.animate(primaryKeyFrames, options);
|
||||
|
||||
let secondaryAnimation = document
|
||||
secondaryAnimation = document
|
||||
.querySelector(".secondary")
|
||||
.animate(secondaryKeyFrames, options);
|
||||
|
||||
|
|
@ -598,20 +753,22 @@ async function checkToAnimate() {
|
|||
scrolling = false;
|
||||
checkToAnimate();
|
||||
}
|
||||
} else if (!scrolling) {
|
||||
} else if (scrolling) {
|
||||
document.querySelector(".secondary").style.display = "none";
|
||||
|
||||
// cancel animations
|
||||
document
|
||||
.querySelector(".task-container")
|
||||
.getAnimations()
|
||||
.forEach((a) => {
|
||||
a.cancel();
|
||||
});
|
||||
cancelAnimation();
|
||||
scrolling = false;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelAnimation() {
|
||||
if (primaryAnimation && secondaryAnimation) {
|
||||
primaryAnimation.cancel();
|
||||
secondaryAnimation.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
setupDB();
|
||||
importStyles();
|
||||
|
|
|
|||
Loading…
Reference in a new issue