stablyai / stablyai/orca

feat(mobile): Support hardware keyboard shortcut to send messages in Native Chat

Open
#14,744 1 comment 0 reactions 1 assignee Claimed by @brennanb2025 View on GitHub
Dominant language
TypeScript
Stars
71.3k
Forks
4.7k
Avg merge
14h 54m
Merged PRs (30d)
520

Description

## Summary

On iPad, when using Orca Native Chat with a Bluetooth / hardware keyboard, pressing **Enter/Return** inserts a newline instead of sending the message.

As a result, hardware keyboard users must reach for the screen and tap the **Send** button every time they want to submit a message.

This is particularly inconvenient when Orca is being used remotely from an iPad with a keyboard.

## Current behavior

In the mobile Native Chat composer, the message field is implemented as a multiline React Native `TextInput`.

Relevant component:

`mobile/src/session/MobileNativeChatComposer.tsx`

The input is configured with `multiline`, while message submission is handled separately by `handleSend()` and the on-screen send button.

Conceptually, the current behavior is:

```text
Hardware Enter / Return


Insert newline

On-screen Send button

handleSend()

Send message
```

There does not appear to be a hardware-keyboard shortcut connected to `handleSend()`.

## Proposed behavior

For iPad / hardware keyboard users, add a keyboard shortcut for sending the current message.

### Preferred behavior

```text
Cmd + Enter → Send message
Enter → Insert newline
```

I prefer **Cmd+Enter** over changing plain Enter because it preserves the existing multiline behavior and should reduce the risk of interfering with IME composition, including Korean input.

### Alternative behavior

Another common chat convention would be:

```text
Enter → Send message
Shift + Enter → Insert newline
```

However, modifier handling and IME composition should be considered carefully on iOS/iPadOS.

## Why this matters

Orca's mobile experience works well with an iPad and external keyboard, but Native Chat currently requires touching the screen for every message submission.

Supporting a hardware-keyboard send shortcut would make Native Chat much more practical for:

- iPad + Bluetooth keyboard users
- Magic Keyboard users
- Remote development sessions
- Keyboard-focused workflows

## Implementation area

The likely implementation point is:

`mobile/src/session/MobileNativeChatComposer.tsx`

The composer currently contains a multiline `TextInput` similar to:

```tsx
{
setCursor(e.nativeEvent.selection.end)
setPendingSelection(null)
}}
placeholder={placeholder}
placeholderTextColor={colors.textMuted}
selectionColor={colors.accentBlue}
multiline
textAlignVertical="top"
/>
```

The existing send path should ideally be reused rather than introducing separate submission logic:

```text
Hardware shortcut

handleSend()

existing onSend() path
```

## Implementation considerations

The shortcut should avoid triggering while an IME composition is being confirmed. This is particularly important for Korean, Japanese, and Chinese input methods.

Suggested requirements:

1. Detect a hardware keyboard send shortcut in the Native Chat composer.
2. Call the existing `handleSend()` function rather than duplicating send logic.
3. Preserve normal multiline Enter behavior when the send modifier is not pressed.
4. Avoid sending while IME text composition is still active.
5. Keep the on-screen Send button behavior unchanged.
6. Verify behavior on iPadOS with a physical/Bluetooth keyboard.

## Suggested test cases

| Input | Expected result |
|---|---|
| Enter | Newline |
| Cmd+Enter | Send message |
| Cmd+Enter with empty input | Do not send |
| Cmd+Enter while sending/disabled | Respect existing disabled state |
| Korean IME composition + Enter | Confirm composition, do not accidentally send |
| Korean text + Cmd+Enter after composition | Send normally |
| On-screen Send button | Existing behavior remains unchanged |

## Acceptance criteria

- [ ] A message can be sent from an iPad hardware keyboard without touching the screen.
- [ ] `Cmd+Enter` sends the message.
- [ ] Plain `Enter` continues to insert a newline.
- [ ] Existing `handleSend()` / `onSend()` behavior is reused.
- [ ] Empty or disabled messages are not sent unexpectedly.
- [ ] Korean/IME composition does not cause accidental message submission.
- [ ] The existing on-screen Send button continues to work.

## Relevant links

- Orca repository: https://github.com/stablyai/orca
- Mobile Native Chat composer: https://github.com/stablyai/orca/blob/4cacd5552c8d161a25967e7df85101f138c42cb8/mobile/src/session/MobileNativeChatComposer.tsx
- Related mobile Native Chat PR: https://github.com/stablyai/orca/pull/13658
- Related Native Chat composer PR: https://github.com/stablyai/orca/pull/13754

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.