Fix file upload: disable inactive input on submit
Two inputs with name="file" caused Rack to pick up the empty one.
Track which input was used and disable the other before submit.

https://claude.ai/code/session_018Ym45siELMvsBQj4w9QAXf
change
commit 28eefe4129329978c1a137f239944eb5978a2752
author Alpha Chen <alpha@kejadlen.dev>
date
parent b984b9be
diff --git a/lib/views/capture.rb b/lib/views/capture.rb
index 822863a..461c5a3 100644
--- a/lib/views/capture.rb
+++ b/lib/views/capture.rb
@@ -59,7 +59,7 @@ module Domus
               capture: "environment",
               class: "sr-only",
               "x-ref": "cameraInput",
-              "@change": "onFileInput($event)"
+              "@change": "onCameraInput($event)"
             )
             input(
               type: "file",
@@ -101,7 +101,8 @@ module Domus
               "x-show": "state === 'saved'",
               method: "post",
               action: "/files",
-              enctype: "multipart/form-data"
+              enctype: "multipart/form-data",
+              "@submit": "onSubmit()"
             ) do
               div(class: "preview-zone") do
                 img(
diff --git a/public/capture.js b/public/capture.js
index 7495180..311a547 100644
--- a/public/capture.js
+++ b/public/capture.js
@@ -3,30 +3,39 @@ function captureApp() {
     state: 'capture',
     preview: null,
     dragging: false,
+    activeRef: null,
 
-    handleFile(file) {
+    handleFile(file, ref) {
       if (!file) return;
+      this.activeRef = ref;
       this.preview = file.type.startsWith('image/') ? URL.createObjectURL(file) : null;
       this.state = 'saved';
     },
 
-    onFileInput(e) {
-      this.handleFile(e.target.files[0]);
-    },
+    onCameraInput(e) { this.handleFile(e.target.files[0], 'cameraInput'); },
+    onFileInput(e)   { this.handleFile(e.target.files[0], 'fileInput'); },
 
     onDrop(e) {
       this.dragging = false;
       const file = e.dataTransfer?.files[0];
       if (file) {
         this.$refs.fileInput.files = e.dataTransfer.files;
-        this.handleFile(file);
+        this.handleFile(file, 'fileInput');
       }
     },
 
+    onSubmit() {
+      const inactive = this.activeRef === 'cameraInput' ? this.$refs.fileInput : this.$refs.cameraInput;
+      inactive.disabled = true;
+    },
+
     reset() {
       if (this.preview) URL.revokeObjectURL(this.preview);
       this.state = 'capture';
       this.preview = null;
+      this.activeRef = null;
+      this.$refs.fileInput.disabled = false;
+      this.$refs.cameraInput.disabled = false;
       this.$refs.fileInput.value = '';
       this.$refs.cameraInput.value = '';
     }