Remove FeatureFlags.Space entirely

This commit is contained in:
ganfra 2025-12-22 17:46:45 +01:00
parent 7b3f082eb3
commit 9afdbdc4ab
6 changed files with 7 additions and 63 deletions

View file

@ -28,8 +28,6 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.indicator.api.IndicatorService
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncService
@ -48,7 +46,6 @@ class HomePresenter(
private val homeSpacesPresenter: Presenter<HomeSpacesState>, private val homeSpacesPresenter: Presenter<HomeSpacesState>,
private val logoutPresenter: Presenter<DirectLogoutState>, private val logoutPresenter: Presenter<DirectLogoutState>,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability, private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
private val featureFlagService: FeatureFlagService,
private val sessionStore: SessionStore, private val sessionStore: SessionStore,
private val announcementService: AnnouncementService, private val announcementService: AnnouncementService,
) : Presenter<HomeState> { ) : Presenter<HomeState> {
@ -69,9 +66,6 @@ class HomePresenter(
val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false) val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false)
val roomListState = roomListPresenter.present() val roomListState = roomListPresenter.present()
val homeSpacesState = homeSpacesPresenter.present() val homeSpacesState = homeSpacesPresenter.present()
val isSpaceFeatureEnabled by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space)
}.collectAsState(initial = false)
var currentHomeNavigationBarItemOrdinal by rememberSaveable { mutableIntStateOf(HomeNavigationBarItem.Chats.ordinal) } var currentHomeNavigationBarItemOrdinal by rememberSaveable { mutableIntStateOf(HomeNavigationBarItem.Chats.ordinal) }
val currentHomeNavigationBarItem by remember { val currentHomeNavigationBarItem by remember {
derivedStateOf { derivedStateOf {
@ -117,7 +111,6 @@ class HomePresenter(
snackbarMessage = snackbarMessage, snackbarMessage = snackbarMessage,
canReportBug = canReportBug, canReportBug = canReportBug,
directLogoutState = directLogoutState, directLogoutState = directLogoutState,
isSpaceFeatureEnabled = isSpaceFeatureEnabled,
eventSink = ::handleEvent, eventSink = ::handleEvent,
) )
} }

View file

@ -29,10 +29,9 @@ data class HomeState(
val snackbarMessage: SnackbarMessage?, val snackbarMessage: SnackbarMessage?,
val canReportBug: Boolean, val canReportBug: Boolean,
val directLogoutState: DirectLogoutState, val directLogoutState: DirectLogoutState,
val isSpaceFeatureEnabled: Boolean,
val eventSink: (HomeEvents) -> Unit, val eventSink: (HomeEvents) -> Unit,
) { ) {
val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats
val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters
val showNavigationBar = isSpaceFeatureEnabled && homeSpacesState.spaceRooms.isNotEmpty() val showNavigationBar = homeSpacesState.spaceRooms.isNotEmpty()
} }

View file

