From 6793cbd25b7f1fa0c3e4750423bbbf4039e2a279 Mon Sep 17 00:00:00 2001 From: Tom Brow Date: Thu, 5 Nov 2026 11:49:48 -0800 Subject: [PATCH] fix(mobile): focus the search field when search opens (#9120) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Opening search from Home now focuses the search field, so the keyboard comes up right away and you can start typing without tapping the field first. This applies when `SearchPage` opens as its own route; the embedded variant is unchanged. Closing with X and reopening works as before (the previous query is kept and the field is focused again). ### Validation - Extended the existing open-and-close journey in `search_page_test.dart`: it now opens search without tapping the field and asserts the field has focus and the keyboard is shown. The step fails with the production change reverted. - Full mobile test suite and checks passed in the pre-push hook. - Automated run on an iOS 27 simulator (iPhone 17 Pro) signed in to a real community: opened search from Home (keyboard up, caret in the field), typed a query and got channel and message results, closed with X, reopened (keyboard up again). The recording contains internal community content, so it was shared internally rather than here. - Human testing waived under the author's standing exception; the automated simulator run above covers it. buzz-review-completed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Tom Brow Co-authored-by: Tom Brow Co-authored-by: Claude Opus 5.5 --- mobile/lib/features/search/search_page.dart | 10 ++++++++++ mobile/test/features/search/search_page_test.dart | 7 ++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/mobile/lib/features/search/search_page.dart b/mobile/lib/features/search/search_page.dart index 48607d97f3..7bfa577247 100644 --- a/mobile/lib/features/search/search_page.dart +++ b/mobile/lib/features/search/search_page.dart @@ -101,6 +101,16 @@ class SearchPage extends HookConsumerWidget { void activateSearch() => focusNode.requestFocus(); + // Opening search as its own route means the user wants to type, so raise + // the keyboard right away instead of waiting for a tap on the field. + useEffect(() { + if (embedded) return null; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (context.mounted) focusNode.requestFocus(); + }); + return null; + }, const []); + useEffect(() { final reselection = tabReselection; if (reselection == null) return null; diff --git a/mobile/test/features/search/search_page_test.dart b/mobile/test/features/search/search_page_test.dart index 6aac4a4eb9..4fa4b6c964 100644 --- a/mobile/test/features/search/search_page_test.dart +++ b/mobile/test/features/search/search_page_test.dart @@ -252,7 +252,7 @@ void main() { debugDefaultTargetPlatformOverride = null; }); - testWidgets('X dismisses search while the keyboard is focused', ( + testWidgets('opening search focuses the field; X dismisses it', ( tester, ) async { await tester.pumpWidget( @@ -278,8 +278,9 @@ void main() { ); await tester.tap(find.text('Open search')); await tester.pumpAndSettle(); - await tester.tap(find.byType(TextField)); - await tester.pumpAndSettle(); + final field = tester.widget(find.byType(TextField)); + expect(field.focusNode!.hasFocus, isTrue); + expect(tester.testTextInput.isVisible, isTrue); await tester.enterText(find.byType(TextField), 'draft'); await tester.tap(find.byTooltip('Close search')); await tester.pumpAndSettle();