Skip to content

fix(contacts): allow spaces in the contacts search query - #1126

Merged
torlando-tech merged 1 commit into
mainfrom
fix/contacts-search-spaces
Sep 4, 2026
Merged

fix(contacts): allow spaces in the contacts search query#1126
torlando-tech merged 1 commit into
mainfrom
fix/contacts-search-spaces

Conversation

@torlando-tech

Copy link
Copy Markdown
Owner

Bug

The Contacts search bar does not let you type a space (user report). Affects both the My Contacts and Network tabs, which share the one search field.

Root cause

The search field is a controlled \textfield whose onValueChange round-trips every keystroke through InputValidator.sanitizeText, which trims. The instant the user presses the space key, the space is the trailing character, so it is stripped before the field can render it and the query never contains a space. Internal spaces are unreachable for the same reason (each is trailing at the moment it is typed).

Fix

  • Add InputValidator.sanitizeSearchQuery: strips control characters, normalizes whitespace runs, enforces length, but does not trim, so a live field does not fight the user while composing.
  • ContactsScreen search field uses sanitizeSearchQuery.
  • ContactsViewModel trims the query at match time (mirrors AnnounceStreamViewModel, which already trims before the SQL query), so trailing spaces are harmless for filtering and an all-space query is treated as empty.
  • validateSearchQuery routes through sanitizeSearchQuery; sanitizeText keeps its generic trimming contract for non-search callers.

Tests

  • Compose regression: type 'Alice', press space, then 'Alice Smith' and assert the ViewModel receives the space (fails on the old code, passes now).
  • Validator unit tests for sanitizeSearchQuery (trailing/leading space, internal normalization, control chars, length) plus a guard that sanitizeText still trims.
  • ViewModel tests for match-time trimming and all-space-query-as-empty.

Verification

  • Full app unit suites on both backends: 6130 + 6130 tests, 0 failures
  • Data suite: 390 tests, 0 failures
  • detekt + ktlint clean

The contacts search bar is a controlled text field whose onValueChange
round-trips every keystroke through InputValidator.sanitizeText, which
trims. The moment the user pressed the space key, the space was the
trailing character, so it was stripped before the field could render it
and the query never contained a space (user report: the search bar
does not let you type a space). The same flaw applied to both the
My Contacts and Network tabs, which share this field.

- Add InputValidator.sanitizeSearchQuery: strips control characters,
  normalizes whitespace runs, enforces length, but does NOT trim, so a
  live field does not fight the user while composing.
- ContactsScreen search field uses sanitizeSearchQuery.
- ContactsViewModel trims the query at match time (mirrors
  AnnounceStreamViewModel, which already trims before the SQL query),
  so trailing spaces are harmless for filtering and an all-space query
  is treated as empty.
- validateSearchQuery routes through sanitizeSearchQuery; sanitizeText
  keeps its generic trimming contract for non-search callers.

Regression tests: compose test typing 'Alice' then a space then
'Alice Smith' asserts the ViewModel receives the space (fails on the
old code), validator unit tests for the new function, and ViewModel
tests for match-time trimming.

Verified: full app unit suites on both backends (12260 tests) and data
suite (390 tests) green; detekt/ktlint clean.
@greptile-apps

greptile-apps Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the shared Contacts search field so users can compose multi-word queries without trailing spaces being removed after each keystroke.

  • Adds a search-specific sanitizer that preserves leading and trailing whitespace while retaining control-character removal, whitespace normalization, and length enforcement.
  • Trims queries at match time in ContactsViewModel; the Network search already trims before its repository query.
  • Adds UI, validator, and ViewModel regression coverage for spaces, normalization, sanitization, length limits, and whitespace-only searches.

Confidence Score: 5/5

The PR appears safe to merge, with both shared search paths preserving live input while trimming before matching.

No actionable failures remain: Contacts trims before in-memory matching, Network already trims before repository filtering, and the regression behavior is covered across the UI, sanitizer, and ViewModel layers.

Important Files Changed

Filename Overview
app/src/main/java/network/columba/app/ui/screens/ContactsScreen.kt Routes live search input through the whitespace-preserving sanitizer for both Contacts and Network tabs.
app/src/main/java/network/columba/app/util/validation/InputValidator.kt Adds a search-specific sanitizer and updates search validation without changing the generic text sanitizer’s trimming contract.
app/src/main/java/network/columba/app/viewmodel/ContactsViewModel.kt Trims the live query before contact matching and treats whitespace-only input as an empty search.
app/src/test/java/network/columba/app/ui/screens/ContactsScreenTest.kt Adds regression coverage requiring spaced search values to reach the Contacts ViewModel.
app/src/test/java/network/columba/app/util/validation/InputValidatorTest.kt Covers preserved edge spaces, whitespace normalization, control-character removal, truncation, and the unchanged generic sanitizer contract.
app/src/test/java/network/columba/app/viewmodel/ContactsViewModelTest.kt Covers match-time trimming and whitespace-only queries returning all contacts.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[User edits shared search field] --> B[sanitizeSearchQuery]
    B --> C{Selected tab}
    C -->|My Contacts| D[ContactsViewModel]
    C -->|Network| E[AnnounceStreamViewModel]
    D --> F[Trim at in-memory match time]
    E --> G[Trim before repository query]
    F --> H[Filtered contacts]
    G --> I[Filtered announces]
Loading

Reviews (1): Last reviewed commit: "fix(contacts): allow spaces in the conta..." | Re-trigger Greptile

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@torlando-tech
torlando-tech merged commit fc086dc into main Sep 4, 2026
13 checks passed
@torlando-tech
torlando-tech deleted the fix/contacts-search-spaces branch September 4, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant