feat(web): multiline composer — Enter adds a newline, arrow sends
Stops fat-fingered early sends. The single-line input is now an auto-growing textarea (Claude-app style): Enter inserts a newline and expands the box (up to a cap, then it scrolls); you tap the ↑ arrow to send. ⌘/Ctrl+Enter still sends from a hardware keyboard. Send button is now a round arrow; box resets to one line after sending. Mobile button is a 42-44px touch target. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -116,8 +116,8 @@
|
||||
|
||||
<!-- Input box -->
|
||||
<div id="input">
|
||||
<input id="userInput" type="text" placeholder="Type a message..." autofocus />
|
||||
<button id="sendBtn">Send</button>
|
||||
<textarea id="userInput" rows="1" placeholder="Type a message…" autofocus></textarea>
|
||||
<button id="sendBtn" aria-label="Send" title="Send (or ⌘/Ctrl+Enter)">↑</button>
|
||||
</div>
|
||||
|
||||
<!-- Bottom tab bar (mobile only; hides while the keyboard is open) -->
|
||||
@@ -287,6 +287,8 @@
|
||||
if (!msg) return;
|
||||
inputEl.value = "";
|
||||
|
||||
autoGrow(inputEl); // collapse the box back to one line after clearing
|
||||
|
||||
addMessage("user", msg);
|
||||
history.push({ role: "user", content: msg });
|
||||
await saveSession(); // ✅ persist both user + assistant messages
|
||||
@@ -548,6 +550,13 @@
|
||||
return b;
|
||||
}
|
||||
|
||||
// Grow the input textarea to fit its content (up to a cap, then it scrolls).
|
||||
function autoGrow(el) {
|
||||
if (!el) return;
|
||||
el.style.height = "auto";
|
||||
el.style.height = Math.min(el.scrollHeight, 140) + "px";
|
||||
}
|
||||
|
||||
function addMessage(role, text, autoScroll = true) {
|
||||
const messagesEl = document.getElementById("messages");
|
||||
|
||||
@@ -1004,11 +1013,15 @@
|
||||
checkHealth();
|
||||
setInterval(checkHealth, 10000);
|
||||
|
||||
// Input events
|
||||
// Input events. Enter inserts a newline and grows the box (like the Claude
|
||||
// app) — you tap the arrow to send. ⌘/Ctrl+Enter sends from the keyboard.
|
||||
document.getElementById("sendBtn").addEventListener("click", sendMessage);
|
||||
document.getElementById("userInput").addEventListener("keypress", e => {
|
||||
if (e.key === "Enter") sendMessage();
|
||||
const inputBox = document.getElementById("userInput");
|
||||
inputBox.addEventListener("input", () => autoGrow(inputBox));
|
||||
inputBox.addEventListener("keydown", e => {
|
||||
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); sendMessage(); }
|
||||
});
|
||||
autoGrow(inputBox);
|
||||
|
||||
// ========== THINKING STREAM INTEGRATION ==========
|
||||
const thinkingPanel = document.getElementById("thinkingPanel");
|
||||
|
||||
Reference in New Issue
Block a user