Skip to content

Commit 07a67ed

Browse files
committed
Fix keyboard command and layout bugs in mobile app
- Suppress focusSearch key commands (Cmd+F, Cmd+K) when a text input is active so they don't steal focus from the composer or other fields - Account for sidebar width when constraining file inspector width so the inspector doesn't grow so large it unnecessarily suppresses the thread sidebar at medium viewport sizes - Register a files keyboard command handler in ThreadRouteContent that opens the inspector pane in split view, matching toolbar behavior instead of always pushing a files route via stack navigation
1 parent 4689c43 commit 07a67ed

5 files changed

Lines changed: 24 additions & 7 deletions

File tree

apps/mobile/modules/t3-native-controls/ios/T3KeyboardCommandsModule.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ public final class T3KeyboardCommandsView: ExpoView {
2121
public override var canBecomeFirstResponder: Bool { true }
2222

2323
public override var keyCommands: [UIKeyCommand]? {
24-
[
24+
let responder = window?.t3FirstResponder
25+
let textInputActive = responder is UITextField || responder is UITextView
26+
27+
return [
2528
enabledCommand("newTask", input: "n", modifiers: .command, action: #selector(newTask), title: "New Task"),
26-
enabledCommand("focusSearch", input: "f", modifiers: .command, action: #selector(focusSearch), title: "Find"),
27-
enabledCommand("focusSearch", input: "k", modifiers: .command, action: #selector(focusSearch), title: "Focus Search"),
29+
textInputActive ? nil : enabledCommand("focusSearch", input: "f", modifiers: .command, action: #selector(focusSearch), title: "Find"),
30+
textInputActive ? nil : enabledCommand("focusSearch", input: "k", modifiers: .command, action: #selector(focusSearch), title: "Focus Search"),
2831
enabledCommand("back", input: "[", modifiers: .command, action: #selector(goBack), title: "Back"),
2932
enabledCommand("files", input: "f", modifiers: [.command, .shift], action: #selector(openFiles), title: "Open Files"),
3033
enabledCommand("terminal", input: "t", modifiers: [.command, .shift], action: #selector(openTerminal), title: "Open Terminal"),

apps/mobile/src/features/layout/AdaptiveWorkspaceLayout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export function AdaptiveWorkspaceLayout(props: { readonly children: ReactNode })
131131
layout,
132132
viewportWidth: width,
133133
preferredWidth: fileInspectorPreferredWidth ?? undefined,
134+
sidebarWidth: layout.listPaneWidth ?? 0,
134135
}),
135136
[fileInspectorPreferredWidth, layout, width],
136137
);

apps/mobile/src/features/threads/ThreadRouteScreen.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import {
6060
useAdaptiveWorkspaceLayout,
6161
useAdaptiveWorkspacePaneRole,
6262
} from "../layout/AdaptiveWorkspaceLayout";
63+
import { useHardwareKeyboardCommand } from "../keyboard/hardwareKeyboardCommands";
6364
import { WorkspaceSidebarToolbar } from "../layout/workspace-sidebar-toolbar";
6465
import { ThreadFileNavigatorPane } from "../files/thread-file-navigator-pane";
6566
import {
@@ -377,6 +378,14 @@ function ThreadRouteContent(
377378
}
378379
action.toggleAuxiliaryPane();
379380
}, []);
381+
const handleFilesKeyboardCommand = useCallback(() => {
382+
if (fileInspector.supported && selectedThreadCwd !== null) {
383+
handleOpenFilesInspector();
384+
return true;
385+
}
386+
return false;
387+
}, [fileInspector.supported, handleOpenFilesInspector, selectedThreadCwd]);
388+
useHardwareKeyboardCommand("files", handleFilesKeyboardCommand);
380389
const handleSelectInspectorFile = useCallback(
381390
(path: string) => {
382391
if (selectedThread === null) {

apps/mobile/src/lib/layout.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ describe("deriveWorkspacePaneLayout", () => {
164164
contentPaneWidth: 1_024,
165165
supportsAuxiliaryPane: true,
166166
auxiliaryPaneVisible: true,
167-
auxiliaryPaneWidth: 287,
167+
auxiliaryPaneWidth: 260,
168168
});
169169
});
170170

@@ -185,7 +185,7 @@ describe("deriveWorkspacePaneLayout", () => {
185185
contentPaneWidth: 986,
186186
supportsAuxiliaryPane: true,
187187
auxiliaryPaneVisible: true,
188-
auxiliaryPaneWidth: 320,
188+
auxiliaryPaneWidth: 276,
189189
});
190190
});
191191

apps/mobile/src/lib/layout.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export function deriveWorkspacePaneLayout(input: {
100100
layout: input.layout,
101101
viewportWidth,
102102
preferredWidth: input.auxiliaryPanePreferredWidth,
103+
sidebarWidth: preferredPrimarySidebarWidth,
103104
});
104105
const auxiliaryPaneVisible = fileInspector.supported && input.auxiliaryPanePreferredVisible;
105106
const primarySidebarSuppressedByAuxiliary =
@@ -151,10 +152,13 @@ export function deriveFileInspectorPaneLayout(input: {
151152
readonly layout: Layout;
152153
readonly viewportWidth: number;
153154
readonly preferredWidth?: number;
155+
readonly sidebarWidth?: number;
154156
}): FileInspectorPaneLayout {
155157
const viewportWidth = Math.max(0, input.viewportWidth);
158+
const sidebarWidth = input.sidebarWidth ?? 0;
156159
const supported =
157160
input.layout.usesSplitView && viewportWidth >= FILE_INSPECTOR_MIN_VIEWPORT_WIDTH;
161+
const availableWidth = Math.max(0, viewportWidth - sidebarWidth);
158162

159163
return {
160164
supported,
@@ -163,11 +167,11 @@ export function deriveFileInspectorPaneLayout(input: {
163167
preferredWidth:
164168
input.preferredWidth ??
165169
clamp(
166-
Math.round(viewportWidth * 0.28),
170+
Math.round(availableWidth * 0.28),
167171
AUXILIARY_PANE_MIN_WIDTH,
168172
AUXILIARY_PANE_DEFAULT_MAX_WIDTH,
169173
),
170-
availableWidth: viewportWidth,
174+
availableWidth,
171175
})
172176
: null,
173177
};

0 commit comments

Comments
 (0)