shelley: Fix Android keyboard covering chat input on Firefox (#48)

Michael Lynch and Shelley created

* Fix Android keyboard covering chat input on Firefox

When the virtual keyboard appears on Android Firefox, it can cover
the chat input field, making it impossible to see what you're typing.

This fix adds two mechanisms to ensure the input stays visible:

1. On focus: scroll the input into view with a small delay to let
   the keyboard animation start

2. On viewport resize: use the visualViewport API to detect when
   the keyboard changes the viewport size and scroll the input
   into view if it's focused

Fixes #47

Co-authored-by: Shelley <shelley@exe.dev>

* Drop the onFocus handler

The visualViewport API should be sufficient

* Restore previous comment

---------

Co-authored-by: Shelley <shelley@exe.dev>

Change summary

ui/src/components/MessageInput.tsx | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)

Detailed changes

ui/src/components/MessageInput.tsx 🔗

@@ -381,6 +381,29 @@ function MessageInput({
     }
   }, [autoFocus]);
 
+  // Handle virtual keyboard appearance on mobile (especially Android Firefox)
+  // The visualViewport API lets us detect when the keyboard shrinks the viewport
+  useEffect(() => {
+    if (typeof window === "undefined" || !window.visualViewport) {
+      return;
+    }
+
+    const handleViewportResize = () => {
+      // Only scroll if our textarea is focused (keyboard is for us)
+      if (document.activeElement === textareaRef.current) {
+        // Small delay to let the viewport settle after resize
+        requestAnimationFrame(() => {
+          textareaRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
+        });
+      }
+    };
+
+    window.visualViewport.addEventListener("resize", handleViewportResize);
+    return () => {
+      window.visualViewport?.removeEventListener("resize", handleViewportResize);
+    };
+  }, []);
+
   const isDisabled = disabled || uploadsInProgress > 0;
   const canSubmit = message.trim() && !isDisabled && !submitting;