Skip to content

Commit

Permalink
feat(settings): hotkeys customisation
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreDemailly committed Nov 30, 2023
1 parent 816cf17 commit 773d00f
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 48 deletions.
65 changes: 60 additions & 5 deletions public/css/views/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
overflow-y: auto;
}

#settings--view>h1 {
#settings--view>h1, #settings--view h2 {
height: 40px;
border-bottom: 2px solid var(--primary);
margin-bottom: 20px;
Expand All @@ -18,6 +18,20 @@
font-family: 'mononoki';
}

#settings--view h2 {
margin-top: 30px;
}

#settings--view .icon-keyboard {
background: url("../../img/keyboard-solid.svg");
background-position: 10% center;
background-repeat: no-repeat;
width: 34px;
height: 20px;
margin-right: 2px;
filter: invert(14%) sepia(80%) saturate(5663%) hue-rotate(252deg) brightness(69%) contrast(98%);
}

#settings--view>h1 i {
margin-right: 5px;
}
Expand All @@ -37,15 +51,56 @@
box-sizing: border-box;
}

#settings--view>form .line label,
#settings--view>form .line>p {
#settings--view>form .line p, #settings--view>form .line label {
font-size: 15px;
margin-bottom: 6px;
color: #4a5e68;
font-weight: bold;
letter-spacing: 0.5px;
}

#settings--view>form .line>p, #settings--view>form .line>label {
margin-bottom: 6px;
font-weight: bold;
}

#settings--view .shortcuts div:nth-child(n+1) {
margin-top: 10px;
}

#settings--view .shortcuts .note {
border-left: 3px solid #01579B;
padding: 10px 15px;
background: #81d4fa59;
color: #283593;
font-weight: 400;
border-radius: 2px;
box-sizing: border-box;
margin-bottom: 20px;
}

#settings--view .shortcuts label {
color: #4a5e68;
margin-left: 10px;
font-weight: 500;
}

#settings--view .shortcuts input:read-only {
background: transparent;
border-color: rgb(168, 168, 168);
color: rgb(141, 140, 140);
border-style: solid;
}

#settings--view .shortcuts input {
width: 36px;
height: 36px;
border-radius: 6px;
text-align: center;
font-family: system-ui;
font-size: 20px;
font-weight: 500;
border-bottom-width: 4px;
}

#settings--view>form .line>div {
display: flex;
height: 22px;
Expand Down
2 changes: 1 addition & 1 deletion public/img/arrow-right-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/img/keyboard-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 6 additions & 4 deletions public/js/components/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,23 @@ export class ViewNavigation {
navigationMenu.addEventListener("click", () => this.onNavigationSelected(navigationMenu));
}


document.addEventListener("keydown", (event) => {
if (window.searchbar.background.classList.contains("show")) {
return;
}

switch(event.code) {
case "KeyH": {
const hotkeys = JSON.parse(localStorage.getItem("hotkeys"));
switch (event.key.toUpperCase()) {
case hotkeys.home: {
this.onNavigationSelected(this.menus.get("home--view"));
break;
}
case "KeyN": {
case hotkeys.network: {
this.onNavigationSelected(this.menus.get("network--view"));
break;
}
case "KeyS": {
case hotkeys.settings: {
this.onNavigationSelected(this.menus.get("settings--view"));
break;
}
Expand Down
98 changes: 97 additions & 1 deletion public/js/components/settings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
// Import Third-party Dependencies
import { getJSON } from "@nodesecure/vis-network";

// CONSTANTS
const kAllowedHotKeys = new Set([
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "w", "x", "y", "z"
]);
const kDefaultHotKeys = {
home: "H",
network: "N",
settings: "S"
}

export class Settings {
static defaultMenuName = "info";

Expand All @@ -12,7 +24,9 @@ export class Settings {
/** @type {HTMLInputElement[]} */
warningsCheckbox: document.querySelectorAll("input[name='warnings']"),
/** @type {HTMLInputElement[]} */
flagsCheckbox: document.querySelectorAll("input[name='flags']")
flagsCheckbox: document.querySelectorAll("input[name='flags']"),
/** @type {HTMLInputElement} */
shortcutsSection: document.querySelector(".shortcuts"),
}

this.saveButton = document.querySelector(".save");
Expand All @@ -23,6 +37,88 @@ export class Settings {
for (const checkbox of [...this.dom.warningsCheckbox, ...this.dom.flagsCheckbox]) {
checkbox.addEventListener("change", () => this.enableSaveButton());
}

const that = this;
this.dom.shortcutsSection.querySelectorAll(".hotkey").forEach((input) => {
input.addEventListener("click", () => {
if (!input.readOnly) {
return;
}

const currentValue = input.value;
input.readOnly = false;
input.value = "";

const onKeyDown = (event) => {
// Prevent the app to change view if key is equal to view's hotkey
event.preventDefault();
event.stopPropagation();

function setValue(value) {
input.value = value;
input.readOnly = true;
input.blur();
input.removeEventListener("keydown", onKeyDown);
that.updateHotKeys();
}
if (event.key === currentValue) {
setValue(currentValue);
}

if (kAllowedHotKeys.has(event.key.toLowerCase())) {
const isHotKeyAlreadyUsed = [...this.dom.shortcutsSection.querySelectorAll(".hotkey")].find((input) => {
return input.value === event.key.toUpperCase();
});

setValue(isHotKeyAlreadyUsed ? currentValue : event.key.toUpperCase());
}
}
input.addEventListener("keydown", onKeyDown);
});
});

if (localStorage.getItem("hotkeys") === null) {
localStorage.setItem("hotkeys", JSON.stringify(kDefaultHotKeys));
}

const hotkeys = JSON.parse(localStorage.getItem("hotkeys"));
this.updateNavigationHotKey(hotkeys);
this.updateFormHotKeys(hotkeys);
}

updateNavigationHotKey(hotkeys) {
const navigationElement = document.getElementById("view-navigation");
navigationElement.querySelectorAll("span").forEach((span) => {
// network--view -> network
const viewName = span.parentElement.getAttribute("data-menu").split("--")[0];
const hotkey = hotkeys[viewName];
span.textContent = hotkey;
});
}

updateFormHotKeys(hotkeys) {
const hotkeysInputs = [...this.dom.shortcutsSection.querySelectorAll(".hotkey")];

for (const input of hotkeysInputs) {
const viewName = input.getAttribute("id");
const hotkey = hotkeys[viewName];
input.value = hotkey;
}
}

updateHotKeys() {
const hotkeys = {};
const hotkeysInputs = [...this.dom.shortcutsSection.querySelectorAll(".hotkey")];

for (const input of hotkeysInputs) {
const viewName = input.getAttribute("id");
const hotkey = input.value;
hotkeys[viewName] = hotkey;
}

this.updateNavigationHotKey(hotkeys);

localStorage.setItem("hotkeys", JSON.stringify(hotkeys));
}

enableSaveButton() {
Expand Down
Loading

0 comments on commit 773d00f

Please sign in to comment.