authorgravatar for maxtheyoung@gmail.comMaxwell Young <maxtheyoung@gmail.com> 2026-07-18 09:14:45+12:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-17 23:14:45+02:00
log6a17629670f31a00719fb92c7c9413661cd6def5
tree017840fdba9d35d859d31a9010771bcba2265921
parent7b8d12618b3d857874a1cc709d11c5df087b6390
signature Signed by PGP key B5690EEEBB952194

[codex] fix mobile composer Enter behavior (#3930)

Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: codex <codex@users.noreply.github.com>

3 files changed, 27 insertions(+), 1 deletions(-)

apps/web/src/components/chat/ChatComposer.tsx+5-1
......@@ -41,6 +41,7 @@ import {
4141 detectComposerTrigger,
4242 expandCollapsedComposerCursor,
4343 replaceTextRange,
44 shouldSubmitComposerOnEnter,
4445} from "../../composer-logic";
4546import { deriveComposerSendState, readFileAsDataUrl } from "../ChatView.logic";
4647import {
......@@ -1750,7 +1751,10 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
17501751 return true;
17511752 }
17521753 }
1753 if (key === "Enter" && !event.shiftKey) {
1754 if (
1755 key === "Enter" &&
1756 shouldSubmitComposerOnEnter({ isMobileViewport, shiftKey: event.shiftKey })
1757 ) {
17541758 submitComposer();
17551759 return true;
17561760 }
apps/web/src/composer-logic.test.ts+15
......@@ -8,9 +8,24 @@ import {
88 isCollapsedCursorAdjacentToInlineToken,
99 parseStandaloneComposerSlashCommand,
1010 replaceTextRange,
11 shouldSubmitComposerOnEnter,
1112} from "./composer-logic";
1213import { INLINE_TERMINAL_CONTEXT_PLACEHOLDER } from "./lib/terminalContext";
1314
15describe("shouldSubmitComposerOnEnter", () => {
16 it("submits plain Enter on desktop", () => {
17 expect(shouldSubmitComposerOnEnter({ isMobileViewport: false, shiftKey: false })).toBe(true);
18 });
19
20 it("inserts a newline for plain Enter on mobile", () => {
21 expect(shouldSubmitComposerOnEnter({ isMobileViewport: true, shiftKey: false })).toBe(false);
22 });
23
24 it("inserts a newline for Shift+Enter", () => {
25 expect(shouldSubmitComposerOnEnter({ isMobileViewport: false, shiftKey: true })).toBe(false);
26 });
27});
28
1429describe("detectComposerTrigger", () => {
1530 it("detects @path trigger at cursor", () => {
1631 const text = "Please check @src/com";
apps/web/src/composer-logic.ts+7
......@@ -11,6 +11,13 @@ export interface ComposerTrigger {
1111 rangeEnd: number;
1212}
1313
14export function shouldSubmitComposerOnEnter(input: {
15 isMobileViewport: boolean;
16 shiftKey: boolean;
17}): boolean {
18 return !input.isMobileViewport && !input.shiftKey;
19}
20
1421const isInlineTokenSegment = (
1522 segment:
1623 | { type: "text"; text: string }