From 4631b1f6a3f095f95a291abf79a4bb2da0251022 Mon Sep 17 00:00:00 2001 From: liyunze <50455574+liyunze-coding@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:59:58 +0800 Subject: [PATCH] BETA changed configs format, nowTask, score display --- configs.js | 892 ++++++++++++++++++-------------------------- get_token.txt | 5 - scripts/index.js | 45 ++- scripts/taskList.js | 405 ++++++++++++++++++-- 4 files changed, 788 insertions(+), 559 deletions(-) delete mode 100644 get_token.txt diff --git a/configs.js b/configs.js index 517f8b1..bcd1bbf 100644 --- a/configs.js +++ b/configs.js @@ -1,538 +1,386 @@ const configs = (function () { "use strict"; - // settings - const enableLimit = false; // true or false - const limit = 10; // integer - const automaticDoneIndex = true; // true or false - Automatically assume first unfinished task is complete - const pointsName = "points"; // string - const pointsPerTask = 10; // integer - const taskSeparator = [";", ","]; // array of strings - - // SETTING THIS 'TRUE' WILL RESET EXISTING TASKS - const testTasks = false; // true or false - - // animation - const scrollSpeed = 40; // milliseconds - const gapBetweenScrolls = 0; // px - - // STYLES - // task list - const taskListBackgroundColor = "#000000"; // hex only - const taskListBackgroundOpacity = 0; // 0.0 - 1.0 - - const taskListBorderWidth = "0px"; // px - const taskListBorderColor = "#ffffff"; // hex or name - const taskListBorderRadius = "0px"; // px - - const taskListHorizontalPadding = "0px"; // px - const taskListVerticalPadding = "0px"; // px - - // header - const headerHorizontalPadding = "10px"; // px - const headerVerticalPadding = "10px"; // px - - const headerBackgroundColor = "#fff"; // hex only - const headerBackgroundOpacity = 1; // 0.0 - 1.0 - - const headerBorderWidth = "0px"; // px - const headerBorderColor = "#ffffff"; // hex or name - const headerBorderRadius = "3px"; // px - - const headerFontFamily = "Fredoka"; // font name - const headerGoogleFont = true; // true: use google font, false: use system font - - const headerFontSize = "25px"; // px - const headerFontWeight = "bold"; // normal or bold or number - - const headerFontColor = "#000"; // hex or name - - // body - const bodyBackgroundColor = "#fff"; // hex only - const bodyBackgroundOpacity = 0; // 0.0 - 1.0 - - const bodyBorderWidth = "0px"; // px - const bodyBorderColor = "#fff"; // hex or name - const bodyBorderRadius = "5px"; // px - - // task - const lineHeight = 1.5; // number - const usernameFontWeight = "bold"; // normal or bold or number - const usernameColor = "pink"; // hex or name or "" for twitch user color - const usernameFontSize = "20px"; // px - - const taskWidth = "100%"; - - const taskBackgroundColor = "#000"; // hex only - const taskBackgroundOpacity = 0; // 0.0 - 1.0 - - const taskFontFamily = "Poppins"; // font name - const taskGoogleFont = true; // true: use google font, false: use system font - - const taskFontSize = "20px"; // px - const taskFontColor = "#fff"; // hex or name - - const taskBorderColor = "#fff"; // hex or name - const taskBorderWidth = "0px"; // px - const taskBorderRadius = "10px"; // px - - const taskMarginBottom = "10px"; // px - const taskHorizontalPadding = "20px"; // px - const taskVerticalPadding = "10px"; // px - - // done task - const doneTaskFontColor = "#bbb"; // hex or name - - // focus task - const focusTaskBackgroundColor = "#fff"; // hex only - const focusTaskBackgroundOpacity = 1; // 0.0 - 1.0 - const focusTaskBorderRadius = "5px"; // px - - const focusTaskFontColor = "#000"; // hex or name - - const focusTaskHorizontalPadding = "7px"; // px - const focusTaskVerticalPadding = "0px"; // px - - // Add task commands - please add commands in the exact format - const addTaskCommands = [ - "!taska", - "!taskadd", - "!atask", - "!addtask", - "!task", - "!add", - "!todo", - "!a", - ]; - - // Edit task commands - please add commands in the exact format - const editTaskCommands = [ - "!taske", - "!taskedit", - "!etask", - "!edittask", - "!edit", - "!e", - ]; - - // Delete task commands - please add commands in the exact format - const deleteTaskCommands = [ - "!taskdel", - "!taskdelete", - "!deltask", - "!deletetask", - "!taskr", - "!taskremove", - "!rtask", - "!removetask", - "!remove", - "!delete", - "!r", - ]; - - // Finish task commands - please add commands in the exact format - const finishTaskCommands = [ - "!taskf", - "!taskfinish", - "!ftask", - "!finishtask", - "!taskd", - "!taskdone", - "!donetask", - "!dtask", - "!finish", - "!done", - "!finished", - "!f", - ]; - - // Unfinish task commands - please add commands in the exact format - const unfinishTaskCommands = [ - "!tasku", - "!taskunfinish", - "!utask", - "!unfinishtask", - "!taskud", - "!taskundone", - "!undonetask", - "!undone", - "!unfinish", - "!unfinished", - "!u", - ]; - - // focus task commands - please add commands in the exact format - const focusTaskCommands = ["!focus", "!taskfocus", "!focustask"]; - - const unfocusTaskCommands = ["!unfocus", "!taskunfocus", "!unfocustask"]; - - // Check task commands - please add commands in the exact format - const checkCommands = [ - "!taskc", - "!taskcheck", - "!ctask", - "!checktask", - "!mytask", - "!check", - "!mytasks", - ]; - - // List tasks commands - please add commands in the exact format - const listCommands = ["!taskl", "!tasklist", "!listtasks", "!list"]; - - // Clear my done commands - please add commands in the exact format - const clearMyDoneCommands = ["!clearmydone"]; - - // check count commands - please add commands in the exact format - const checkCountCommands = [ - "!taskcount", - "!count", - "!checkcount", - "!mycount", - ]; - - const checkAllCountCommands = [ - "!taskallcount", - "!allcount", - "!checkallcount", - "!boardcount", - "!checkboardcount", - "!taskboardcount", - ]; - - const checkMyPointsCommands = [ - "!taskpoints", - "!points", - "!mypoints", - "!checkpoints", - ]; - - // sync points with count commands - please add commands in the exact format - const syncCountPointsCommands = ["!syncpoints", "!synccount"]; - - const addPointsCommands = ["!addpoints", "!givepoints", "!adduserpoints"]; - - const reducePointsCommands = ["!reducepoints", "!takepoints"]; - - const setUserPointsCommands = [ - "!setuserpoints", - "!setpoints", - "!setpointsuser", - "!setuserpoint", - ]; - - const setUserTaskCountCommands = [ - "!setusertaskcount", - "!settaskcount", - "!settaskcountuser", - "!setusertask", - ]; - - const leaderboardCommands = ["!leaderboard", "!lb", "!top", "!toppoints"]; - - // Help commands - please add commands in the exact format - const helpCommands = [ - "!taskh", - "!taskhelp", - "!htask", - "!helptask", - "!tasks", - "!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", - "!adel", - "!adelete", - "!admindelete", - ]; - - // Admin clear done - please add commands following the exact format - const adminClearDoneCommands = [ - "!acleardone", - "!admincleardone", - "!cleardone", - ]; - - const adminClearTasksCommands = ["!cleartasks"]; - - const adminResetBoardCount = ["!resetboardcount", "!resetallcount"]; - - const adminResetUsersCount = ["!resetuserscount"]; - - const adminClearAllCommands = [ - "!clearall", - "!allclear", - "!adminclearall", - "!adminallclear", - "!aclearall", - "!aclear", - ]; - - const adminSetBoardCount = ["!setboardcount", "!setallcount"]; - - // Responses related to task addition - const taskAdded = 'The task(s) "{task}" has been added, {user}!'; - 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 duplicateTask = - "Looks like you already have the task '{message}' up there {user}!"; - - // Responses related to task deletion - const taskDeleted = - 'Task(s) "{task}" has been deleted successfully, {user}'; - const specifyTaskIndex = - "Try specifying the index of the incomplete task(s) {user}"; - const clearTasksExceptBroadcaster = - "All tasks have been cleared except for the streamer's, {user}!"; - const adminDeleteTasks = "All of {mentioned}'s tasks have been deleted"; - - // Responses related to task completion - const taskFinished = - 'Good job on finishing the task(s) "{task}", {user}! You have earned {pointCount} {pointName} and completed {doneCount} task(s) so far!'; - const allTasksFinished = - "Good job on finishing all your tasks, {user}! You have completed {doneCount} task(s) so far!"; - const taskUnfinished = - 'Task(s) "{task}" has been unmarked as done, {user}!'; - const taskAlreadyFinished = - "Looks like you already finished that task {user}"; - - // Responses related to task editing - const taskEdited = - 'Task "{originalTask}" has been edited to "{task}" successfully, {user}'; - const noTaskEdit = "Try doing !edit [index] [new task] {user}"; - - // Responses related to task focus - const taskFocused = 'Task "{task}" has been focused, {user}!'; - const clearFocused = "Task has been unfocused, {user}!"; - const noFocusedTask = "Looks like you don't have a focused task {user}!"; - const alreadyFocusedTask = - "Looks like you already have that task set to focus {user}!"; - const onlyOneFocus = "You can only focus one task at a time {user}!"; - const specifyFocusTask = - "Try specifying an incomplete task to focus {user}!"; - - // Responses related to task existence - const noTask = "Looks like you don't have a task up there {user}"; - const noTaskA = "Looks like there is no task from that user there {user}"; - - // Responses related to viewing counts / points - const checkMyPoints = "You have {pointCount} {pointName}, {user}!"; - const checkUserPoints = - "{mentioned} has {pointCount} {pointName}, {user}!"; - const checkYourCount = - "You have completed {doneCount} task(s) so far, {user}!"; - const checkUserCount = - "{mentioned} has completed {doneCount} task(s) so far, {user}!"; - const checkAllCount = - "Everyone has completed {doneCount} task(s) so far, {user}!"; - const noCountAll = "Looks like no one has completed a task yet {user}"; - const leaderboard = "Leaderboard: {leaderboard}"; - - // Responses related to modifying points - const syncCountPoints = "Points have been synced with count, {user}!"; - const addPoints = "{mentioned} has been given {pointCount} {pointName}!"; - const reducePoints = "{mentioned} has lost {pointCount} {pointName}!"; - const setUserPoints = "{mentioned} now has {pointCount} {pointName}!"; - const setUserTaskCount = "{mentioned} now has {taskCount} tasks!"; - const specifyPoints = "Try specifying a number of points {user}"; - - // Responses related to permissions - const notMod = "Permission denied, {user}; Mods only"; - const notStreamer = "Permission denied, {user}; Streamer only"; - - // Responses related to clearing tasks / counts - const clearedAll = "All tasks and counts have been cleared!"; - const clearedTasks = "All tasks have been cleared!"; - const clearedDone = "All completed tasks have been cleared!"; - const clearedMyDone = "All your completed tasks have been cleared!"; - const clearedBoardCount = "The board count has been reset!"; - const clearedUsersCount = "The users count has been reset!"; - const setBoardCount = "The board count has been set to {count}!"; - const specifyUser = "Try specifying a user to delete their tasks {user}"; - const invalidNumber = "Try specifying a valid number {user}"; - - // Help response - const help = `{user} Use the following commands to help you out - !task !edit !remove !done. For mods, you can do !adel @user. More commmands here: https://github.com/liyunze-coding/Chat-Task-Tic-Overlay/blob/main/MultiTask.md/`; - // to edit check task command, go to - // scripts/taskList.js - // function checkTasks(username) - - const additionalCommands = { - "!botcred": - "{user} Ryan is the creator of this bot! You can find him on https://github.com/liyunze-coding or https://www.twitch.tv/RythonDev", - }; - - const titles = [ - "!taskhelp", - "!task", - "!edit", - "!remove", - "!done", - "!undone", - "!botcred", - "!count", - "!points", - "!boardcount", - ]; - const settings = { - enableLimit, - limit, - automaticDoneIndex, - pointsName, - pointsPerTask, - taskSeparator, - headerGoogleFont, - taskGoogleFont, - testTasks, - }; - - const styles = { - taskListBackgroundColor, - taskListBackgroundOpacity, - taskListBorderWidth, - taskListBorderColor, - taskListBorderRadius, - taskListHorizontalPadding, - taskListVerticalPadding, - headerHorizontalPadding, - headerVerticalPadding, - headerBackgroundColor, - headerBackgroundOpacity, - headerBorderWidth, - headerBorderColor, - headerBorderRadius, - headerFontSize, - headerFontWeight, - headerFontFamily, - headerFontColor, - bodyBackgroundColor, - bodyBackgroundOpacity, - bodyBorderWidth, - bodyBorderColor, - bodyBorderRadius, - taskWidth, - lineHeight, - usernameFontWeight, - usernameColor, - usernameFontSize, - doneTaskFontColor, - taskBackgroundColor, - taskBackgroundOpacity, - taskFontFamily, - taskFontSize, - taskFontColor, - taskBorderColor, - taskBorderWidth, - taskBorderRadius, - taskMarginBottom, - taskHorizontalPadding, - taskVerticalPadding, - focusTaskBackgroundColor, - focusTaskBackgroundOpacity, - focusTaskFontColor, - focusTaskHorizontalPadding, - focusTaskVerticalPadding, - focusTaskBorderRadius, + enableLimit: false, // true or false + limit: 10, // integer + automaticDoneIndex: true, // true or false - Automatically assume first unfinished task is complete + pointsName: "points", // string + pointsPerTask: 10, // integer + taskSeparator: [";", ","], // array of strings + testTasks: false, // true or false + headerGoogleFont: true, // true: use google font, false: use system font + taskGoogleFont: true, // true: use google font, false: use system font + displayTaskCount: true, // true or false }; const animation = { - scrollSpeed, - gapBetweenScrolls, - titles, + scrollSpeed: 40, // milliseconds + gapBetweenScrolls: 0, // px + titles: [ + "!taskhelp", + "!task", + "!edit", + "!remove", + "!done", + "!undone", + "!botcred", + "!count", + "!points", + "!boardcount", + ], }; + const styles = { + // task list + taskListBackgroundColor: "#000000", // hex only + taskListBackgroundOpacity: 0, // 0.0 - 1.0 + + taskListBorderWidth: "0px", // px + taskListBorderColor: "#ffffff", // hex or name + taskListBorderRadius: "0px", // px + + taskListHorizontalPadding: "0px", // px + taskListVerticalPadding: "0px", // px + + // header + headerHorizontalPadding: "10px", // px + headerVerticalPadding: "10px", // px + + headerBackgroundColor: "#fff", // hex only + headerBackgroundOpacity: 1, // 0.0 - 1.0 + + headerBorderWidth: "0px", // px + headerBorderColor: "#ffffff", // hex or name + headerBorderRadius: "3px", // px + + headerFontFamily: "Fredoka", // font name + + headerFontSize: "25px", // px + headerFontWeight: "bold", // normal or bold or number + + headerFontColor: "#000", // hex or name + + // body + bodyBackgroundColor: "#fff", // hex only + bodyBackgroundOpacity: 0, // 0.0 - 1.0 + + bodyBorderWidth: "0px", // px + bodyBorderColor: "#fff", // hex or name + bodyBorderRadius: "5px", // px + + // task + lineHeight: 1.5, // number + usernameFontWeight: "bold", // normal or bold or number + usernameColor: "pink", // hex or name or "" for twitch user color + usernameFontSize: "20px", // px + + taskWidth: "100%", + + taskBackgroundColor: "#000", // hex only + taskBackgroundOpacity: 0, // 0.0 - 1.0 + + taskFontFamily: "Poppins", // font name + + taskFontSize: "20px", // px + taskFontColor: "#fff", // hex or name + + taskBorderColor: "#fff", // hex or name + taskBorderWidth: "0px", // px + taskBorderRadius: "10px", // px + + taskMarginBottom: "10px", // px + taskHorizontalPadding: "20px", // px + taskVerticalPadding: "10px", // px + + // done task + doneTaskFontColor: "#bbb", // hex or name + + // focus task + focusTaskBackgroundColor: "#fff", // hex only + focusTaskBackgroundOpacity: 1, // 0.0 - 1.0 + focusTaskBorderRadius: "5px", // px + + focusTaskFontColor: "#000", // hex or name + + focusTaskHorizontalPadding: "7px", // px + focusTaskVerticalPadding: "0px", // px + }; + + // STYLES + const commands = { - addTaskCommands, - editTaskCommands, - deleteTaskCommands, - finishTaskCommands, - unfinishTaskCommands, - focusTaskCommands, - unfocusTaskCommands, - helpCommands, - checkCommands, - listCommands, - clearMyDoneCommands, - checkCountCommands, - checkAllCountCommands, - checkMyPointsCommands, - syncCountPointsCommands, - addPointsCommands, - reducePointsCommands, - setUserPointsCommands, - setUserTaskCountCommands, - leaderboardCommands, - adminDeleteCommands, - adminClearNotStreamerCommands, - adminClearDoneCommands, - adminClearAllCommands, - adminClearTasksCommands, - adminSetBoardCount, - adminResetBoardCount, - adminResetUsersCount, - additionalCommands, + // Add task commands - please add commands in the exact format + addTaskCommands: [ + "!taska", + "!taskadd", + "!atask", + "!addtask", + "!task", + "!add", + "!todo", + "!a", + ], + + // Edit task commands - please add commands in the exact format + editTaskCommands: [ + "!taske", + "!taskedit", + "!etask", + "!edittask", + "!edit", + "!e", + ], + + // Delete task commands - please add commands in the exact format + deleteTaskCommands: [ + "!taskdel", + "!taskdelete", + "!deltask", + "!deletetask", + "!taskr", + "!taskremove", + "!rtask", + "!removetask", + "!remove", + "!delete", + "!r", + ], + + // Finish task commands - please add commands in the exact format + finishTaskCommands: [ + "!taskf", + "!taskfinish", + "!ftask", + "!finishtask", + "!taskd", + "!taskdone", + "!donetask", + "!dtask", + "!finish", + "!done", + "!finished", + "!f", + ], + + // Unfinish task commands - please add commands in the exact format + unfinishTaskCommands: [ + "!tasku", + "!taskunfinish", + "!utask", + "!unfinishtask", + "!taskud", + "!taskundone", + "!undonetask", + "!undone", + "!unfinish", + "!unfinished", + "!u", + ], + + nextTaskCommands: [ + "!taskn", + "!tasknext", + "!ntask", + "!nexttask", + "!next", + "!n", + ], + + // focus task commands - please add commands in the exact format + focusTaskCommands: ["!focus", "!taskfocus", "!focustask"], + unfocusTaskCommands: ["!unfocus", "!taskunfocus", "!unfocustask"], + + nowTaskCommands: ["!now", "!tasknow", "!nowtask"], + + // Check task commands - please add commands in the exact format + checkCommands: [ + "!taskc", + "!taskcheck", + "!ctask", + "!checktask", + "!mytask", + "!check", + "!mytasks", + ], + + // List tasks commands - please add commands in the exact format + listCommands: ["!taskl", "!tasklist", "!listtasks", "!list"], + + // Clear my done commands - please add commands in the exact format + clearMyDoneCommands: ["!clearmydone"], + + // check count commands - please add commands in the exact format + checkCountCommands: ["!taskcount", "!count", "!checkcount", "!mycount"], + + checkAllCountCommands: [ + "!taskallcount", + "!allcount", + "!checkallcount", + "!boardcount", + "!checkboardcount", + "!taskboardcount", + ], + + checkMyPointsCommands: [ + "!taskpoints", + "!points", + "!mypoints", + "!checkpoints", + ], + + // sync points with count commands - please add commands in the exact format + syncCountPointsCommands: ["!syncpoints", "!synccount"], + + addPointsCommands: ["!addpoints", "!givepoints", "!adduserpoints"], + + reducePointsCommands: ["!reducepoints", "!takepoints"], + + setUserPointsCommands: [ + "!setuserpoints", + "!setpoints", + "!setpointsuser", + "!setuserpoint", + ], + + setUserTaskCountCommands: [ + "!setusertaskcount", + "!settaskcount", + "!settaskcountuser", + "!setusertask", + ], + + leaderboardCommands: ["!leaderboard", "!lb", "!top", "!toppoints"], + + // Help commands - please add commands in the exact format + helpCommands: [ + "!taskh", + "!taskhelp", + "!htask", + "!helptask", + "!tasks", + "!help", + ], + + // Admin clear all except streamer - please add commands following the exact format + adminClearNotStreamerCommands: [ + "!clearnotstreamer", + "!aclearnotstreamer", + "!adminclearnotstreamer", + "!clearns", + ], + + // Admin delete - please add commands following the exact format + adminDeleteCommands: ["!taskadel", "!adel", "!adelete", "!admindelete"], + + // Admin clear done - please add commands following the exact format + adminClearDoneCommands: [ + "!acleardone", + "!admincleardone", + "!cleardone", + ], + + adminClearTasksCommands: ["!cleartasks"], + + adminResetBoardCount: ["!resetboardcount", "!resetallcount"], + + adminResetUsersCount: ["!resetuserscount"], + + adminClearAllCommands: [ + "!clearall", + "!allclear", + "!adminclearall", + "!adminallclear", + "!aclearall", + "!aclear", + ], + + adminSetBoardCount: ["!setboardcount", "!setallcount"], + additionalCommands: { + "!botcred": + "{user} Ryan is the creator of this bot! You can find him on https://github.com/liyunze-coding or https://www.twitch.tv/RythonDev", + }, }; const responses = { - taskAdded, - noTaskAdded, - noTaskContent, - taskDeleted, - specifyTaskIndex, - duplicateTask, - taskFinished, - allTasksFinished, - taskUnfinished, - taskAlreadyFinished, - taskEdited, - noTaskEdit, - clearFocused, - noFocusedTask, - alreadyFocusedTask, - onlyOneFocus, - specifyFocusTask, - taskFocused, - noTask, - noTaskA, - checkMyPoints, - checkUserPoints, - checkYourCount, - checkUserCount, - checkAllCount, - noCountAll, - leaderboard, - syncCountPoints, - addPoints, - reducePoints, - setUserPoints, - setUserTaskCount, - specifyPoints, - notMod, - notStreamer, - help, - clearTasksExceptBroadcaster, - adminDeleteTasks, - clearedMyDone, - clearedBoardCount, - clearedUsersCount, - clearedAll, - clearedTasks, - clearedDone, - setBoardCount, - specifyUser, - invalidNumber, + // Responses related to task addition + taskAdded: 'The task(s) "{task}" has been added, {user}!', + noTaskAdded: + "Looks like you already hit the limit of incomplete tasks, {user}", + noTaskContent: "Try using !task the-task-you-are-working-on {user}", + duplicateTask: + "Looks like you already have the task '{message}' up there {user}!", + taskEdited: + 'Task "{originalTask}" has been edited to "{task}" successfully, {user}', + noTaskEdit: "Try doing !edit [index] [new task] {user}", + nowTask: 'Task "{task}" is now the task you are working on, {user}!', + + // Grouped by task progression responses + taskNext: + "Good job on finishing the task '{oldTask}'! Now moving onto '{newTask}', {user}!", + nextNoContent: "Try using !next the-task-you-want-to-do-next {user}", + taskNextFailed: + "Unable to perform command with multiple incomplete tasks, {user}!", + + // Grouped by task deletion responses + clearedMyDone: "All of your completed tasks have been cleared, {user}!", + taskDeleted: 'Task(s) "{task}" has been deleted successfully, {user}', + specifyTaskIndex: + "Try specifying the index of the incomplete task(s) {user}", + clearTasksExceptBroadcaster: + "All tasks have been cleared except for the streamer's, {user}!", + adminDeleteTasks: "All of {mentioned}'s tasks have been deleted", + + // Grouped by task completion responses + taskFinished: + 'Good job on finishing the task(s) "{task}", {user}! You have earned {pointCount} {pointName} and completed {doneCount} task(s) so far!', + allTasksFinished: + "Good job on finishing all your tasks, {user}! You have completed {doneCount} task(s) so far!", + taskUnfinished: 'Task(s) "{task}" has been unmarked as done, {user}!', + taskAlreadyFinished: "Looks like you already finished that task {user}", + + // Grouped by task focus responses + clearFocused: "Task has been unfocused, {user}!", + noFocusedTask: "Looks like you don't have a focused task {user}!", + alreadyFocusedTask: + "Looks like you already have that task set to focus {user}!", + onlyOneFocus: "You can only focus one task at a time {user}!", + specifyFocusTask: "Try specifying an incomplete task to focus {user}!", + taskFocused: 'Task "{task}" has been focused, {user}!', + + // Grouped by task existence responses + noTask: "Looks like you don't have a task up there {user}", + noTaskA: "Looks like there is no task from that user there {user}", + + // Grouped by point-related responses + checkMyPoints: "You have {pointCount} {pointName}, {user}!", + checkUserPoints: "{mentioned} has {pointCount} {pointName}, {user}!", + syncCountPoints: "Points have been synced with count, {user}!", + addPoints: "{mentioned} has been given {pointCount} {pointName}!", + reducePoints: "{mentioned} has lost {pointCount} {pointName}!", + setUserPoints: "{mentioned} now has {pointCount} {pointName}!", + specifyPoints: "Try specifying a number of points {user}", + + // Grouped by count-related responses + checkYourCount: + "You have completed {doneCount} task(s) so far, {user}!", + checkUserCount: + "{mentioned} has completed {doneCount} task(s) so far, {user}!", + checkAllCount: + "Everyone has completed {doneCount} task(s) so far, {user}!", + noCountAll: "Looks like no one has completed a task yet {user}", + leaderboard: "Leaderboard: {leaderboard}", + setUserTaskCount: "{mentioned} now has {taskCount} tasks!", + + // Grouped by permission-related responses + notMod: "Permission denied, {user}; Mods only", + notStreamer: "Permission denied, {user}; Streamer only", + + // Help response + help: `{user} Use the following commands to help you out - !task !edit !remove !done. For mods, you can do !adel @user. More commmands here: https://github.com/liyunze-coding/Chat-Task-Tic-Overlay/blob/main/MultiTask.md/`, + // to edit check task command, go to + // scripts/taskList.js + // function checkTasks(username) }; return { diff --git a/get_token.txt b/get_token.txt deleted file mode 100644 index 69978cd..0000000 --- a/get_token.txt +++ /dev/null @@ -1,5 +0,0 @@ -https://id.twitch.tv/oauth2/authorize -?client_id=CLIENT_ID_HERE -&redirect_uri=http://localhost -&response_type=token -&scope=channel:moderate+chat:edit+chat:read+channel:manage:broadcast+user:edit:broadcast+channel:read:redemptions+user:read:email diff --git a/scripts/index.js b/scripts/index.js index dc8577b..e353d9e 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -18,9 +18,7 @@ function isStreamer(flags) { return flags.broadcaster; } -ComfyJS.onCommand = (user, command, message, flags, extra) => { - command = `!${command.toLowerCase()}`; - +function processCommand(user, command, message, flags, extra) { params = { user: user, message: message, @@ -131,6 +129,35 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => { } respond(unfinishedResponse, params); + } else if (commands.nextTaskCommands.includes(command)) { + let nextRequest = nextTask(user, message); + + if (nextRequest.status !== 200) { + respond(nextRequest.body.error, params); + return; + } + + // task next + let nextResponse = responses.taskNext; + + params.oldTask = nextRequest.body.oldTask; + params.newTask = nextRequest.body.newTask; + + respond(nextResponse, params); + } else if (commands.nowTaskCommands.includes(command)) { + let nowRequest = nowTask(user, extra.userColor, message); + + if (nowRequest.status !== 200) { + respond(nowRequest.body.error, params); + return; + } + + // task now + let nowResponse = responses.nowTask; + + params.task = nowRequest.body.task; + + respond(nowResponse, params); } else if (commands.focusTaskCommands.includes(command)) { let focusRequest = focusTask(user, message); @@ -166,7 +193,7 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => { return; } - return ComfyJS.Say(checkRequest.body.reply); + return respond(checkRequest.body.reply, params); } else { let mentioned = message.replace("@", ""); let checkRequest = checkTasks(mentioned); @@ -177,7 +204,7 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => { return; } - return ComfyJS.Say(checkRequest.body.reply); + return respond(checkRequest.body.reply, params); } } else if (commands.adminDeleteCommands.includes(command)) { if (!isMod(flags)) { @@ -224,7 +251,7 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => { } else if (commands.clearMyDoneCommands.includes(command)) { let clearOwnDoneResponse = clearOwnDoneTasks(user); - if (clearOwnDoneResponse.status === 0) { + if (clearOwnDoneResponse.status !== 200) { // no tasks respond(responses.noTask, params); return; @@ -491,6 +518,12 @@ ComfyJS.onCommand = (user, command, message, flags, extra) => { } else { // command not found } +} + +ComfyJS.onCommand = (user, command, message, flags, extra) => { + command = `!${command.toLowerCase()}`; + + processCommand(user, command, message, flags, extra); }; ComfyJS.Init(auth.username, `oauth:${auth.oauth}`, [auth.channel]); diff --git a/scripts/taskList.js b/scripts/taskList.js index f3fa255..a3ac10d 100644 --- a/scripts/taskList.js +++ b/scripts/taskList.js @@ -125,6 +125,10 @@ function importStyles() { ); }); + if (!settings.displayTaskCount) { + document.querySelector(".task-count").style.display = "none"; + } + let currentTitle = 0; // interval the task title setInterval(async () => { @@ -268,6 +272,7 @@ function addDoneCount(username, value) { counts.users[username.toLowerCase()].completeCount += value; counts.totalCompleteCount += value; + taskListMemory.doneTaskCount += value; // check if user has points if (!counts.users[username.toLowerCase()].points) { @@ -354,12 +359,8 @@ function addPoints(username, value) { counts.users[username.toLowerCase()].points = 0; } - console.log(counts.users[username.toLowerCase()].points); - counts.users[username.toLowerCase()].points += value; - console.log(counts.users[username.toLowerCase()].points); - localStorage.setItem(`counts`, JSON.stringify(counts)); return { @@ -688,6 +689,9 @@ function addTask(username, userColor, task) { tasksFailedToAdd.push(t); continue; } + + taskListMemory.totalTaskCount++; + tasks[username].todos.push({ text: t, done: false, @@ -708,10 +712,217 @@ function addTask(username, userColor, task) { tasksFailedToAdd: tasksFailedToAdd.join('", "') || "", }, }; + } else { + tasks[username].todos.push({ text: task, done: false, focus: false }); + taskListMemory.totalTaskCount++; + + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + if (!scrolling) { + renderTaskListToDOM(); + } + + return { + status: 200, + body: { + task: task, + tasksFailedToAdd: "", + }, + }; + } +} + +/** + * 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. + */ +function nowTask(username, userColor, task) { + const tasks = JSON.parse(localStorage.tasks); + if (!tasks[username]) { + tasks[username] = { + todos: [], + done: [], + userColor: userColor, + }; } - tasks[username].todos.push({ text: task, done: false, focus: false }); + if ( + incompleteTasksCount(username) >= settings.limit && + settings.enableLimit + ) { + return { + status: 0, + body: { + "error message": `@${username} has reached the limit of ${settings.limit} tasks`, + error: responses.noTaskAdded, + }, + }; + } + + if ( + tasks[username].todos.find( + (t) => t.text.toLowerCase() === task.toLowerCase() + ) + ) { + return { + status: 1, + body: { + "error message": `@${username} already has this task`, + error: responses.duplicateTask, + }, + }; + } + + // if task is whitespace or empty + if (!task || !task.trim()) { + return { + status: 2, + body: { + "error message": `@${username} empty task`, + error: responses.noTaskContent, + }, + }; + } + + // if task is "all", return error + if (task.toLowerCase() === "all") { + return { + status: 2, + body: { + "error message": `@${username} all is a reserved keyword`, + error: responses.noTaskContent, + }, + }; + } + + // if task has commas + if (taskSeparator.some((char) => task.includes(char))) { + // return an error because you can't add multiple tasks with now + return { + status: 2, + body: { + "error message": `@${username} cannot add multiple tasks with now`, + error: responses.noTaskContent, + }, + }; + } + + // set all tasks to unfocused + for (const task of tasks[username].todos) { + task.focus = false; + } + + tasks[username].todos.push({ text: task, done: false, focus: true }); + taskListMemory.totalTaskCount++; + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + + if (!scrolling) { + renderTaskListToDOM(); + } + + return { + status: 200, + body: { + task: 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. + */ +function nowTask(username, userColor, task) { + const tasks = JSON.parse(localStorage.tasks); + if (!tasks[username]) { + tasks[username] = { + todos: [], + done: [], + userColor: userColor, + }; + } + + if ( + incompleteTasksCount(username) >= settings.limit && + settings.enableLimit + ) { + return { + status: 0, + body: { + "error message": `@${username} has reached the limit of ${settings.limit} tasks`, + error: responses.noTaskAdded, + }, + }; + } + + if ( + tasks[username].todos.find( + (t) => t.text.toLowerCase() === task.toLowerCase() + ) + ) { + return { + status: 1, + body: { + "error message": `@${username} already has this task`, + error: responses.duplicateTask, + }, + }; + } + + // if task is whitespace or empty + if (!task || !task.trim()) { + return { + status: 2, + body: { + "error message": `@${username} empty task`, + error: responses.noTaskContent, + }, + }; + } + + // if task is "all", return error + if (task.toLowerCase() === "all") { + return { + status: 2, + body: { + "error message": `@${username} all is a reserved keyword`, + error: responses.noTaskContent, + }, + }; + } + + // if task has commas + if (taskSeparator.some((char) => task.includes(char))) { + // return an error because you can't add multiple tasks with now + return { + status: 2, + body: { + "error message": `@${username} cannot add multiple tasks with now`, + error: responses.noTaskContent, + }, + }; + } + + // set all tasks to unfocused + for (const task of tasks[username].todos) { + task.focus = false; + } + + tasks[username].todos.push({ text: task, done: false, focus: true }); + taskListMemory.totalTaskCount++; + + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + if (!scrolling) { renderTaskListToDOM(); } @@ -720,7 +931,6 @@ function addTask(username, userColor, task) { status: 200, body: { task: task, - tasksFailedToAdd: "", }, }; } @@ -936,9 +1146,7 @@ function removeTask(username, task) { if (isInt(t)) { index = parseInt(t) - 1; // ACTUAL INDEX } else if (incompleteTasks.length === 1) { - index = tasks[username].todos.findIndex( - (t) => !t.done - ); + index = tasks[username].todos.findIndex((t) => !t.done); tasksRemoved.push(tasks[username].todos[index].text); removedTaskIndex.push(index); } else { @@ -975,6 +1183,7 @@ function removeTask(username, task) { // remove tasks from tasks array for (const index of removedTaskIndex) { tasks[username].todos.splice(index, 1); + taskListMemory.totalTaskCount--; } localStorage.setItem(`tasks`, JSON.stringify(tasks)); @@ -1022,6 +1231,7 @@ function removeTask(username, task) { task = tasks[username].todos[index].text; tasks[username].todos.splice(index, 1); + taskListMemory.totalTaskCount--; localStorage.setItem(`tasks`, JSON.stringify(tasks)); renderTaskListToDOM(); return { @@ -1034,6 +1244,134 @@ function removeTask(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. + */ +function nextTask(username, task) { + const tasks = JSON.parse(localStorage.tasks); + if (!tasks[username] || tasks[username].todos.length === 0) { + return { + status: 0, + body: { + "error message": `@${username} has no tasks`, + error: responses.noTask, + }, + }; + } + + if (task === "") { + return { + status: 1, + body: { + "error message": `@${username} empty task`, + error: responses.nextNoContent, + }, + }; + } + + const incompleteTasks = tasks[username].todos.filter((t) => !t.done); + + if (incompleteTasks.length !== 1) { + return { + status: 0, + body: { + "error message": `@${username} has more than one incomplete task`, + error: responses.taskNextFailed, + }, + }; + } else { + // mark the incomplete task as complete, then add a new task "task" + + // find index of incomplete task + let index = tasks[username].todos.findIndex((t) => !t.done); + + let oldTask = tasks[username].todos[index].text; + + // mark task as done + tasks[username].todos[index].done = true; + addDoneCount(username, 1); + + // add new task + tasks[username].todos.push({ text: task, done: false, focus: false }); + taskListMemory.totalTaskCount++; + + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + + return { + status: 200, + body: { + oldTask: oldTask, + newTask: task, + }, + }; + } +} + +function nextTask(username, task) { + const tasks = JSON.parse(localStorage.tasks); + if (!tasks[username] || tasks[username].todos.length === 0) { + return { + status: 0, + body: { + "error message": `@${username} has no tasks`, + error: responses.noTask, + }, + }; + } + + if (task === "") { + return { + status: 1, + body: { + "error message": `@${username} empty task`, + error: responses.nextNoContent, + }, + }; + } + + const incompleteTasks = tasks[username].todos.filter((t) => !t.done); + + if (incompleteTasks.length !== 1) { + return { + status: 0, + body: { + "error message": `@${username} has more than one incomplete task`, + error: responses.taskNextFailed, + }, + }; + } else { + // mark the incomplete task as complete, then add a new task "task" + + // find index of incomplete task + let index = tasks[username].todos.findIndex((t) => !t.done); + + let oldTask = tasks[username].todos[index].text; + + // mark task as done + tasks[username].todos[index].done = true; + addDoneCount(username, 1); + + // add new task + tasks[username].todos.push({ text: task, done: false, focus: false }); + taskListMemory.totalTaskCount++; + + localStorage.setItem(`tasks`, JSON.stringify(tasks)); + + return { + status: 200, + body: { + oldTask: oldTask, + newTask: task, + }, + }; + } +} + /** * Determines if a given value is an integer. * @@ -1151,12 +1489,8 @@ function markTaskDone(username, task) { if (isInt(t)) { index = parseInt(t) - 1; // ACTUAL INDEX } else if (incompleteTasks.length === 1) { - index = tasks[username].todos.findIndex( - (t) => !t.done - ); - tasksMarkedComplete.push( - tasks[username].todos[index].text - ); + index = tasks[username].todos.findIndex((t) => !t.done); + tasksMarkedComplete.push(tasks[username].todos[index].text); // increment count addDoneCount(username, 1); } else { @@ -1171,9 +1505,7 @@ function markTaskDone(username, task) { tasksFailedToComplete.push(t); continue; } else { - tasksMarkedComplete.push( - tasks[username].todos[index].text - ); + tasksMarkedComplete.push(tasks[username].todos[index].text); // increment count addDoneCount(username, 1); } @@ -1226,8 +1558,7 @@ function markTaskDone(username, task) { } else if (focusedTask) { index = tasks[username].todos.findIndex( (t) => - t.text.toLowerCase() === - focusedTask.text.toLowerCase() + t.text.toLowerCase() === focusedTask.text.toLowerCase() ); } else if (settings.automaticDoneIndex) { // index is the first incomplete task @@ -1379,9 +1710,7 @@ function markTaskUndone(username, task) { continue; } else { - tasksMarkedUndone.push( - tasks[username].todos[index].text - ); + tasksMarkedUndone.push(tasks[username].todos[index].text); } } else { tasksMarkedUndone.push(tasks[username].todos[index].text); @@ -1760,12 +2089,21 @@ function clearAll() { }; } -// 200: success -function clearAllExceptStreamer(streamer) { +/** + * 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[]} streamerUsernames - 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). + */ +function clearAllExceptStreamer(streamerUsername) { // clear all tasks except for broadcasters const tasks = JSON.parse(localStorage.tasks); + + // streamerusernames lowercased + for (const user in tasks) { - if (user.toLowerCase() !== streamer.toLowerCase()) { + if (user.toLowerCase() !== streamerUsername.toLowerCase()) { tasks[user].todos = []; } } @@ -1783,15 +2121,22 @@ function clearAllExceptStreamer(streamer) { }; } +const taskListMemory = { + doneTaskCount: 0, + totalTaskCount: 0, +}; + function renderTaskListToDOM() { const tasks = JSON.parse(localStorage.tasks); const taskContainers = document.querySelectorAll(".task-container"); + taskContainers.forEach((taskList) => { taskList.innerHTML = ""; let totalTaskCount = 0; let completedTasksCount = 0; + for (const user in tasks) { const userTasks = tasks[user]; if (userTasks.todos.length === 0) { @@ -1840,9 +2185,17 @@ function renderTaskListToDOM() { } } + if (taskListMemory.doneTaskCount > completedTasksCount) { + completedTasksCount = taskListMemory.doneTaskCount; + totalTaskCount = taskListMemory.totalTaskCount; + } + document.querySelector( ".task-count" ).innerText = `${completedTasksCount}/${totalTaskCount}`; + + taskListMemory.doneTaskCount = completedTasksCount; + taskListMemory.totalTaskCount = totalTaskCount; }); localStorage.setItem(`tasks`, JSON.stringify(tasks)); checkToAnimate();