Skip to content

Commit

Permalink
fix: show proper empty user search screens [WPB-6257] 🍒 (v4.7) (#3604)
Browse files Browse the repository at this point in the history
  • Loading branch information
saleniuk authored Nov 14, 2024
1 parent 1febd6b commit 596f3f3
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

@file:Suppress("TooManyFunctions")

package com.wire.android.ui.home.conversations.search

import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -36,31 +35,34 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.wire.android.R
import com.wire.android.model.Clickable
import com.wire.android.model.ItemActionType
import com.wire.android.ui.common.button.WireSecondaryButton
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.progress.WireCircularProgressIndicator
import com.wire.android.ui.common.progress.CenteredCircularProgressBarIndicator
import com.wire.android.ui.home.conversations.search.widget.SearchFailureBox
import com.wire.android.ui.home.conversationslist.model.Membership
import com.wire.android.ui.home.newconversation.model.Contact
import com.wire.android.ui.theme.WireTheme
import com.wire.android.util.extension.folderWithElements
import com.wire.android.util.ui.PreviewMultipleThemes
import com.wire.kalium.logic.data.user.ConnectionState
import com.wire.kalium.logic.data.user.UserId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.collections.immutable.toPersistentSet

private const val DEFAULT_SEARCH_RESULT_ITEM_SIZE = 4

@Composable
fun SearchAllPeopleScreen(
searchQuery: String,
noneSearchSucceed: Boolean,
contactsSearchResult: ImmutableList<Contact>,
publicSearchResult: ImmutableList<Contact>,
contactsAddedToGroup: ImmutableSet<Contact>,
Expand All @@ -71,27 +73,25 @@ fun SearchAllPeopleScreen(
onOpenUserProfile: (Contact) -> Unit,
lazyListState: LazyListState = rememberLazyListState()
) {
if (contactsSearchResult.isEmpty() && publicSearchResult.isEmpty()) {
EmptySearchQueryScreen()
} else {
if (noneSearchSucceed) {
SearchFailureBox(R.string.label_no_results_found)
} else {
Column {
SearchResult(
searchQuery = searchQuery,
publicSearchResult = publicSearchResult,
contactsSearchResult = contactsSearchResult,
contactsAddedToGroup = contactsAddedToGroup,
onChecked = onChecked,
onOpenUserProfile = onOpenUserProfile,
lazyListState = lazyListState,
isSearchActive = isSearchActive,
isLoading = isLoading,
actionType = actionType,
)
}
}
val emptyResults = contactsSearchResult.isEmpty() && publicSearchResult.isEmpty()
when {
isLoading -> CenteredCircularProgressBarIndicator()

searchQuery.isBlank() && emptyResults -> EmptySearchQueryScreen()

searchQuery.isNotBlank() && emptyResults -> SearchFailureBox(R.string.label_no_results_found)

else -> SearchResult(
searchQuery = searchQuery,
publicSearchResult = publicSearchResult,
contactsSearchResult = contactsSearchResult,
contactsAddedToGroup = contactsAddedToGroup,
onChecked = onChecked,
onOpenUserProfile = onOpenUserProfile,
lazyListState = lazyListState,
isSearchActive = isSearchActive,
actionType = actionType,
)
}
}

Expand All @@ -100,7 +100,6 @@ private fun SearchResult(
searchQuery: String,
contactsSearchResult: ImmutableList<Contact>,
publicSearchResult: ImmutableList<Contact>,
isLoading: Boolean,
isSearchActive: Boolean,
actionType: ItemActionType,
contactsAddedToGroup: ImmutableSet<Contact>,
Expand All @@ -124,8 +123,7 @@ private fun SearchResult(
searchQuery = searchQuery,
contactsAddedToGroup = contactsAddedToGroup,
onChecked = onChecked,
isLoading = isLoading,
contactSearchResult = contactsSearchResult,
searchResult = contactsSearchResult,
allItemsVisible = !isSearchActive || searchPeopleScreenState.contactsAllResultsCollapsed,
showMoreOrLessButtonVisible = isSearchActive,
onShowAllButtonClicked = searchPeopleScreenState::toggleShowAllContactsResult,
Expand All @@ -138,8 +136,7 @@ private fun SearchResult(
externalSearchResults(
searchTitle = context.getString(R.string.label_public_wire),
searchQuery = searchQuery,
contactSearchResult = publicSearchResult,
isLoading = isLoading,
searchResult = publicSearchResult,
allItemsVisible = searchPeopleScreenState.publicResultsCollapsed,
showMoreOrLessButtonVisible = isSearchActive,
onShowAllButtonClicked = searchPeopleScreenState::toggleShowAllPublicResult,
Expand All @@ -152,72 +149,6 @@ private fun SearchResult(

@Suppress("LongParameterList")
private fun LazyListScope.internalSearchResults(
searchTitle: String,
searchQuery: String,
contactsAddedToGroup: ImmutableSet<Contact>,
onChecked: (Boolean, Contact) -> Unit,
actionType: ItemActionType,
isLoading: Boolean,
contactSearchResult: ImmutableList<Contact>,
allItemsVisible: Boolean,
showMoreOrLessButtonVisible: Boolean,
onShowAllButtonClicked: () -> Unit,
onOpenUserProfile: (Contact) -> Unit
) {
when {
isLoading -> {
inProgressItem()
}

else -> {
internalSuccessItem(
searchTitle = searchTitle,
allItemsVisible = allItemsVisible,
showMoreOrLessButtonVisible = showMoreOrLessButtonVisible,
contactsAddedToGroup = contactsAddedToGroup,
onChecked = onChecked,
searchResult = contactSearchResult,
searchQuery = searchQuery,
onShowAllButtonClicked = onShowAllButtonClicked,
onOpenUserProfile = onOpenUserProfile,
actionType = actionType,
)
}
}
}

@Suppress("LongParameterList")
private fun LazyListScope.externalSearchResults(
searchTitle: String,
searchQuery: String,
contactSearchResult: ImmutableList<Contact>,
isLoading: Boolean,
allItemsVisible: Boolean,
showMoreOrLessButtonVisible: Boolean,
onShowAllButtonClicked: () -> Unit,
onOpenUserProfile: (Contact) -> Unit,
) {
when {
isLoading -> {
inProgressItem()
}

else -> {
externalSuccessItem(
searchTitle = searchTitle,
allItemsVisible = allItemsVisible,
showMoreOrLessButtonVisible = showMoreOrLessButtonVisible,
searchResult = contactSearchResult,
searchQuery = searchQuery,
onShowAllButtonClicked = onShowAllButtonClicked,
onOpenUserProfile = onOpenUserProfile,
)
}
}
}

@Suppress("LongParameterList")
private fun LazyListScope.internalSuccessItem(
searchTitle: String,
allItemsVisible: Boolean,
showMoreOrLessButtonVisible: Boolean,
Expand Down Expand Up @@ -274,7 +205,7 @@ private fun LazyListScope.internalSuccessItem(
}

@Suppress("LongParameterList")
private fun LazyListScope.externalSuccessItem(
private fun LazyListScope.externalSearchResults(
searchTitle: String,
allItemsVisible: Boolean,
showMoreOrLessButtonVisible: Boolean,
Expand Down Expand Up @@ -323,30 +254,6 @@ private fun LazyListScope.externalSuccessItem(
}
}

fun LazyListScope.inProgressItem() {
item {
Box(
Modifier
.fillMaxWidth()
.height(224.dp)
) {
WireCircularProgressIndicator(
progressColor = Color.Black,
modifier = Modifier.align(
Alignment.Center
)
)
}
}
}

fun LazyListScope.failureItem(@StringRes failureMessage: Int) {
item {
SearchFailureBox(failureMessage)
}
}

@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun ShowButton(
isShownAll: Boolean,
Expand All @@ -373,3 +280,116 @@ fun PreviewShowButton() {
ShowButton(isShownAll = false, onShowButtonClicked = {})
}
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_Loading() = WireTheme {
SearchAllPeopleScreen(
searchQuery = "",
contactsSearchResult = persistentListOf(),
publicSearchResult = persistentListOf(),
contactsAddedToGroup = persistentSetOf(),
isLoading = true,
isSearchActive = false,
actionType = ItemActionType.CHECK,
onChecked = { _, _ -> },
onOpenUserProfile = {}
)
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_InitialResults() = WireTheme {
val contacts = previewContactsList(count = 10, startIndex = 0, isContact = true).toPersistentList()
SearchAllPeopleScreen(
searchQuery = "",
contactsSearchResult = contacts,
publicSearchResult = persistentListOf(),
contactsAddedToGroup = persistentSetOf(),
isLoading = false,
isSearchActive = false,
actionType = ItemActionType.CHECK,
onChecked = { _, _ -> },
onOpenUserProfile = {}
)
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_EmptyInitialResults() = WireTheme {
SearchAllPeopleScreen(
searchQuery = "",
contactsSearchResult = persistentListOf(),
publicSearchResult = persistentListOf(),
contactsAddedToGroup = persistentSetOf(),
isLoading = false,
isSearchActive = false,
actionType = ItemActionType.CHECK,
onChecked = { _, _ -> },
onOpenUserProfile = {}
)
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_SearchResults_TypeClick() = WireTheme {
val contacts = previewContactsList(count = 10, startIndex = 0, isContact = true).toPersistentList()
val public = previewContactsList(count = 10, startIndex = 10, isContact = false).toPersistentList()
SearchAllPeopleScreen(
searchQuery = "Con",
contactsSearchResult = contacts,
publicSearchResult = public,
contactsAddedToGroup = persistentSetOf(),
isLoading = false,
isSearchActive = true,
actionType = ItemActionType.CLICK,
onChecked = { _, _ -> },
onOpenUserProfile = {}
)
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_SearchResults_TypeCheck() = WireTheme {
val contacts = previewContactsList(count = 10, startIndex = 0, isContact = true).toPersistentList()
val public = previewContactsList(count = 10, startIndex = 10, isContact = false).toPersistentList()
val selectedContacts = contacts.filterIndexed { index, _ -> index % 3 == 0 }.toPersistentSet()
SearchAllPeopleScreen(
searchQuery = "Con",
contactsSearchResult = contacts,
publicSearchResult = public,
contactsAddedToGroup = selectedContacts,
isLoading = false,
isSearchActive = true,
actionType = ItemActionType.CHECK,
onChecked = { _, _ -> },
onOpenUserProfile = {}
)
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_EmptySearchResults() = WireTheme {
SearchAllPeopleScreen(
searchQuery = "Con",
contactsSearchResult = persistentListOf(),
publicSearchResult = persistentListOf(),
contactsAddedToGroup = persistentSetOf(),
isLoading = false,
isSearchActive = true,
actionType = ItemActionType.CLICK,
onChecked = { _, _ -> },
onOpenUserProfile = {}
)
}

private fun previewContact(index: Int, isContact: Boolean) = Contact(
id = index.toString(),
domain = "wire.com",
name = "Contact nr $index",
connectionState = if (isContact) ConnectionState.ACCEPTED else ConnectionState.NOT_CONNECTED,
membership = Membership.Standard,
)

private fun previewContactsList(count: Int, startIndex: Int = 0, isContact: Boolean): List<Contact> =
buildList { repeat(count) { index -> add(previewContact(startIndex + index, isContact)) } }
Loading

0 comments on commit 596f3f3

Please sign in to comment.