mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-12-28 19:08:32 +08:00
Add dynamic keymap legend style (#2592) by Ferotiq
* Add dynamic keymap legend style * Speed * make it work with all layouts * Fix bug * Update layout-emulator.js * Update layout-emulator.js * mac fix * we didn't need layout state * make quote show up * remove some * Rename Co-authored-by: Miodec <bartnikjack@gmail.com>
This commit is contained in:
parent
6d496fe983
commit
34ac755630
10 changed files with 90 additions and 16 deletions
|
|
@ -60,7 +60,9 @@ const CONFIG_SCHEMA = joi.object({
|
|||
keymapStyle: joi
|
||||
.string()
|
||||
.valid("staggered", "alice", "matrix", "split", "split_matrix"),
|
||||
keymapLegendStyle: joi.string().valid("lowercase", "uppercase", "blank"),
|
||||
keymapLegendStyle: joi
|
||||
.string()
|
||||
.valid("lowercase", "uppercase", "blank", "dynamic"),
|
||||
keymapLayout: joi.string().valid(),
|
||||
fontFamily: joi.string(),
|
||||
smoothLineScroll: joi.boolean(),
|
||||
|
|
|
|||
|
|
@ -1422,13 +1422,13 @@ export function setKeymapLegendStyle(
|
|||
): boolean {
|
||||
if (
|
||||
!isConfigValueValid("keymap legend style", style, [
|
||||
["lowercase", "uppercase", "blank"],
|
||||
["lowercase", "uppercase", "blank", "dynamic"],
|
||||
])
|
||||
)
|
||||
return false;
|
||||
|
||||
// Remove existing styles
|
||||
const keymapLegendStyles = ["lowercase", "uppercase", "blank"];
|
||||
const keymapLegendStyles = ["lowercase", "uppercase", "blank", "dynamic"];
|
||||
keymapLegendStyles.forEach((name) => {
|
||||
$(".keymapLegendStyle").removeClass(name);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -779,6 +779,7 @@ $(document).keydown(async (event) => {
|
|||
correctShiftUsed =
|
||||
(await ShiftTracker.isUsingOppositeShift(event)) !== false;
|
||||
}
|
||||
|
||||
if (Config.funbox === "arrows") {
|
||||
let char = event.key;
|
||||
if (["ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown"].includes(char)) {
|
||||
|
|
|
|||
|
|
@ -1590,6 +1590,14 @@ const commandsKeymapLegendStyle: MonkeyTypes.CommandsGroup = {
|
|||
UpdateConfig.setKeymapLegendStyle("blank");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "setKeymapLegendStyleDynamic",
|
||||
display: "dynamic",
|
||||
configValue: "dynamic",
|
||||
exec: (): void => {
|
||||
UpdateConfig.setKeymapLegendStyle("dynamic");
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,10 @@ export async function refresh(
|
|||
} else if (Config.keymapLegendStyle === "uppercase") {
|
||||
keyDisplay = keyDisplay.toUpperCase();
|
||||
}
|
||||
const keyElement = `<div class="keymap-key" data-key="${key}">
|
||||
const keyElement = `<div class="keymap-key" data-key="${key.replace(
|
||||
'"',
|
||||
"""
|
||||
)}">
|
||||
<span class="letter">${keyDisplay}</span>
|
||||
${bump ? "<div class='bump'></div>" : ""}
|
||||
</div>`;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import Config from "../config";
|
||||
|
||||
export let capsState = false;
|
||||
|
||||
function show(): void {
|
||||
if ($("#capsWarning").hasClass("hidden")) {
|
||||
$("#capsWarning").removeClass("hidden");
|
||||
|
|
@ -13,11 +15,17 @@ function hide(): void {
|
|||
}
|
||||
|
||||
$(document).keydown(function (event) {
|
||||
if (
|
||||
event?.originalEvent?.getModifierState &&
|
||||
event?.originalEvent?.getModifierState("CapsLock")
|
||||
) {
|
||||
capsState = true;
|
||||
} else {
|
||||
capsState = false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (
|
||||
Config.capsLockWarning &&
|
||||
event.originalEvent?.getModifierState("CapsLock")
|
||||
) {
|
||||
if (Config.capsLockWarning && capsState) {
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
|
|
@ -26,11 +34,18 @@ $(document).keydown(function (event) {
|
|||
});
|
||||
|
||||
$(document).keyup(function (event) {
|
||||
if (
|
||||
event?.originalEvent?.getModifierState &&
|
||||
event?.originalEvent?.getModifierState("CapsLock")
|
||||
) {
|
||||
//filthy fix but optional chaining refues to work
|
||||
capsState = true;
|
||||
} else {
|
||||
capsState = false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (
|
||||
Config.capsLockWarning &&
|
||||
event.originalEvent?.getModifierState("CapsLock")
|
||||
) {
|
||||
if (Config.capsLockWarning && capsState) {
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import Config from "../config";
|
||||
import * as Misc from "../misc";
|
||||
import { capsLock } from "./caps-warning";
|
||||
|
||||
export async function getCharFromEvent(event) {
|
||||
function emulatedLayoutShouldShiftKey(event, newKeyPreview) {
|
||||
const isCapsLockHeld = event.originalEvent.getModifierState("CapsLock");
|
||||
if (isCapsLockHeld)
|
||||
return Misc.isASCIILetter(newKeyPreview) !== event.shiftKey;
|
||||
if (capsLock) return Misc.isASCIILetter(newKeyPreview) !== event.shiftKey;
|
||||
return event.shiftKey;
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +169,7 @@ export async function getCharFromEvent(event) {
|
|||
}
|
||||
|
||||
const layoutKeys = layout.keys;
|
||||
|
||||
const layoutMap = layoutKeys["row1"]
|
||||
.concat(layoutKeys["row2"])
|
||||
.concat(layoutKeys["row3"])
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import Config from "../config";
|
||||
import * as Misc from "../misc";
|
||||
import { capsLock } from "./caps-warning";
|
||||
|
||||
export let leftState = false;
|
||||
export let rightState = false;
|
||||
let caseState = false;
|
||||
|
||||
let keymapStrings = {
|
||||
left: null,
|
||||
|
|
@ -10,6 +12,33 @@ let keymapStrings = {
|
|||
keymap: null,
|
||||
};
|
||||
|
||||
function dynamicKeymapLegendStyle(uppercase) {
|
||||
const keymapKeys = [...document.getElementsByClassName("keymap-key")];
|
||||
|
||||
const layoutKeys = keymapKeys.map((el) => el.dataset.key);
|
||||
|
||||
const keys = keymapKeys.map((el) => el.childNodes[1]);
|
||||
|
||||
if (capsLock) uppercase = !uppercase;
|
||||
|
||||
if (layoutKeys.filter((v) => v === undefined).length > 2) return;
|
||||
|
||||
if ((uppercase && caseState) || (!uppercase && !caseState)) return;
|
||||
|
||||
const index = uppercase ? 1 : 0;
|
||||
|
||||
caseState = index === 1 ? true : false;
|
||||
|
||||
for (let i = 0; i < layoutKeys.length; i++) {
|
||||
const layoutKey = layoutKeys[i],
|
||||
key = keys[i];
|
||||
|
||||
if (key === undefined || layoutKey === undefined) continue;
|
||||
|
||||
key.textContent = layoutKey[index];
|
||||
}
|
||||
}
|
||||
|
||||
async function buildKeymapStrings() {
|
||||
if (keymapStrings.keymap === Config.keymapLayout) return;
|
||||
|
||||
|
|
@ -52,6 +81,10 @@ $(document).keydown((e) => {
|
|||
leftState = false;
|
||||
rightState = true;
|
||||
}
|
||||
|
||||
if (Config.keymapLegendStyle === "dynamic") {
|
||||
dynamicKeymapLegendStyle(leftState || rightState);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).keyup((e) => {
|
||||
|
|
@ -59,6 +92,10 @@ $(document).keyup((e) => {
|
|||
leftState = false;
|
||||
rightState = false;
|
||||
}
|
||||
|
||||
if (Config.keymapLegendStyle === "dynamic") {
|
||||
dynamicKeymapLegendStyle(leftState || rightState);
|
||||
}
|
||||
});
|
||||
|
||||
export function reset() {
|
||||
|
|
|
|||
2
frontend/src/scripts/types/types.d.ts
vendored
2
frontend/src/scripts/types/types.d.ts
vendored
|
|
@ -57,7 +57,7 @@ declare namespace MonkeyTypes {
|
|||
| "split"
|
||||
| "split_matrix";
|
||||
|
||||
type KeymapLegendStyle = "lowercase" | "uppercase" | "blank";
|
||||
type KeymapLegendStyle = "lowercase" | "uppercase" | "blank" | "dynamic";
|
||||
|
||||
type SingleListCommandLine = "manual" | "on";
|
||||
|
||||
|
|
|
|||
|
|
@ -3364,6 +3364,14 @@
|
|||
>
|
||||
blank
|
||||
</div>
|
||||
<div
|
||||
class="button"
|
||||
keymapLegendStyle="dynamic"
|
||||
tabindex="0"
|
||||
onclick="this.blur();"
|
||||
>
|
||||
dynamic
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sectionSpacer"></div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue