mirror of
https://github.com/MathMan05/Fermi.git
synced 2026-10-15 02:20:26 +00:00
add shortcuts
This commit is contained in:
@@ -51,6 +51,8 @@ import {CDNParams} from "./utils/cdnParams.js";
|
||||
import {SnowFlake} from "./snowflake.js";
|
||||
import {trimTrailingSlashes} from "./utils/netUtils.js";
|
||||
import {Versions} from "./versions.js";
|
||||
import {Shortcut} from "./shortcuts/shortcut.js";
|
||||
import {getShortcuts, setShortcuts} from "./utils/storage/shortcuts.js";
|
||||
type traceObj = {
|
||||
micros: number;
|
||||
calls?: (string | traceObj)[];
|
||||
@@ -93,6 +95,7 @@ class Localuser {
|
||||
readonly messages = new Map<string, Message>();
|
||||
readonly idToPrev = new Map<string, string | undefined>();
|
||||
readonly idToNext = new Map<string, string | undefined>();
|
||||
static readonly globalShortcuts = new Shortcut();
|
||||
get status() {
|
||||
return this.user.status;
|
||||
}
|
||||
@@ -2570,6 +2573,15 @@ class Localuser {
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
static initShortcuts() {
|
||||
const cur = getShortcuts();
|
||||
for (const [name, combo] of cur) {
|
||||
this.globalShortcuts.registerKeycombo(combo, name);
|
||||
}
|
||||
this.globalShortcuts.registerShortcut("gifSearch", () => {
|
||||
document.getElementById("gifTB")?.click();
|
||||
});
|
||||
}
|
||||
async showusersettings() {
|
||||
const prefs = await getPreferences();
|
||||
const localSettings = getLocalSettings();
|
||||
@@ -3167,6 +3179,25 @@ class Localuser {
|
||||
}
|
||||
})();
|
||||
}
|
||||
{
|
||||
const shortcuts = settings.addButton(I18n.keyboard.shortcuts(), {contained: true});
|
||||
const cur = getShortcuts();
|
||||
console.log(Localuser.globalShortcuts);
|
||||
for (const [name] of cur) {
|
||||
shortcuts.addText(I18n.keyboard.descs[name]());
|
||||
shortcuts.addHTMLArea(
|
||||
Localuser.globalShortcuts.shortCutbutton(
|
||||
name,
|
||||
(short) => {
|
||||
cur[name] = short;
|
||||
setShortcuts(cur);
|
||||
console.log(cur);
|
||||
},
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const installP = installPGet();
|
||||
if (installP) {
|
||||
@@ -5528,4 +5559,6 @@ class Localuser {
|
||||
return userinfos.preferences.notisound;
|
||||
}
|
||||
}
|
||||
Localuser.globalShortcuts.listen(document.body);
|
||||
Localuser.initShortcuts();
|
||||
export {Localuser};
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import {I18n} from "../i18n";
|
||||
|
||||
export class Shortcut {
|
||||
private shortcuts = new Map<string, () => void>();
|
||||
private keycombos = new Map<string, string>();
|
||||
private nameToCombo = new Map<string, Set<string>>();
|
||||
registerShortcut(name: string, callback: () => void) {
|
||||
this.shortcuts.set(name, callback);
|
||||
}
|
||||
unregisterKeycombo(combo: string) {
|
||||
const name = this.keycombos.get(combo);
|
||||
this.keycombos.delete(Shortcut.normalize(combo));
|
||||
if (!name) return;
|
||||
let nset = this.nameToCombo.get(name);
|
||||
if (nset) nset.delete(combo);
|
||||
}
|
||||
registerKeycombo(combo: string, name: string) {
|
||||
combo = Shortcut.normalize(combo);
|
||||
this.keycombos.set(combo, name);
|
||||
let nset = this.nameToCombo.get(name);
|
||||
if (!nset) {
|
||||
nset = new Set();
|
||||
this.nameToCombo.set(name, nset);
|
||||
}
|
||||
nset.add(combo);
|
||||
}
|
||||
clear() {
|
||||
this.keycombos.clear();
|
||||
this.shortcuts.clear();
|
||||
this.nameToCombo.clear();
|
||||
}
|
||||
private static normalize(e: string): string {
|
||||
const code = new Set(e.toLowerCase().split("-"));
|
||||
const build = [] as string[];
|
||||
if (code.has("meta")) build.push("meta");
|
||||
if (code.has("ctrl")) build.push("ctrl");
|
||||
if (code.has("alt")) build.push("alt");
|
||||
if (code.has("shift")) build.push("shift");
|
||||
build.push(...[...code].filter((_) => _.length === 1).map((_) => _.toLowerCase()));
|
||||
return build.join("-");
|
||||
}
|
||||
private static eventToCombo(e: KeyboardEvent, down = true): string {
|
||||
const build = [] as string[];
|
||||
if (e.metaKey || (e.key === "Meta" && down)) {
|
||||
if (e.key !== "Meta" || down) build.push("meta");
|
||||
}
|
||||
if (e.ctrlKey) build.push("ctrl");
|
||||
if (e.altKey) build.push("alt");
|
||||
if (e.shiftKey) build.push("shift");
|
||||
if (e.key.length === 1) build.push(e.key.toLowerCase());
|
||||
return build.join("-");
|
||||
}
|
||||
shortCutbutton(name: string | null, callback: (combo: string) => void, updateCombo: boolean) {
|
||||
let cur = (name && [...(this.nameToCombo.get(name) ?? [])].at(0)) ?? "";
|
||||
const button = document.createElement("button");
|
||||
function updateButton(combo?: string) {
|
||||
button.textContent = combo || cur || I18n.keyboard.empty();
|
||||
}
|
||||
const register = () => {
|
||||
button.onkeyup = (event) => {
|
||||
const combo = Shortcut.eventToCombo(event, false);
|
||||
updateButton(combo);
|
||||
};
|
||||
button.onkeydown = (event) => {
|
||||
const combo = Shortcut.eventToCombo(event);
|
||||
updateButton(combo);
|
||||
if (event.key.length === 1) {
|
||||
callback(combo);
|
||||
button.onkeyup = () => {};
|
||||
button.onkeydown = () => {};
|
||||
if (updateCombo && name) {
|
||||
this.unregisterKeycombo(cur);
|
||||
this.registerKeycombo(combo, name);
|
||||
}
|
||||
cur = combo;
|
||||
updateButton();
|
||||
}
|
||||
event.preventDefault();
|
||||
};
|
||||
button.onblur = () => {
|
||||
button.onkeyup = () => {};
|
||||
button.onkeydown = () => {};
|
||||
updateButton();
|
||||
};
|
||||
};
|
||||
button.onclick = register;
|
||||
updateButton();
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("flexltr", "shortCutSetting");
|
||||
|
||||
const clear = document.createElement("button");
|
||||
clear.textContent = I18n.settings.clear();
|
||||
div.append(button, clear);
|
||||
clear.onclick = () => {
|
||||
callback("");
|
||||
if (updateCombo && name) {
|
||||
this.unregisterKeycombo(cur);
|
||||
}
|
||||
cur = "";
|
||||
updateButton();
|
||||
};
|
||||
return div;
|
||||
}
|
||||
listen(elm: HTMLElement) {
|
||||
elm.addEventListener("keydown", (event) => {
|
||||
if (event.key.length !== 1) return;
|
||||
const combo = Shortcut.eventToCombo(event);
|
||||
const name = this.keycombos.get(combo);
|
||||
if (!name) return;
|
||||
const func = this.shortcuts.get(name);
|
||||
if (!func) return;
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
func();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -187,6 +187,11 @@ body {
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
}
|
||||
.shortCutSetting {
|
||||
:last-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.pollRes {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const props = ["gifSearch"] as const;
|
||||
export class Shortcuts {
|
||||
gifSearch = "ctrl+g";
|
||||
|
||||
constructor(data: Partial<Shortcuts> = {}) {
|
||||
Object.assign(this, data);
|
||||
}
|
||||
*[Symbol.iterator]() {
|
||||
for (const thing of props) {
|
||||
yield [thing, this[thing]] as const;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export function getShortcuts(): Shortcuts {
|
||||
return new Shortcuts(JSON.parse(localStorage.getItem("shortCuts") ?? "{}"));
|
||||
}
|
||||
|
||||
export function setShortcuts(settings: Shortcuts): void {
|
||||
localStorage.setItem("shortCuts", JSON.stringify(settings));
|
||||
}
|
||||
@@ -991,6 +991,13 @@
|
||||
"editMode":{
|
||||
"editMsg":"Escape to $1cancel$1"
|
||||
},
|
||||
"keyboard":{
|
||||
"shortcuts":"Shortcuts",
|
||||
"empty":"<No keybind set>",
|
||||
"descs":{
|
||||
"gifSearch":"Search GIFs:"
|
||||
}
|
||||
},
|
||||
"domain":{
|
||||
"title":"Verify domain",
|
||||
"domain":"Domain:",
|
||||
|
||||
Reference in New Issue
Block a user