webui: add cmd+s keyboard shortcut to Monaco diff editor

Add Cmd+S (Ctrl+S on Windows/Linux) keyboard shortcut to trigger save
in Monaco diff editor instead of browser save dialog.

This prevents people with cmd+s-in-editor habits from constantly
having to dismiss browser save pop-up dialogs.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sd86641652ae6f54ak
diff --git a/webui/src/web-components/sketch-monaco-view.ts b/webui/src/web-components/sketch-monaco-view.ts
index 40b1200..9d84aa2 100644
--- a/webui/src/web-components/sketch-monaco-view.ts
+++ b/webui/src/web-components/sketch-monaco-view.ts
@@ -112,7 +112,7 @@
 
   // Custom event to request save action from external components
   private requestSave() {
-    if (this.saveState !== "modified") return;
+    if (!this.editableRight || this.saveState !== "modified") return;
 
     this.saveState = "saving";
 
@@ -148,6 +148,22 @@
     }
   }
 
+  // Rescue people with strong save-constantly habits
+  private setupKeyboardShortcuts() {
+    if (!this.editor) return;
+    const modifiedEditor = this.editor.getModifiedEditor();
+    if (!modifiedEditor) return;
+
+    modifiedEditor.addCommand(
+      monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
+      () => {
+        this.requestSave();
+      }
+    );
+
+    console.log("Keyboard shortcuts set up for Monaco editor");
+  }
+
   // Setup content change listener for debounced save
   private setupContentChangeListener() {
     if (!this.editor || !this.editableRight) return;
@@ -626,6 +642,8 @@
         // Set up selection change event listeners for both editors
         this.setupSelectionChangeListeners();
 
+        this.setupKeyboardShortcuts();
+
         // If this is an editable view, set the correct read-only state for each editor
         if (this.editableRight) {
           // Make sure the original editor is always read-only