diff --git a/css/options.css b/css/options.css index c4918fa..37fd954 100644 --- a/css/options.css +++ b/css/options.css @@ -64,6 +64,7 @@ h2 { position: relative; flex-wrap: wrap; justify-content: flex-end; + min-height: 44px; } .setting-description { @@ -221,3 +222,36 @@ hr { .setting > div:first-of-type { margin: auto 4px auto auto; } + +/* For Notification Messages */ + +#notify { + --notificationBGColor: rgba(0, 137, 255, 0.6); + --notificationBorder: rgb(0, 137, 255); + --notificationTextColor: white; + position: sticky; + top: 0px; + width: 400px; + height: 0; + color: var(--notificationTextColor); + font-size: 15px; + font-weight: 500; + text-align: center; + background: var(--notificationBGColor); + overflow: hidden; + box-sizing: border-box; + transition: height .2s, border .2s, margin .2s; + left: 50%; + transform: translateX(-50%); +} + +#notifyText { + line-height: 50px; + vertical-align: middle; +} + +.active { + height:50px !important; + border-bottom: 2px var(--notificationBorder) solid !important; + margin-top: -50px; +} diff --git a/js/options.js b/js/options.js index 8b8c9a4..5e0dcbc 100644 --- a/js/options.js +++ b/js/options.js @@ -56,20 +56,64 @@ function enterNewHotkey(event) { window.removeEventListener("keydown", keyPress); window.removeEventListener("keyup", keyRelease); // setHotkeyBtn(element.parentNode); - updateHotkey(element, [...keysFinal]); + let newHotkey = [...keysFinal]; + if (isNotDuplicateHotkey(newHotkey, HOTKEY_CODES)) { + updateHotkey(element, newHotkey); + alertMessage("success", "Hotkey successfully added!", 2000); + } else { + updateHotkey(element, null); + alertMessage("failure", "That hotkey is already in use...", 2000); + } } } } +function alertMessage(type, text, timeOut) { + let notification = document.getElementById("notify"); + let notificationText = document.getElementById("notifyText"); + + // color the notification + let bgColor, textColor, borderColor; + switch (type) { + case "success": + bgColor = "rgb(67 255 125 / 70%)"; + textColor = "white"; + borderColor = "lime"; + break; + case "failure": + bgColor = "rgb(255 70 104 / 70%)"; + textColor = "white"; + borderColor = "red"; + break; + default: + bgColor = "rgb(0 137 255 / 60%)"; + textColor = "white"; + borderColor = "rgb(0 137 255)"; + break; + } + notification.style.setProperty("--notificationBGColor", bgColor); + notification.style.setProperty("--notificationBorder", borderColor); + notification.style.setProperty("--notificationTextColor", textColor); + + // Set the text + notificationText.innerHTML = text; + + // Show the notification for the specified time + notification.classList.add("active"); + setTimeout(function () { + notification.classList.remove("active"); + }, timeOut); +} + function updateHotkey(element, newVal, index) { let parentSection = element.parentNode; parentSection.removeChild(element); let newSettings = SETTINGS_FULL; - if (newVal === null) { + if (newVal === null && typeof index !== "undefined") { // remove the hotkey at the index provided newSettings.hotkeys.codes[parentSection.id].splice(index, 1); - } else { + } else if (newVal !== null) { // add the new hotkey to the beginning of the stored hotkeys newSettings.hotkeys.codes[parentSection.id].unshift(newVal); } @@ -148,6 +192,7 @@ function setHotkeyBtn(btnParent) { "click", (deleteHotkey = function () { updateHotkey(el, null, index); + alertMessage("success", "Hotkey removed!", 2000); }) ); btnParent.appendChild(el); @@ -155,6 +200,30 @@ function setHotkeyBtn(btnParent) { } } +function isNotDuplicateHotkey(newHotkey, allHotkeys) { + let arrayHotkeys = Object.values(allHotkeys); + for (command of arrayHotkeys) { + for (hotkey of command) { + if (areArraysEqual(newHotkey, hotkey)) { + return false; + } + } + } + // no duplicates found + return true; +} + +function areArraysEqual(a, b) { + if (a === b) return true; + if (a == null || b == null) return false; + if (a.length !== b.length) return false; + + for (var i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) return false; + } + return true; +} + getSettings(function () { // once the DOM is ready file in all settings info let stateCheck = setInterval(() => { diff --git a/options.html b/options.html index bccbfd5..3dcfb4e 100644 --- a/options.html +++ b/options.html @@ -9,6 +9,11 @@
+ +