Hide the home navigation bar if the user is not a member of any Space.

https://github.com/element-hq/element-meta/issues/2906: `The tab bar with the option to view joined spaces is only shown when the user has at least one space that they have joined (because otherwise they have no clue what to do in here).`
This commit is contained in:
Benoit Marty
2025-09-08 15:17:51 +02:00
parent 943bbee131
commit 0aa33a3cdc
5 changed files with 46 additions and 5 deletions

View File

@@ -74,6 +74,12 @@ class HomePresenter(
}
}
LaunchedEffect(homeSpacesState.spaceRooms.isEmpty()) {
// If the last space is left, ensure that the Chat view is rendered.
if (homeSpacesState.spaceRooms.isEmpty()) {
currentHomeNavigationBarItemOrdinal = HomeNavigationBarItem.Chats.ordinal
}
}
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
return HomeState(
matrixUser = matrixUser.value,

View File

@@ -29,4 +29,5 @@ data class HomeState(
val eventSink: (HomeEvents) -> Unit,
) {
val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats
val showNavigationBar = isSpaceFeatureEnabled && homeSpacesState.spaceRooms.isNotEmpty()
}

View File

@@ -36,6 +36,8 @@ open class HomeStateProvider : PreviewParameterProvider<HomeState> {
summaries = generateRoomListRoomSummaryList(),
)
),
// For the bottom nav bar to be visible in the preview, the user must be member of at least one space
homeSpacesState = aHomeSpacesState(),
),
aHomeState(
isSpaceFeatureEnabled = true,

View File

@@ -194,7 +194,7 @@ private fun HomeScaffold(
)
},
bottomBar = {
if (state.isSpaceFeatureEnabled) {
if (state.showNavigationBar) {
NavigationBar(
containerColor = Color.Transparent,
modifier = Modifier

View File

@@ -12,9 +12,11 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.home.impl.roomlist.aRoomListState
import io.element.android.features.home.impl.spaces.HomeSpacesState
import io.element.android.features.home.impl.spaces.aHomeSpacesState
import io.element.android.features.logout.api.direct.aDirectLogoutState
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
@@ -30,10 +32,10 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_NAME
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.tests.testutils.MutablePresenter
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@@ -65,6 +67,7 @@ class HomePresenterTest {
assertThat(withUserState.matrixUser.avatarUrl).isEqualTo(AN_AVATAR_URL)
assertThat(withUserState.showAvatarIndicator).isFalse()
assertThat(withUserState.isSpaceFeatureEnabled).isFalse()
assertThat(withUserState.showNavigationBar).isFalse()
}
}
@@ -145,13 +148,42 @@ class HomePresenterTest {
}
}
private fun TestScope.createHomePresenter(
@Test
fun `present - NavigationBar is hidden when the last space is left`() = runTest {
val homeSpacesPresenter = MutablePresenter(aHomeSpacesState())
val presenter = createHomePresenter(
featureFlagService = FakeFeatureFlagService(
initialState = mapOf(FeatureFlags.Space.key to true),
),
homeSpacesPresenter = homeSpacesPresenter,
)
presenter.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats)
assertThat(initialState.showNavigationBar).isTrue()
// User navigate to Spaces
initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces))
val spaceState = awaitItem()
assertThat(spaceState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Spaces)
// The last space is left
homeSpacesPresenter.updateState(aHomeSpacesState(spaceRooms = emptyList()))
skipItems(1)
val finalState = awaitItem()
// We are back to Chats
assertThat(finalState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats)
assertThat(finalState.showNavigationBar).isFalse()
}
}
private fun createHomePresenter(
client: MatrixClient = FakeMatrixClient(),
syncService: SyncService = FakeSyncService(),
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) },
indicatorService: IndicatorService = FakeIndicatorService(),
featureFlagService: FeatureFlagService = FakeFeatureFlagService()
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
homeSpacesPresenter: Presenter<HomeSpacesState> = Presenter { aHomeSpacesState() },
) = HomePresenter(
client = client,
syncService = syncService,
@@ -159,7 +191,7 @@ class HomePresenterTest {
indicatorService = indicatorService,
logoutPresenter = { aDirectLogoutState() },
roomListPresenter = { aRoomListState() },
homeSpacesPresenter = { aHomeSpacesState() },
homeSpacesPresenter = homeSpacesPresenter,
rageshakeFeatureAvailability = rageshakeFeatureAvailability,
featureFlagService = featureFlagService,
)