Add space filter button to HomeTopBar and integrate SpaceFiltersView
This commit is contained in:
@@ -50,6 +50,7 @@ import io.element.android.features.home.impl.roomlist.RoomListDeclineInviteMenu
|
||||
import io.element.android.features.home.impl.roomlist.RoomListEvent
|
||||
import io.element.android.features.home.impl.roomlist.RoomListState
|
||||
import io.element.android.features.home.impl.search.RoomListSearchView
|
||||
import io.element.android.features.home.impl.spacefilters.SpaceFiltersView
|
||||
import io.element.android.features.home.impl.spaces.HomeSpacesView
|
||||
import io.element.android.libraries.androidutils.throttler.FirstThrottler
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
@@ -168,7 +169,6 @@ private fun HomeScaffold(
|
||||
topBar = {
|
||||
HomeTopBar(
|
||||
selectedNavigationItem = state.currentHomeNavigationBarItem,
|
||||
title = stringResource(state.currentHomeNavigationBarItem.labelRes),
|
||||
currentUserAndNeighbors = state.currentUserAndNeighbors,
|
||||
showAvatarIndicator = state.showAvatarIndicator,
|
||||
areSearchResultsDisplayed = roomListState.searchState.isSearchActive,
|
||||
@@ -182,6 +182,7 @@ private fun HomeScaffold(
|
||||
scrollBehavior = scrollBehavior,
|
||||
displayFilters = state.displayRoomListFilters,
|
||||
filtersState = roomListState.filtersState,
|
||||
spaceFiltersState = roomListState.spaceFiltersState,
|
||||
canCreateSpaces = state.homeSpacesState.canCreateSpaces,
|
||||
canReportBug = state.canReportBug,
|
||||
modifier = Modifier.hazeEffect(
|
||||
@@ -256,6 +257,7 @@ private fun HomeScaffold(
|
||||
.consumeWindowInsets(padding)
|
||||
.hazeSource(state = hazeState)
|
||||
)
|
||||
SpaceFiltersView(roomListState.spaceFiltersState)
|
||||
}
|
||||
HomeNavigationBarItem.Spaces -> {
|
||||
HomeSpacesView(
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.pager.VerticalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.IconButtonDefaults
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
@@ -40,10 +41,14 @@ import io.element.android.appconfig.RoomListConfig
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.home.impl.HomeNavigationBarItem
|
||||
import io.element.android.features.home.impl.R
|
||||
import io.element.android.features.home.impl.filters.RoomListFiltersState
|
||||
import io.element.android.features.home.impl.filters.RoomListFiltersView
|
||||
import io.element.android.features.home.impl.filters.aRoomListFiltersState
|
||||
import io.element.android.features.home.impl.spacefilters.SpaceFiltersEvent
|
||||
import io.element.android.features.home.impl.spacefilters.SpaceFiltersState
|
||||
import io.element.android.features.home.impl.spacefilters.aDisabledSpaceFiltersState
|
||||
import io.element.android.features.home.impl.spacefilters.aSelectedSpaceFiltersState
|
||||
import io.element.android.features.home.impl.spacefilters.anUnselectedSpaceFiltersState
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom
|
||||
import io.element.android.libraries.designsystem.components.TopAppBarScrollBehaviorLayout
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
@@ -75,7 +80,6 @@ import kotlinx.collections.immutable.toImmutableList
|
||||
@Composable
|
||||
fun HomeTopBar(
|
||||
selectedNavigationItem: HomeNavigationBarItem,
|
||||
title: String,
|
||||
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
||||
showAvatarIndicator: Boolean,
|
||||
areSearchResultsDisplayed: Boolean,
|
||||
@@ -89,6 +93,7 @@ fun HomeTopBar(
|
||||
canReportBug: Boolean,
|
||||
displayFilters: Boolean,
|
||||
filtersState: RoomListFiltersState,
|
||||
spaceFiltersState: SpaceFiltersState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier) {
|
||||
@@ -103,12 +108,21 @@ fun HomeTopBar(
|
||||
scrolledContainerColor = Color.Transparent,
|
||||
),
|
||||
title = {
|
||||
val displayTitle = when (selectedNavigationItem) {
|
||||
HomeNavigationBarItem.Chats -> {
|
||||
when (spaceFiltersState) {
|
||||
is SpaceFiltersState.Selected -> spaceFiltersState.selectedFilter.spaceRoom.displayName
|
||||
else -> stringResource(selectedNavigationItem.labelRes)
|
||||
}
|
||||
}
|
||||
HomeNavigationBarItem.Spaces -> stringResource(selectedNavigationItem.labelRes)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.semantics {
|
||||
heading()
|
||||
},
|
||||
style = ElementTheme.typography.aliasScreenTitle,
|
||||
text = title,
|
||||
text = displayTitle,
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
@@ -124,7 +138,8 @@ fun HomeTopBar(
|
||||
HomeNavigationBarItem.Chats -> RoomListMenuItems(
|
||||
onToggleSearch = onToggleSearch,
|
||||
onMenuActionClick = onMenuActionClick,
|
||||
canReportBug = canReportBug
|
||||
canReportBug = canReportBug,
|
||||
spaceFiltersState = spaceFiltersState,
|
||||
)
|
||||
HomeNavigationBarItem.Spaces -> SpacesMenuItems(
|
||||
canCreateSpaces = canCreateSpaces,
|
||||
@@ -154,6 +169,7 @@ private fun RoomListMenuItems(
|
||||
onToggleSearch: () -> Unit,
|
||||
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
||||
canReportBug: Boolean,
|
||||
spaceFiltersState: SpaceFiltersState,
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onToggleSearch,
|
||||
@@ -163,6 +179,7 @@ private fun RoomListMenuItems(
|
||||
contentDescription = stringResource(CommonStrings.action_search),
|
||||
)
|
||||
}
|
||||
SpaceFilterButton(spaceFiltersState = spaceFiltersState)
|
||||
if (RoomListConfig.HAS_DROP_DOWN_MENU) {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
IconButton(
|
||||
@@ -228,6 +245,47 @@ private fun SpacesMenuItems(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SpaceFilterButton(
|
||||
spaceFiltersState: SpaceFiltersState,
|
||||
) {
|
||||
when (spaceFiltersState) {
|
||||
SpaceFiltersState.Disabled -> Unit
|
||||
is SpaceFiltersState.Unselected -> {
|
||||
IconButton(
|
||||
onClick = { spaceFiltersState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Filter(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
is SpaceFiltersState.Selecting -> {
|
||||
IconButton(onClick = {}) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Filter(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
is SpaceFiltersState.Selected -> {
|
||||
IconButton(
|
||||
colors = IconButtonDefaults.iconButtonColors(
|
||||
containerColor = ElementTheme.colors.bgAccentRest,
|
||||
contentColor = ElementTheme.colors.iconOnSolidPrimary,
|
||||
),
|
||||
onClick = { spaceFiltersState.eventSink(SpaceFiltersEvent.Selected.ClearSelection) },
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Filter(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NavigationIcon(
|
||||
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
||||
@@ -309,7 +367,6 @@ private fun AccountIcon(
|
||||
internal fun HomeTopBarPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||
showAvatarIndicator = false,
|
||||
areSearchResultsDisplayed = false,
|
||||
@@ -322,6 +379,7 @@ internal fun HomeTopBarPreview() = ElementPreview {
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
spaceFiltersState = anUnselectedSpaceFiltersState(),
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
@@ -332,7 +390,6 @@ internal fun HomeTopBarPreview() = ElementPreview {
|
||||
internal fun HomeTopBarSpacesPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
selectedNavigationItem = HomeNavigationBarItem.Spaces,
|
||||
title = stringResource(R.string.screen_home_tab_spaces),
|
||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||
showAvatarIndicator = false,
|
||||
areSearchResultsDisplayed = false,
|
||||
@@ -345,6 +402,7 @@ internal fun HomeTopBarSpacesPreview() = ElementPreview {
|
||||
canReportBug = true,
|
||||
displayFilters = false,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
spaceFiltersState = anUnselectedSpaceFiltersState(),
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
@@ -355,7 +413,6 @@ internal fun HomeTopBarSpacesPreview() = ElementPreview {
|
||||
internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||
showAvatarIndicator = true,
|
||||
areSearchResultsDisplayed = false,
|
||||
@@ -368,6 +425,7 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
spaceFiltersState = anUnselectedSpaceFiltersState(),
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
@@ -378,7 +436,6 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||
internal fun HomeTopBarMultiAccountPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||
currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(),
|
||||
showAvatarIndicator = false,
|
||||
areSearchResultsDisplayed = false,
|
||||
@@ -391,6 +448,30 @@ internal fun HomeTopBarMultiAccountPreview() = ElementPreview {
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
spaceFiltersState = anUnselectedSpaceFiltersState(),
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun HomeTopSpaceFiltersSelectedPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||
showAvatarIndicator = false,
|
||||
areSearchResultsDisplayed = false,
|
||||
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
|
||||
onOpenSettings = {},
|
||||
onAccountSwitch = {},
|
||||
onToggleSearch = {},
|
||||
onCreateSpace = {},
|
||||
canCreateSpaces = true,
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
spaceFiltersState = aSelectedSpaceFiltersState(),
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
@@ -24,7 +26,7 @@ import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
@Inject
|
||||
@ContributesBinding(SessionScope::class)
|
||||
class SpaceFiltersPresenter(
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
private val matrixClient: MatrixClient,
|
||||
|
||||
@@ -18,10 +18,8 @@ import kotlinx.collections.immutable.persistentListOf
|
||||
class SpaceFiltersStateProvider : PreviewParameterProvider<SpaceFiltersState> {
|
||||
override val values: Sequence<SpaceFiltersState>
|
||||
get() = sequenceOf(
|
||||
aDisabledSpaceFiltersState(),
|
||||
anUnselectedSpaceFiltersState(),
|
||||
aSelectingSpaceFiltersState(),
|
||||
aSelectedSpaceFiltersState(),
|
||||
aSelectingSpaceFiltersState(searchQuery = "Pr")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,11 +52,11 @@ fun aSelectingSpaceFiltersState(
|
||||
roomId = RoomId("!gaming:example.com"),
|
||||
),
|
||||
),
|
||||
searchQuery: TextFieldState = TextFieldState(),
|
||||
searchQuery: String = "",
|
||||
eventSink: (SpaceFiltersEvent.Selecting) -> Unit = {},
|
||||
) = SpaceFiltersState.Selecting(
|
||||
availableFilters = persistentListOf(*availableFilters.toTypedArray()),
|
||||
searchQuery = searchQuery,
|
||||
searchQuery = TextFieldState(searchQuery),
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
@@ -32,9 +33,11 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.home.impl.R
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarType
|
||||
@@ -97,16 +100,20 @@ private fun SpaceFiltersBottomSheetContent(
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp, horizontal = 16.dp)
|
||||
.fillMaxHeight(0.9f)
|
||||
.padding(vertical = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Your spaces",
|
||||
text = stringResource(R.string.screen_roomlist_your_spaces),
|
||||
style = ElementTheme.typography.fontHeadingSmMedium,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
SearchField(
|
||||
state = searchQuery,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
|
||||
placeholder = stringResource(CommonStrings.action_search),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
@@ -149,12 +156,16 @@ private fun SpaceFilterItem(
|
||||
text = spaceRoom.displayName,
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (supportingText != null) {
|
||||
Text(
|
||||
text = supportingText,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user