Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: show proper empty user search screens [WPB-6257] 🍒 #3602

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ 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 @@ -37,16 +36,15 @@ import androidx.compose.runtime.SideEffect
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
Expand Down Expand Up @@ -82,10 +80,15 @@ fun SearchAllPeopleScreen(
onPublicResultsExpansionChanged: (Boolean) -> Unit = {},
lazyListState: LazyListState = rememberLazyListState()
) {
if (contactsSearchResult.isEmpty() && publicSearchResult.isEmpty()) {
EmptySearchQueryScreen()
} else {
SearchResult(
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,
Expand All @@ -94,7 +97,6 @@ fun SearchAllPeopleScreen(
onOpenUserProfile = onOpenUserProfile,
lazyListState = lazyListState,
isSearchActive = isSearchActive,
isLoading = isLoading,
actionType = actionType,
selectedContactResultsExpanded = selectedContactResultsExpanded,
onSelectedContactResultsExpansionChanged = onSelectedContactResultsExpansionChanged,
Expand All @@ -112,7 +114,6 @@ private fun SearchResult(
contactsSearchResult: ImmutableList<Contact>,
publicSearchResult: ImmutableList<Contact>,
contactsSelectedSearchResult: ImmutableList<Contact>,
isLoading: Boolean,
isSearchActive: Boolean,
actionType: ItemActionType,
onChecked: (Boolean, Contact) -> Unit,
Expand Down Expand Up @@ -140,8 +141,7 @@ private fun SearchResult(
searchTitle = context.getString(R.string.label_selected) + " (${contactsSelectedSearchResult.size})",
searchQuery = searchQuery,
onChecked = onChecked,
isLoading = isLoading,
contactSearchResult = contactsSelectedSearchResult.map { it to true }.toImmutableList(),
searchResult = contactsSelectedSearchResult.map { it to true }.toImmutableList(),
allItemsVisible = true, // for selected contacts we always show all items
showMoreOrLessButtonVisible = false,
onShowAllButtonClicked = searchPeopleScreenState::toggleShowAllContactsResult,
Expand All @@ -157,8 +157,7 @@ private fun SearchResult(
searchTitle = context.getString(R.string.label_contacts),
searchQuery = searchQuery,
onChecked = onChecked,
isLoading = isLoading,
contactSearchResult = contactsSearchResult.map { it to false }.toImmutableList(),
searchResult = contactsSearchResult.map { it to false }.toImmutableList(),
allItemsVisible = !isSearchActive || searchPeopleScreenState.contactsAllResultsCollapsed,
showMoreOrLessButtonVisible = isSearchActive,
onShowAllButtonClicked = searchPeopleScreenState::toggleShowAllContactsResult,
Expand All @@ -173,8 +172,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 @@ -193,78 +191,6 @@ private fun SearchResult(

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

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

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

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

@Suppress("LongParameterList")
private fun LazyListScope.internalSuccessItem(
searchTitle: String,
allItemsVisible: Boolean,
showMoreOrLessButtonVisible: Boolean,
Expand Down Expand Up @@ -330,7 +256,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 @@ -383,23 +309,6 @@ private fun LazyListScope.externalSuccessItem(
}
}

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

@Composable
private fun ShowButton(
isShownAll: Boolean,
Expand Down Expand Up @@ -445,10 +354,11 @@ fun PreviewSearchAllPeopleScreen_Loading() = WireTheme {

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_EmptyList() = WireTheme {
fun PreviewSearchAllPeopleScreen_InitialResults() = WireTheme {
val contacts = previewContactsList(count = 10, startIndex = 0, isContact = true)
SearchAllPeopleScreen(
searchQuery = "Search query",
contactsSearchResult = persistentListOf(),
searchQuery = "",
contactsSearchResult = contacts,
publicSearchResult = persistentListOf(),
contactsSelectedSearchResult = persistentListOf(),
isLoading = false,
Expand All @@ -461,11 +371,10 @@ fun PreviewSearchAllPeopleScreen_EmptyList() = WireTheme {

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllPeopleScreen_NoSearch() = WireTheme {
val contacts = previewContactsList(count = 10, startIndex = 0, isContact = true)
fun PreviewSearchAllPeopleScreen_EmptyInitialResults() = WireTheme {
SearchAllPeopleScreen(
searchQuery = "",
contactsSearchResult = contacts,
contactsSearchResult = persistentListOf(),
publicSearchResult = persistentListOf(),
contactsSelectedSearchResult = persistentListOf(),
isLoading = false,
Expand Down Expand Up @@ -514,6 +423,23 @@ fun PreviewSearchAllPeopleScreen_SearchResults_TypeCheck() = WireTheme {
)
}

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

private fun previewContact(index: Int, isContact: Boolean) = Contact(
id = index.toString(),
domain = "wire.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ import com.wire.android.ui.common.UserProfileAvatar
import com.wire.android.ui.common.dimensions
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.util.extension.folderWithElements
import com.wire.android.ui.theme.WireTheme
import com.wire.android.util.ui.PreviewMultipleThemes
import com.wire.kalium.logic.data.user.ConnectionState
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList

@Composable
fun SearchAllServicesScreen(
Expand All @@ -59,7 +65,6 @@ fun SearchAllServicesScreen(
onServiceClicked = onServiceClicked,
result = searchServicesViewModel.state.result,
lazyListState = lazyListState,
error = searchServicesViewModel.state.error,
isLoading = searchServicesViewModel.state.isLoading
)
}
Expand All @@ -69,27 +74,23 @@ private fun SearchAllServicesContent(
searchQuery: String,
result: ImmutableList<Contact>,
isLoading: Boolean,
error: Boolean,
onServiceClicked: (Contact) -> Unit,
lazyListState: LazyListState = rememberLazyListState()
) {
when {
isLoading -> CenteredCircularProgressBarIndicator()
error -> SearchFailureBox(failureMessage = R.string.label_general_error)

// TODO(user experience): what to do when user team has no services?
result.isEmpty() -> {
EmptySearchQueryScreen()
}
searchQuery.isBlank() && result.isEmpty() -> EmptySearchQueryScreen()

else -> {
SuccessServicesList(
searchQuery = searchQuery,
onServiceClicked = onServiceClicked,
services = result,
lazyListState = lazyListState
)
}
searchQuery.isNotBlank() && result.isEmpty() -> SearchFailureBox(R.string.label_no_results_found)

else -> SuccessServicesList(
searchQuery = searchQuery,
onServiceClicked = onServiceClicked,
services = result,
lazyListState = lazyListState
)
}
}

Expand Down Expand Up @@ -141,3 +142,46 @@ private fun SuccessServicesList(
}
}
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllServicesScreen_Loading() = WireTheme {
SearchAllServicesContent("", persistentListOf(), true, {})
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllServicesScreen_InitialResults() = WireTheme {
SearchAllServicesContent("", previewServiceList(count = 10).toPersistentList(), false, {})
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllServicesScreen_EmptyInitialResults() = WireTheme {
SearchAllServicesContent("", persistentListOf(), false, {})
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllServicesScreen_SearchResults() = WireTheme {
SearchAllServicesContent("Serv", previewServiceList(count = 10).toPersistentList(), false, {})
}

@PreviewMultipleThemes
@Composable
fun PreviewSearchAllServicesScreen_EmptySearchResults() = WireTheme {
SearchAllServicesContent("Serv", persistentListOf(), false, {})
}

private fun previewService(index: Int) = Contact(
id = index.toString(),
domain = "wire.com",
name = "Service nr $index",
handle = "service_$index",
connectionState = ConnectionState.NOT_CONNECTED,
membership = Membership.Service,
)

private fun previewServiceList(count: Int): List<Contact> = buildList {
repeat(count) { index -> add(previewService(index)) }
}
Loading
Loading