Merge pull request #11 from Pathduck/multiple-hotkeys-for-each-command
Multiple hotkeys for each command
This commit is contained in:
commit
bb48b83177
@ -59,12 +59,12 @@ h2 {
|
||||
|
||||
.setting {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
position: relative;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.setting-description {
|
||||
@ -83,8 +83,8 @@ h2 {
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
border: 0;
|
||||
border-top: 1px solid #3e4852;
|
||||
box-sizing: content-box;
|
||||
@ -120,6 +120,10 @@ hr {
|
||||
margin: 6px 10px;
|
||||
}
|
||||
|
||||
.hotkeys {
|
||||
margin: 7px 4px;
|
||||
}
|
||||
|
||||
.hotkeys .btn-text {
|
||||
margin-right: 0;
|
||||
}
|
||||
@ -130,6 +134,7 @@ hr {
|
||||
|
||||
.btn-enter {
|
||||
background-color: #00b1e2;
|
||||
margin: 7px 4px;
|
||||
}
|
||||
|
||||
.reset-area {
|
||||
@ -202,3 +207,51 @@ hr {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.addHotkey {
|
||||
opacity: 0;
|
||||
margin: 7px 4px;
|
||||
transition: opacity 0.4s ease-out;
|
||||
}
|
||||
|
||||
.setting:hover .addHotkey {
|
||||
opacity: 1;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
@ -2,17 +2,17 @@ chrome.runtime.onInstalled.addListener(function () {
|
||||
let settings = {
|
||||
hotkeys: {
|
||||
codes: {
|
||||
navUp: ["w"],
|
||||
navLeft: ["a"],
|
||||
navDown: ["s"],
|
||||
navRight: ["d"],
|
||||
expand: ["e"],
|
||||
contract: ["shift", "e"],
|
||||
quit: ["q"],
|
||||
click: ["enter"],
|
||||
shiftClick: ["shift", "enter"],
|
||||
controlClick: ["control", "enter"],
|
||||
disableKeys: ["control", "shift", "x"],
|
||||
navUp: [["w"]],
|
||||
navLeft: [["a"]],
|
||||
navDown: [["s"]],
|
||||
navRight: [["d"]],
|
||||
expand: [["e"]],
|
||||
contract: [["shift", "e"]],
|
||||
quit: [["q"]],
|
||||
click: [["f"], ["enter"]],
|
||||
shiftClick: [["shift", "enter"]],
|
||||
controlClick: [["control", "enter"]],
|
||||
disableKeys: [["control", "shift", "x"]],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
159
js/options.js
159
js/options.js
@ -5,7 +5,6 @@ function getSettings(callback) {
|
||||
chrome.storage.local.get(["extension-settings"], function (result) {
|
||||
SETTINGS_FULL = result["extension-settings"];
|
||||
HOTKEY_CODES = SETTINGS_FULL.hotkeys.codes;
|
||||
console.log(HOTKEY_CODES);
|
||||
if (callback instanceof Function) {
|
||||
callback();
|
||||
}
|
||||
@ -44,7 +43,6 @@ function enterNewHotkey(event) {
|
||||
setHotkeyBtn(element.parentNode);
|
||||
}
|
||||
keysDown.add(e.key.toLowerCase(), keysDown.size);
|
||||
console.log(keysDown);
|
||||
textArea.innerHTML = formateHotkeys(keysDown);
|
||||
keysFinal = new Set(keysDown);
|
||||
}
|
||||
@ -56,18 +54,70 @@ 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 updateHotkey(element, newVal) {
|
||||
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;
|
||||
newSettings.hotkeys.codes[parentSection.id] = newVal;
|
||||
|
||||
if (newVal === null && typeof index !== "undefined") {
|
||||
// remove the hotkey at the index provided
|
||||
newSettings.hotkeys.codes[parentSection.id].splice(index, 1);
|
||||
} else if (newVal !== null) {
|
||||
// add the new hotkey to the beginning of the stored hotkeys
|
||||
newSettings.hotkeys.codes[parentSection.id].unshift(newVal);
|
||||
}
|
||||
|
||||
chrome.storage.local.set({ "extension-settings": newSettings }, function () {
|
||||
setHotkeyBtn(parentSection);
|
||||
getSettings(setHotkeyBtn(parentSection));
|
||||
// TODO: Send message to content scripts that settings updated
|
||||
});
|
||||
}
|
||||
@ -97,23 +147,37 @@ function formateHotkeys(set1) {
|
||||
return keyString;
|
||||
}
|
||||
|
||||
function setHotkeyBtn(element) {
|
||||
let el = document.createElement("div");
|
||||
function setHotkeyBtn(btnParent) {
|
||||
let hotkeys = HOTKEY_CODES[btnParent.id];
|
||||
|
||||
// remove old buttons
|
||||
while (btnParent.childNodes.length > 2) {
|
||||
btnParent.removeChild(btnParent.lastChild);
|
||||
}
|
||||
|
||||
// TODO: Check if hotkey combo in storage
|
||||
|
||||
let createNewBtn = document.createElement("div");
|
||||
createNewBtn.setAttribute("id", btnParent.id + "-btn");
|
||||
createNewBtn.setAttribute("class", "btn btn-hov addHotkey");
|
||||
createNewBtn.innerHTML = `
|
||||
<span class="btn-text">
|
||||
Click to type a new shortcut
|
||||
</span>
|
||||
`;
|
||||
// Add listner for new hotkey input
|
||||
createNewBtn.addEventListener("click", enterNewHotkey);
|
||||
btnParent.appendChild(createNewBtn);
|
||||
|
||||
// if in storage print stored combo
|
||||
if (HOTKEY_CODES[element.id].length !== 0) {
|
||||
console.log(element.id);
|
||||
// delete previous btn
|
||||
let old = document.getElementById(element.id + "-hotkey");
|
||||
if (old !== null && element.parentNode) {
|
||||
old.parentNode.removeChild(old);
|
||||
}
|
||||
el.setAttribute("id", element.id + "-hotkey");
|
||||
el.setAttribute("class", "btn hotkeys");
|
||||
el.innerHTML = `
|
||||
if (hotkeys.length !== 0) {
|
||||
hotkeys.forEach((hotkey, index) => {
|
||||
let el = document.createElement("div");
|
||||
el.setAttribute("id", btnParent.id + "-hotkey-" + index);
|
||||
el.setAttribute("class", "btn hotkeys");
|
||||
el.innerHTML = `
|
||||
<span class="btn-text">
|
||||
${formateHotkeys(new Set(HOTKEY_CODES[element.id]))}
|
||||
${formateHotkeys(new Set(hotkey))}
|
||||
</span>
|
||||
<button class="close" title="Delete shortcut">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
||||
@ -121,33 +185,42 @@ function setHotkeyBtn(element) {
|
||||
</svg>
|
||||
</button>
|
||||
`;
|
||||
el.getElementsByClassName("close")[0].addEventListener(
|
||||
"click",
|
||||
(deleteHotkey = function () {
|
||||
updateHotkey(el, []);
|
||||
})
|
||||
);
|
||||
element.appendChild(el);
|
||||
} else {
|
||||
// delete any previous btn
|
||||
let old = document.getElementById(element.id + "-btn");
|
||||
if (old !== null && element.parentNode) {
|
||||
old.parentNode.removeChild(old);
|
||||
}
|
||||
|
||||
el.setAttribute("id", element.id + "-btn");
|
||||
el.setAttribute("class", "btn btn-hov");
|
||||
el.innerHTML = `
|
||||
<span class="btn-text">
|
||||
Click to type a new shortcut
|
||||
</span>
|
||||
`;
|
||||
// Add listner for new hotkey input
|
||||
el.addEventListener("click", enterNewHotkey);
|
||||
element.appendChild(el);
|
||||
el.getElementsByClassName("close")[0].addEventListener(
|
||||
"click",
|
||||
(deleteHotkey = function () {
|
||||
updateHotkey(el, null, index);
|
||||
alertMessage("success", "Hotkey removed!", 2000);
|
||||
})
|
||||
);
|
||||
btnParent.appendChild(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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(() => {
|
||||
|
@ -1819,7 +1819,9 @@ function getSettings(callback) {
|
||||
exports.getSettings = getSettings;
|
||||
|
||||
function isHotkeyPressed(hotkeyID) {
|
||||
return setArrayMatch(KEYS_DOWN, HOTKEY_CODES[hotkeyID]);
|
||||
return HOTKEY_CODES[hotkeyID].some((combo) => {
|
||||
return setArrayMatch(KEYS_DOWN, combo);
|
||||
})
|
||||
}
|
||||
exports.isHotkeyPressed = isHotkeyPressed;
|
||||
|
||||
|
@ -9,6 +9,11 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- For popup messages -->
|
||||
<div id="notify">
|
||||
<span id="notifyText" class=""></span>
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<h1>Spatial Navigation Options</h1>
|
||||
<hr width="50%">
|
||||
|
Loading…
Reference in New Issue
Block a user