@ -31,7 +31,6 @@ open class HomeStateProvider : PreviewParameterProvider<HomeState> {
aHomeState(hasNetworkConnection = false), aHomeState(hasNetworkConnection = false),
aHomeState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)), aHomeState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)),
aHomeState( aHomeState(
isSpaceFeatureEnabled = true,
roomListState = aRoomListState( roomListState = aRoomListState(
// Add more rooms to see the blur effect under the NavigationBar // Add more rooms to see the blur effect under the NavigationBar
contentState = aRoomsContentState( contentState = aRoomsContentState(
@ -42,7 +41,6 @@ open class HomeStateProvider : PreviewParameterProvider<HomeState> {
homeSpacesState = aHomeSpacesState(), homeSpacesState = aHomeSpacesState(),
), ),
aHomeState( aHomeState(
isSpaceFeatureEnabled = true,
currentHomeNavigationBarItem = HomeNavigationBarItem.Spaces, currentHomeNavigationBarItem = HomeNavigationBarItem.Spaces,
), ),
) + RoomListStateProvider().values.map { ) + RoomListStateProvider().values.map {
@ -60,7 +58,6 @@ internal fun aHomeState(
roomListState: RoomListState = aRoomListState(), roomListState: RoomListState = aRoomListState(),
homeSpacesState: HomeSpacesState = aHomeSpacesState(), homeSpacesState: HomeSpacesState = aHomeSpacesState(),
canReportBug: Boolean = true, canReportBug: Boolean = true,
isSpaceFeatureEnabled: Boolean = false,
directLogoutState: DirectLogoutState = aDirectLogoutState(), directLogoutState: DirectLogoutState = aDirectLogoutState(),
eventSink: (HomeEvents) -> Unit = {} eventSink: (HomeEvents) -> Unit = {}
) = HomeState( ) = HomeState(
@ -73,6 +70,5 @@ internal fun aHomeState(
currentHomeNavigationBarItem = currentHomeNavigationBarItem, currentHomeNavigationBarItem = currentHomeNavigationBarItem,
roomListState = roomListState, roomListState = roomListState,
homeSpacesState = homeSpacesState, homeSpacesState = homeSpacesState,
isSpaceFeatureEnabled = isSpaceFeatureEnabled,
eventSink = eventSink, eventSink = eventSink,
) )

View file

@ -179,14 +179,10 @@ private fun HomeScaffold(
displayFilters = state.displayRoomListFilters, displayFilters = state.displayRoomListFilters,
filtersState = roomListState.filtersState, filtersState = roomListState.filtersState,
canReportBug = state.canReportBug, canReportBug = state.canReportBug,
modifier = if (state.isSpaceFeatureEnabled) { modifier = Modifier.hazeEffect(
Modifier.hazeEffect( state = hazeState,
state = hazeState, style = HazeMaterials.thick(),
style = HazeMaterials.thick(), )
)
} else {
Modifier.background(ElementTheme.colors.bgCanvasDefault)
}
) )
}, },
bottomBar = { bottomBar = {

View file

@ -22,9 +22,6 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.features.rageshake.test.logs.FakeAnnouncementService import io.element.android.features.rageshake.test.logs.FakeAnnouncementService
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher 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
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.indicator.api.IndicatorService
import io.element.android.libraries.indicator.test.FakeIndicatorService import io.element.android.libraries.indicator.test.FakeIndicatorService
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
@ -35,7 +32,6 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION
import io.element.android.libraries.matrix.test.A_USER_ID 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.A_USER_NAME
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.api.SessionStore
import io.element.android.libraries.sessionstorage.test.InMemorySessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore
@ -54,8 +50,6 @@ class HomePresenterTest {
@get:Rule @get:Rule
val warmUpRule = WarmUpRule() val warmUpRule = WarmUpRule()
private val isSpaceEnabled = FeatureFlags.Space.defaultValue(aBuildMeta())
@Test @Test
fun `present - should start with no user and then load user with success`() = runTest { fun `present - should start with no user and then load user with success`() = runTest {
val matrixClient = FakeMatrixClient( val matrixClient = FakeMatrixClient(
@ -79,7 +73,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
}.test { }.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo( assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(
MatrixUser(A_USER_ID, null, null) MatrixUser(A_USER_ID, null, null)
@ -91,8 +84,7 @@ class HomePresenterTest {
MatrixUser(A_USER_ID, A_USER_NAME, AN_AVATAR_URL) MatrixUser(A_USER_ID, A_USER_NAME, AN_AVATAR_URL)
) )
assertThat(withUserState.showAvatarIndicator).isFalse() assertThat(withUserState.showAvatarIndicator).isFalse()
assertThat(withUserState.isSpaceFeatureEnabled).isEqualTo(isSpaceEnabled) assertThat(withUserState.showNavigationBar).isTrue()
assertThat(withUserState.showNavigationBar).isEqualTo(isSpaceEnabled)
} }
} }
@ -114,23 +106,6 @@ class HomePresenterTest {
} }
} }
@Test
fun `present - space feature enabled`() = runTest {
val presenter = createHomePresenter(
featureFlagService = FakeFeatureFlagService(
initialState = mapOf(FeatureFlags.Space.key to true),
),
sessionStore = InMemorySessionStore(
updateUserProfileResult = { _, _, _ -> },
),
)
presenter.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.isSpaceFeatureEnabled).isTrue()
}
}
@Test @Test
fun `present - show avatar indicator`() = runTest { fun `present - show avatar indicator`() = runTest {
val indicatorService = FakeIndicatorService() val indicatorService = FakeIndicatorService()
@ -143,7 +118,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
}.test { }.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.showAvatarIndicator).isFalse() assertThat(initialState.showAvatarIndicator).isFalse()
indicatorService.setShowRoomListTopBarIndicator(true) indicatorService.setShowRoomListTopBarIndicator(true)
@ -168,7 +142,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
}.test { }.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(MatrixUser(matrixClient.sessionId)) assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(MatrixUser(matrixClient.sessionId))
// No new state is coming // No new state is coming
@ -189,7 +162,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
}.test { }.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats) assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats)
initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces)) initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces))
@ -207,16 +179,12 @@ class HomePresenterTest {
sessionStore = InMemorySessionStore( sessionStore = InMemorySessionStore(
updateUserProfileResult = { _, _, _ -> }, updateUserProfileResult = { _, _, _ -> },
), ),
featureFlagService = FakeFeatureFlagService(
initialState = mapOf(FeatureFlags.Space.key to true),
),
homeSpacesPresenter = homeSpacesPresenter, homeSpacesPresenter = homeSpacesPresenter,
announcementService = FakeAnnouncementService( announcementService = FakeAnnouncementService(
showAnnouncementResult = {}, showAnnouncementResult = {},
) )
) )
presenter.test { presenter.test {
skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats) assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats)
assertThat(initialState.showNavigationBar).isTrue() assertThat(initialState.showNavigationBar).isTrue()
@ -241,7 +209,6 @@ internal fun createHomePresenter(
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(), snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) }, rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) },
indicatorService: IndicatorService = FakeIndicatorService(), indicatorService: IndicatorService = FakeIndicatorService(),
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
homeSpacesPresenter: Presenter<HomeSpacesState> = Presenter { aHomeSpacesState() }, homeSpacesPresenter: Presenter<HomeSpacesState> = Presenter { aHomeSpacesState() },
sessionStore: SessionStore = InMemorySessionStore(), sessionStore: SessionStore = InMemorySessionStore(),
announcementService: AnnouncementService = FakeAnnouncementService(), announcementService: AnnouncementService = FakeAnnouncementService(),
@ -250,11 +217,10 @@ internal fun createHomePresenter(
syncService = syncService, syncService = syncService,
snackbarDispatcher = snackbarDispatcher, snackbarDispatcher = snackbarDispatcher,
indicatorService = indicatorService, indicatorService = indicatorService,
logoutPresenter = { aDirectLogoutState() },
roomListPresenter = { aRoomListState() }, roomListPresenter = { aRoomListState() },
homeSpacesPresenter = homeSpacesPresenter, homeSpacesPresenter = homeSpacesPresenter,
logoutPresenter = { aDirectLogoutState() },
rageshakeFeatureAvailability = rageshakeFeatureAvailability, rageshakeFeatureAvailability = rageshakeFeatureAvailability,
featureFlagService = featureFlagService,
sessionStore = sessionStore, sessionStore = sessionStore,
announcementService = announcementService, announcementService = announcementService,
) )

View file

@ -70,12 +70,6 @@ enum class FeatureFlags(
defaultValue = { false }, defaultValue = { false },
isFinished = false, isFinished = false,
), ),
Space(
key = "feature.space",
title = "Spaces",
defaultValue = { true },
isFinished = true,
),
SpaceSettings( SpaceSettings(
key = "feature.spaceSettings", key = "feature.spaceSettings",
title = "Space settings", title = "Space settings",