| author | |
| committer | |
| log | 6a17629670f31a00719fb92c7c9413661cd6def5 |
| tree | 017840fdba9d35d859d31a9010771bcba2265921 |
| parent | 7b8d12618b3d857874a1cc709d11c5df087b6390 |
| signature | Signed by PGP key B5690EEEBB952194 |
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 { | ... | @@ -41,6 +41,7 @@ import { |
| 41 | detectComposerTrigger, | 41 | detectComposerTrigger, |
| 42 | expandCollapsedComposerCursor, | 42 | expandCollapsedComposerCursor, |
| 43 | replaceTextRange, | 43 | replaceTextRange, |
| 44 | shouldSubmitComposerOnEnter, | ||
| 44 | } from "../../composer-logic"; | 45 | } from "../../composer-logic"; |
| 45 | import { deriveComposerSendState, readFileAsDataUrl } from "../ChatView.logic"; | 46 | import { deriveComposerSendState, readFileAsDataUrl } from "../ChatView.logic"; |
| 46 | import { | 47 | import { |
| ... | @@ -1750,7 +1751,10 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -1750,7 +1751,10 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 1750 | return true; | 1751 | return true; |
| 1751 | } | 1752 | } |
| 1752 | } | 1753 | } |
| 1753 | if (key === "Enter" && !event.shiftKey) { | 1754 | if ( |
| 1755 | key === "Enter" && | ||
| 1756 | shouldSubmitComposerOnEnter({ isMobileViewport, shiftKey: event.shiftKey }) | ||
| 1757 | ) { | ||
| 1754 | submitComposer(); | 1758 | submitComposer(); |
| 1755 | return true; | 1759 | return true; |
| 1756 | } | 1760 | } |
apps/web/src/composer-logic.test.ts+15| ... | @@ -8,9 +8,24 @@ import { | ... | @@ -8,9 +8,24 @@ import { |
| 8 | isCollapsedCursorAdjacentToInlineToken, | 8 | isCollapsedCursorAdjacentToInlineToken, |
| 9 | parseStandaloneComposerSlashCommand, | 9 | parseStandaloneComposerSlashCommand, |
| 10 | replaceTextRange, | 10 | replaceTextRange, |
| 11 | shouldSubmitComposerOnEnter, | ||
| 11 | } from "./composer-logic"; | 12 | } from "./composer-logic"; |
| 12 | import { INLINE_TERMINAL_CONTEXT_PLACEHOLDER } from "./lib/terminalContext"; | 13 | import { INLINE_TERMINAL_CONTEXT_PLACEHOLDER } from "./lib/terminalContext"; |
| 13 | 14 | ||
| 15 | describe("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 | |||
| 14 | describe("detectComposerTrigger", () => { | 29 | describe("detectComposerTrigger", () => { |
| 15 | it("detects @path trigger at cursor", () => { | 30 | it("detects @path trigger at cursor", () => { |
| 16 | const text = "Please check @src/com"; | 31 | const text = "Please check @src/com"; |
apps/web/src/composer-logic.ts+7| ... | @@ -11,6 +11,13 @@ export interface ComposerTrigger { | ... | @@ -11,6 +11,13 @@ export interface ComposerTrigger { |
| 11 | rangeEnd: number; | 11 | rangeEnd: number; |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | export function shouldSubmitComposerOnEnter(input: { | ||
| 15 | isMobileViewport: boolean; | ||
| 16 | shiftKey: boolean; | ||
| 17 | }): boolean { | ||
| 18 | return !input.isMobileViewport && !input.shiftKey; | ||
| 19 | } | ||
| 20 | |||
| 14 | const isInlineTokenSegment = ( | 21 | const isInlineTokenSegment = ( |
| 15 | segment: | 22 | segment: |
| 16 | | { type: "text"; text: string } | 23 | | { type: "text"; text: string } |