diff --git a/src/models/model.ts b/src/models/model.ts index ee3352dd5..a548d6c21 100644 --- a/src/models/model.ts +++ b/src/models/model.ts @@ -36,6 +36,7 @@ import { Cmd } from "./cmd"; import { GlobalCommandRunner } from "./global"; import { clearMonoFontCache, getMonoFontSize } from "@/util/textmeasure"; import type { TermWrap } from "@/plugins/terminal/term"; +import * as util from "@/util/util"; type SWLinePtr = { line: LineType; @@ -143,6 +144,8 @@ class Model { }); this.ws.reconnect(); this.keybindManager = new KeybindManager(); + this.readConfigKeybindings(); + this.initSystemKeybindings(); this.inputModel = new InputModel(this); this.pluginsModel = new PluginsModel(this); this.bookmarksModel = new BookmarksModel(this); @@ -201,8 +204,22 @@ class Model { }; } - initKeybindings(userKeybindings: any) { - this.keybindManager = new KeybindManager(userKeybindings); + readConfigKeybindings() { + const url = new URL(this.getBaseHostPort() + "/config/keybindings.json"); + let prtn = fetch(url, { method: "get", body: null, headers: this.getFetchHeaders() }); + prtn.then((resp) => { + if (resp.status == 404) { + return []; + } else if (!resp.ok) { + util.handleNotOkResp(resp, url); + } + return resp.json(); + }).then((userKeybindings) => { + this.keybindManager.setUserKeybindings(userKeybindings); + }); + } + + initSystemKeybindings() { this.keybindManager.registerKeybinding("system", "electron", "any", (waveEvent) => { if (this.keybindManager.checkKeyPressed(waveEvent, "system:toggleDeveloperTools")) { getApi().toggleDeveloperTools(); diff --git a/src/util/keyutil.ts b/src/util/keyutil.ts index dac4b9d63..3e030936c 100644 --- a/src/util/keyutil.ts +++ b/src/util/keyutil.ts @@ -1,8 +1,10 @@ import * as React from "react"; +import * as mobx from "mobx"; import * as electron from "electron"; import { parse } from "node:path"; import { v4 as uuidv4 } from "uuid"; -import keybindings from "../../assets/keybindings.json"; +import defaultKeybindingsFile from "../../assets/keybindings.json"; +const defaultKeybindings: KeybindConfig = defaultKeybindingsFile; type KeyPressDecl = { mods: { @@ -22,6 +24,7 @@ const KeyTypeKey = "key"; const KeyTypeCode = "code"; type KeybindCallback = (event: WaveKeyboardEvent) => boolean; +type KeybindConfig = Array<{ command: string; keys: Array }>; type Keybind = { domain: string; @@ -36,6 +39,66 @@ class KeybindManager { levelMap: Map>; levelArray: Array; keyDescriptionsMap: Map>; + userKeybindings: KeybindConfig; + userKeybindingError: OV; + + constructor() { + this.levelMap = new Map(); + this.domainCallbacks = new Map(); + this.levelArray = KeybindLevels; + for (let index = 0; index < this.levelArray.length; index++) { + let curLevel = this.levelArray[index]; + this.levelMap.set(curLevel, new Array()); + } + this.userKeybindingError = mobx.observable.box(null, { + name: "keyutil-userKeybindingError", + }); + this.initKeyDescriptionsMap(); + } + + initKeyDescriptionsMap() { + mobx.action(() => { + this.userKeybindingError.set(null); + })(); + let newKeyDescriptions = new Map(); + for (let index = 0; index < defaultKeybindings.length; index++) { + let curKeybind = defaultKeybindings[index]; + newKeyDescriptions.set(curKeybind.command, curKeybind.keys); + } + let curUserCommand = ""; + if (this.userKeybindings != null && this.userKeybindings instanceof Array) { + try { + console.log("setting user keybindings"); + for (let index = 0; index < this.userKeybindings.length; index++) { + let curKeybind = this.userKeybindings[index]; + if (curKeybind == null) { + throw new Error("keybind entry is null"); + } + curUserCommand = curKeybind.command; + if (typeof curKeybind.command != "string") { + throw new Error("invalid keybind command"); + } + if (curKeybind.keys == null || !(curKeybind.keys instanceof Array)) { + throw new Error("invalid keybind keys"); + } + for (let key of curKeybind.keys) { + if (typeof key != "string") { + throw new Error("invalid keybind key"); + } + } + newKeyDescriptions.set(curKeybind.command, curKeybind.keys); + } + } catch (e) { + let userError = `${curUserCommand} is invalid: error: ${e}`; + console.log(userError); + mobx.action(() => { + this.userKeybindingError.set(userError); + })(); + } + } + this.keyDescriptionsMap = newKeyDescriptions; + console.log("key desc map:", this.keyDescriptionsMap); + } processLevel(nativeEvent: any, event: WaveKeyboardEvent, keybindsArray: Array): boolean { // iterate through keybinds in backwards order @@ -196,50 +259,11 @@ class KeybindManager { this.domainCallbacks.set(domain, callback); } - constructor() { - this.levelMap = new Map(); - this.domainCallbacks = new Map(); - this.levelArray = KeybindLevels; - for (let index = 0; index < this.levelArray.length; index++) { - let curLevel = this.levelArray[index]; - this.levelMap.set(curLevel, new Array()); - } + setUserKeybindings(userKeybindings) { + this.userKeybindings = userKeybindings; this.initKeyDescriptionsMap(); } - initKeyDescriptionsMap() { - this.keyDescriptionsMap = new Map(); - for (let index = 0; index < keybindings.length; index++) { - let curKeybind = keybindings[index]; - this.keyDescriptionsMap.set(curKeybind.command, curKeybind.keys); - } - let error = false; - let numberedTabKeybinds = []; - for (let index = 1; index <= 9; index++) { - let curKeybind = this.keyDescriptionsMap.get("app:selectTab-" + index); - if (curKeybind == null) { - error = true; - break; - } - numberedTabKeybinds = numberedTabKeybinds.concat(curKeybind); - } - if (!error) { - this.keyDescriptionsMap.set("app:selectNumberedTab", numberedTabKeybinds); - } - let numberedWorkspaceKeybinds = []; - for (let index = 1; index <= 9; index++) { - let curKeybind = this.keyDescriptionsMap.get("app:selectTab-" + index); - if (curKeybind == null) { - error = true; - break; - } - numberedWorkspaceKeybinds = numberedWorkspaceKeybinds.concat(curKeybind); - } - if (!error) { - this.keyDescriptionsMap.set("app:selectNumberedTab", numberedWorkspaceKeybinds); - } - } - checkKeyPressed(event: WaveKeyboardEvent, keyDescription: string): boolean { if (keyDescription == "any") { return true; diff --git a/src/util/util.ts b/src/util/util.ts index a5a9bef6b..e91d47c73 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -398,6 +398,7 @@ function fireAndForget(f: () => Promise) { } export { + handleNotOkResp, handleJsonFetchResponse, base64ToString, stringToBase64, diff --git a/wavesrv/cmd/main-server.go b/wavesrv/cmd/main-server.go index 7744d841f..265da3108 100644 --- a/wavesrv/cmd/main-server.go +++ b/wavesrv/cmd/main-server.go @@ -680,17 +680,20 @@ func HandleRunCommand(w http.ResponseWriter, r *http.Request) { func AuthKeyMiddleWare(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { reqAuthKey := r.Header.Get("X-AuthKey") + w.Header().Set(CacheControlHeaderKey, CacheControlHeaderNoCache) if reqAuthKey == "" { + log.Printf("mk2\n") w.WriteHeader(500) w.Write([]byte("no x-authkey header")) return } if reqAuthKey != GlobalAuthKey { + log.Printf("mk1\n") w.WriteHeader(500) w.Write([]byte("x-authkey header is invalid")) return } - w.Header().Set(CacheControlHeaderKey, CacheControlHeaderNoCache) + log.Printf("mk3\n") next.ServeHTTP(w, r) }) }