From 51413c6f6f405dbd72397206db630b71676ab381 Mon Sep 17 00:00:00 2001 From: andOrlando <59105749+andOrlando@users.noreply.github.com> Date: Mon, 18 Jan 2021 12:19:01 -0500 Subject: [PATCH] adds an undo feature with ctrl+z -fixes a random tooltips bug for some reason -changes the ::after to ::before for no reason -adds an undo-registry to keep track of all the undos -adds states to make it easier to ascertain the status of a given snackbar -slightly improves a couple comments --- public/css/home.css | 4 ++-- public/js/buttonFunctions.js | 2 ++ public/js/home.js | 30 +++++++++++++++++++++++++-- public/js/snackbar.js | 40 +++++++++++++++++++++++++++++++++--- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/public/css/home.css b/public/css/home.css index 833e4b8c..ca80d1c1 100644 --- a/public/css/home.css +++ b/public/css/home.css @@ -1292,7 +1292,7 @@ p#large_clock_period { order: 2; } -.snackbar button::after { +.snackbar button::before { content: ''; height: 100%; width: 100%; @@ -1306,7 +1306,7 @@ p#large_clock_period { transition: opacity 100ms ease-in; } -.snackbar button:hover::after { +.snackbar button:hover::before { opacity: 1; } diff --git a/public/js/buttonFunctions.js b/public/js/buttonFunctions.js index 17416363..9b2b6e1e 100755 --- a/public/js/buttonFunctions.js +++ b/public/js/buttonFunctions.js @@ -304,6 +304,8 @@ let updateGradePage = function() { $(".gpa_select-selected").html("Quarter GPA: " + GPA.percent); $("#" + currentTerm).html("Quarter GPA: " + GPA.percent); } + + setup_tooltips(); } let exportTableData = async function(prefs) { diff --git a/public/js/home.js b/public/js/home.js index dbafa011..4ff6dda1 100644 --- a/public/js/home.js +++ b/public/js/home.js @@ -39,6 +39,23 @@ let termsReset = {}; // Counter for creating new assignments var newAssignmentIDCounter = 0; +// Registry for undos, contains assignment ID and the snackbar that corresponds to it +// contains all the undo snackbars +const undoRegistry = [] + +document.onkeydown = e => { + var evtobj = window.event || e + if (evtobj.keyCode == 90 && evtobj.ctrlKey && undoRegistry.length !== 0) { + console.log(`list: ${undoRegistry}`) + console.log(`state: ${undoRegistry[0].state}`) + if (undoRegistry[0].state == Snackbar.SHOWN) { + undoRegistry[0].destroy(); + } + undoRegistry[0].buttonClick(); + } +} + + let tempCell; // When the user clicks anywhere outside of a modal or dropdown, close it window.addEventListener("click", function(event) { @@ -595,18 +612,27 @@ let assignmentsTable = new Tabulator("#assignmentsTable", { width: 40, align: "center", cellClick: function(e, cell) { + const data = cell.getRow().getData() replaceAssignmentFromID(data, {assignment_id: data["assignment_id"], placeholder: true}, selected_class_i); - new Snackbar(`You deleted ${data["name"]}`, { + const undoSnackbar = new Snackbar(`You deleted ${data["name"]}`, { color: "var(--red1)", textColor: "var(--white)", buttonText: "Undo", - buttonClick: () => replaceAssignmentFromID({ assignment_id: data["assignment_id"], placeholder: true }, data, selected_class_i), + //buttonclick replaces the assignment with a placeholder that just contains the assignemnt ID + buttonClick: () => { + replaceAssignmentFromID({ assignment_id: data["assignment_id"], placeholder: true }, data, selected_class_i) + undoRegistry.splice(undoRegistry.indexOf(undoSnackbar), 1) + }, timeout: 7500, + //on either timeout or bodyclick (basically just when its dismissed) deletes the placeholder assignment timeoutFunction: () => removeAssignmentFromID(data["assignment_id"], selected_class_i), bodyClick: () => removeAssignmentFromID(data["assignment_id"], selected_class_i), }).show(); + + undoRegistry.push(undoSnackbar) + }, headerSort: false, cssClass: "icon-col allow-overflow" diff --git a/public/js/snackbar.js b/public/js/snackbar.js index 3ae9215f..7fdcebba 100644 --- a/public/js/snackbar.js +++ b/public/js/snackbar.js @@ -1,7 +1,29 @@ +/** snackbar.js + * Has all the snackbar class code in it + * To use the snackbar, just give it some text, give it some options (or not) and .show() it. + * It goes a little more into detail in the descriptions of each function. It also has a nice + * little jsdoc thing if you're using something that supports it. If not, sucks for you. + */ class Snackbar { + + /** + * snackbars contains key value pairs of snackbar IDs and snackbar references respectively + * if you ever need to get a snackbar from an ID + * snackbarIDs makes sure the IDs are unique + */ static snackbars = {}; static snackbarIDs = []; + /** + * state IDs + * DESTROYED means it doesn't exist in html + * HIDDEN means it exists but is hdiden + * SHOWN means it exists and is shown + */ + static DESTROYED = 0 + static HIDDEN = 1 + static SHOWN = 2 + /** * text is the main requirement, and it's just text * color: String - string reference to a color or a variable, sets the background color @@ -47,6 +69,10 @@ class Snackbar { //creates this.id this.id; + + //sets state to destroyed + this.state = Snackbar.DESTROYED + } /** @@ -61,6 +87,7 @@ class Snackbar { } //gives it an ID if it doesn't already have one + //this can happen if the snackbar object still exists but has been destroyed if (this.id === undefined) { this.createID(); } @@ -70,12 +97,12 @@ class Snackbar { snackbarNode.classList.add("snackbar"); snackbarNode.classList.add("hidden"); - //assigns it id based off of it's actual id + //assigns its id based off of it's actual id snackbarNode.id = `snackbar-${this.id}`; //adds color if given if (this.color !== undefined) { - snackbarNode.style.backgroundColor = `${this.color}`; + snackbarNode.style.backgroundColor = this.color; } //sets the body onclick listener which just destroys it by default @@ -135,6 +162,7 @@ class Snackbar { document.body.appendChild(snackbarNode); this.element = document.getElementById(`snackbar-${this.id}`); + this.state = Snackbar.HIDDEN return this; } @@ -154,7 +182,10 @@ class Snackbar { }, this.timeout); } - const removeHidden = () => this.element.classList.remove("hidden"); + const removeHidden = () => { + this.state = Snackbar.SHOWN + this.element.classList.remove("hidden"); + } //if not already made, makes the snackbar if (document.getElementById(`snackbar-${this.id}`) === null) { @@ -179,6 +210,7 @@ class Snackbar { } this.element.classList.add("hidden"); + this.state = Snackbar.HIDDEN return this; } @@ -197,6 +229,8 @@ class Snackbar { snackbar.id = undefined; } + this.state = Snackbar.DESTROYED + //if it's not hidden it shouldn't just dissapear if (this.element.classList.contains("hidden")) { finalizeDeletion();