From b4ee3b1dd6246990ab2cbde0825b090495e68471 Mon Sep 17 00:00:00 2001 From: chelsea Date: Mon, 12 Jan 2026 20:27:58 +0000 Subject: [PATCH] Use floating toolbar on homepage --- .../android/features/home/impl/HomeState.kt | 1 - .../android/features/home/impl/HomeView.kt | 82 ++++++++++--------- .../home/impl/components/HomeTopBar.kt | 23 +----- gradle/libs.versions.toml | 2 +- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt index dbb994e23e..934dac831e 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt @@ -33,7 +33,6 @@ data class HomeState( val eventSink: (HomeEvent) -> Unit, ) { val isBackHandlerEnabled = currentHomeNavigationBarItem != HomeNavigationBarItem.Chats || roomListState.spaceFiltersState is SpaceFiltersState.Selected - val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters val showNavigationBar = homeSpacesState.canCreateSpaces || homeSpacesState.spaceRooms.isNotEmpty() } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt index eee6f49db3..a57d8c8278 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt @@ -13,6 +13,7 @@ package io.element.android.features.home.impl import androidx.activity.compose.BackHandler import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding @@ -21,19 +22,25 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.FabPosition +import androidx.compose.material3.FloatingToolbarDefaults.ScreenOffset +import androidx.compose.material3.HorizontalFloatingToolbar +import androidx.compose.material3.IconButton import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex import dev.chrisbanes.haze.hazeEffect import dev.chrisbanes.haze.hazeSource import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi @@ -59,14 +66,11 @@ import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.FloatingActionButton import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.NavigationBar -import io.element.android.libraries.designsystem.theme.components.NavigationBarIcon -import io.element.android.libraries.designsystem.theme.components.NavigationBarItem -import io.element.android.libraries.designsystem.theme.components.NavigationBarText import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.coroutines.launch @Composable @@ -198,7 +202,7 @@ private fun HomeScaffold( ) ) }, - bottomBar = { + floatingActionButton = { if (state.showNavigationBar) { val coroutineScope = rememberCoroutineScope() HomeBottomBar( @@ -222,13 +226,16 @@ private fun HomeScaffold( state.eventSink(HomeEvent.SelectHomeNavigationBarItem(item)) } }, - modifier = Modifier.hazeEffect( - state = hazeState, - style = HazeMaterials.thick(), - ) + floatingActionButton = { + when (state.currentHomeNavigationBarItem) { + HomeNavigationBarItem.Chats -> HomeFloatingActionButton(onStartChatClick, CommonStrings.action_create_a_room) + HomeNavigationBarItem.Spaces -> HomeFloatingActionButton(onCreateSpaceClick, CommonStrings.action_create_space) + } + } ) } }, + floatingActionButtonPosition = FabPosition.Center, content = { padding -> when (state.currentHomeNavigationBarItem) { HomeNavigationBarItem.Chats -> { @@ -286,50 +293,51 @@ private fun HomeScaffold( } } }, - floatingActionButton = { - if (state.displayActions) { - FloatingActionButton( - onClick = onStartChatClick, - ) { - Icon( - imageVector = CompoundIcons.Plus(), - contentDescription = stringResource(id = R.string.screen_roomlist_a11y_create_message), - ) - } - } - }, snackbarHost = { SnackbarHost(snackbarHostState) }, ) } +@Composable +private fun HomeFloatingActionButton( + onClick: () -> Unit, + contentDescription: Int, + modifier: Modifier = Modifier, +) { + FloatingActionButton(onClick = onClick, modifier = modifier) { + Icon( + imageVector = CompoundIcons.Plus(), + contentDescription = stringResource(id = contentDescription), + ) + } +} + +@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class) @Composable private fun HomeBottomBar( currentHomeNavigationBarItem: HomeNavigationBarItem, onItemClick: (HomeNavigationBarItem) -> Unit, + floatingActionButton: @Composable () -> Unit, modifier: Modifier = Modifier, ) { - NavigationBar( - containerColor = Color.Transparent, + HorizontalFloatingToolbar( + expanded = true, + floatingActionButton = floatingActionButton, modifier = modifier + .padding(bottom = ScreenOffset) + .zIndex(1f), ) { HomeNavigationBarItem.entries.forEach { item -> val isSelected = currentHomeNavigationBarItem == item - NavigationBarItem( - selected = isSelected, - onClick = { - onItemClick(item) - }, - icon = { - NavigationBarIcon( + IconButton( + onClick = { onItemClick(item) }, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon( imageVector = item.icon(isSelected), - ) - }, - label = { - NavigationBarText( - text = stringResource(item.labelRes), + contentDescription = stringResource(item.labelRes), ) } - ) + } } } } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt index 69547db58a..afba2e1b82 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt @@ -134,17 +134,13 @@ fun HomeTopBar( ) }, actions = { - when (selectedNavigationItem) { - HomeNavigationBarItem.Chats -> RoomListMenuItems( + if (selectedNavigationItem == HomeNavigationBarItem.Chats) { + RoomListMenuItems( onToggleSearch = onToggleSearch, onMenuActionClick = onMenuActionClick, canReportBug = canReportBug, spaceFiltersState = spaceFiltersState, ) - HomeNavigationBarItem.Spaces -> SpacesMenuItems( - canCreateSpaces = canCreateSpaces, - onCreateSpace = onCreateSpace - ) } }, // We want a 16dp left padding for the navigationIcon : @@ -230,21 +226,6 @@ private fun RoomListMenuItems( } } -@Composable -private fun SpacesMenuItems( - canCreateSpaces: Boolean, - onCreateSpace: () -> Unit -) { - if (canCreateSpaces) { - IconButton(onClick = onCreateSpace) { - Icon( - imageVector = CompoundIcons.Plus(), - contentDescription = stringResource(CommonStrings.action_create_space) - ) - } - } -} - @Composable private fun SpaceFilterButton( spaceFiltersState: SpaceFiltersState, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1ea2c839f7..45d8517fa8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -120,7 +120,7 @@ androidx_preference = "androidx.preference:preference:1.2.1" androidx_webkit = "androidx.webkit:webkit:1.15.0" androidx_compose_bom = { module = "androidx.compose:compose-bom", version.ref = "compose_bom" } -androidx_compose_material3 = { module = "androidx.compose.material3:material3" } +androidx_compose_material3 = { module = "androidx.compose.material3:material3", version = '1.5.0-alpha11' } androidx_compose_material3_windowsizeclass = { module = "androidx.compose.material3:material3-window-size-class" } androidx_compose_material3_adaptive = "androidx.compose.material3:material3-adaptive-android:1.0.0-alpha06" androidx_compose_ui = { module = "androidx.compose.ui:ui" }