Skip to content

feat: Display up to 5 matching contacts during search#2863

Open
elouanbtx wants to merge 21 commits intomainfrom
contact-search
Open

feat: Display up to 5 matching contacts during search#2863
elouanbtx wants to merge 21 commits intomainfrom
contact-search

Conversation

@elouanbtx
Copy link
Copy Markdown

Expected behavior:
While the user has not pressed Enter or selected a filter, display a maximum of 5 contacts matching the search query.
When a contact is clicked, the search input is automatically populated with that contact's email address (<contact.email>).

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 14, 2026

PR Reviewer Guide 🔍

(Review updated until commit 239353b)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ No major issues detected

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 5fabd6a

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 3509caa

Comment thread app/src/main/java/com/infomaniak/mail/ui/main/search/SearchFragment.kt Outdated
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 01d14c1

Comment thread app/src/main/java/com/infomaniak/mail/ui/main/search/SearchFragment.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt Outdated
@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

Comment thread app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadItem.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/search/SearchFragment.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/AvatarNameEmailView.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/search/SearchViewModel.kt Outdated
Comment thread app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt Outdated
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 1e00265

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

Comment thread app/src/main/java/com/infomaniak/mail/ui/main/search/SearchFragment.kt Outdated
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit ef31a79

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

1 similar comment
@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 715fdce

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 239353b

@github-actions
Copy link
Copy Markdown

Failed to generate code suggestions for PR

@sonarqubecloud
Copy link
Copy Markdown

Comment on lines +46 to +57
fun searchMergedContacts(searchQuery: String, searchQueryClean: String, limit: Int = 5): List<MergedContact> {
val queryStr = if (searchQuery != searchQueryClean) {
"(name CONTAINS[c] $0 OR email CONTAINS[c] $0) OR (name CONTAINS[c] $1 OR email CONTAINS[c] $1)"
} else {
"name CONTAINS[c] $0 OR email CONTAINS[c] $0"
}
return userInfoRealm.query<MergedContact>(queryStr, searchQuery, searchQueryClean)
.sort(MergedContact::name.name)
.sort(MergedContact::comesFromApi.name, Sort.DESCENDING)
.limit(limit)
.find()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should divide this in two function, a private "-query" one, and a public one that call the query, like this others

You should also use findSuspend instead of find

Comment on lines +174 to +176
if (!isOnlyRightShown()) {
searchViewModel.clearSearchState()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!isOnlyRightShown()) {
searchViewModel.clearSearchState()
}
if (!isOnlyRightShown()) searchViewModel.clearSearchState()

Comment on lines +214 to +215
binding.searchBar.searchTextInput.setText(emailWithQuotes)
binding.searchBar.searchTextInput.setSelection(emailWithQuotes.length)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use an apply here to avoid repeating the searchInput stuff

Comment on lines +117 to +120
val allSearchResults = combine(
contactsResults,
threadsSearchResults,
) { contacts, threads ->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
val allSearchResults = combine(
contactsResults,
threadsSearchResults,
) { contacts, threads ->
val allSearchResults = combine(contactsResults, threadsSearchResults ) { contacts, threads ->

var currentSearchQuery: String = ""
private set

val uiState = MutableLiveData<SearchUiState>(SearchUiState.IDLE)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable isn't read, so it's useless

Comment on lines +349 to +350
val contactsList = mergedContactController.searchMergedContacts(query, queryClean)
contactsList
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Th evariable here is not very useful


computeSearchFilters(folder, filters, query)?.let { newFilters ->
fetchThreads(folder, newFilters, query, shouldGetNextPage)
fetchThreads(folder, newFilters, query, shouldGetNextPage, contacts.isNotEmpty())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the argument name for all boolean that aren't already named the same

newFilters: Set<ThreadFilter>,
query: String,
shouldGetNextPage: Boolean,
hasContacts: Boolean = false,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This default value is useless as the function is only use once
Furthermore, I think we want to enforce passing an argument here to avoid forgetting that case

threadController.saveSearchThreads(searchThreads)
}

enum class SearchUiState {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
enum class SearchUiState {
private enum class SearchUiState {

}
}

fun removeBackground(){
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fun removeBackground(){
fun removeBackground() {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants