Merge pull request #5960 from element-hq/feature/fga/fix_space_ff_disabled

Ensure space feature is enabled
This commit is contained in:
ganfra 2026-01-05 11:30:37 +01:00 committed by GitHub
commit 094b4c8c0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 57 additions and 109 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.designsystem.utils.snackbar.SnackbarDispatcher
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.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.sync.SyncService
@ -48,7 +46,6 @@ class HomePresenter(
private val homeSpacesPresenter: Presenter<HomeSpacesState>,
private val logoutPresenter: Presenter<DirectLogoutState>,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
private val featureFlagService: FeatureFlagService,
private val sessionStore: SessionStore,
private val announcementService: AnnouncementService,
) : Presenter<HomeState> {
@ -69,9 +66,6 @@ class HomePresenter(
val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false)
val roomListState = roomListPresenter.present()
val homeSpacesState = homeSpacesPresenter.present()
val isSpaceFeatureEnabled by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space)
}.collectAsState(initial = false)
var currentHomeNavigationBarItemOrdinal by rememberSaveable { mutableIntStateOf(HomeNavigationBarItem.Chats.ordinal) }
val currentHomeNavigationBarItem by remember {
derivedStateOf {
@ -117,7 +111,6 @@ class HomePresenter(
snackbarMessage = snackbarMessage,
canReportBug = canReportBug,
directLogoutState = directLogoutState,
isSpaceFeatureEnabled = isSpaceFeatureEnabled,
eventSink = ::handleEvent,
)
}

View file

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

View file

@ -179,14 +179,10 @@ private fun HomeScaffold(
displayFilters = state.displayRoomListFilters,
filtersState = roomListState.filtersState,
canReportBug = state.canReportBug,
modifier = if (state.isSpaceFeatureEnabled) {
Modifier.hazeEffect(
state = hazeState,
style = HazeMaterials.thick(),
)
} else {
Modifier.background(ElementTheme.colors.bgCanvasDefault)
}
modifier = Modifier.hazeEffect(
state = hazeState,
style = HazeMaterials.thick(),
)
)
},
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.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
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.indicator.api.IndicatorService
import io.element.android.libraries.indicator.test.FakeIndicatorService
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_NAME
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.sessionstorage.api.SessionStore
import io.element.android.libraries.sessionstorage.test.InMemorySessionStore
@ -54,8 +50,6 @@ class HomePresenterTest {
@get:Rule
val warmUpRule = WarmUpRule()
private val isSpaceEnabled = FeatureFlags.Space.defaultValue(aBuildMeta())
@Test
fun `present - should start with no user and then load user with success`() = runTest {
val matrixClient = FakeMatrixClient(
@ -79,7 +73,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem()
assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(
MatrixUser(A_USER_ID, null, null)
@ -91,8 +84,7 @@ class HomePresenterTest {
MatrixUser(A_USER_ID, A_USER_NAME, AN_AVATAR_URL)
)
assertThat(withUserState.showAvatarIndicator).isFalse()
assertThat(withUserState.isSpaceFeatureEnabled).isEqualTo(isSpaceEnabled)
assertThat(withUserState.showNavigationBar).isEqualTo(isSpaceEnabled)
assertThat(withUserState.showNavigationBar).isTrue()
}
}
@ -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
fun `present - show avatar indicator`() = runTest {
val indicatorService = FakeIndicatorService()
@ -143,7 +118,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem()
assertThat(initialState.showAvatarIndicator).isFalse()
indicatorService.setShowRoomListTopBarIndicator(true)
@ -168,7 +142,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem()
assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(MatrixUser(matrixClient.sessionId))
// No new state is coming
@ -189,7 +162,6 @@ class HomePresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
if (isSpaceEnabled) skipItems(1)
val initialState = awaitItem()
assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats)
initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces))
@ -207,16 +179,12 @@ class HomePresenterTest {
sessionStore = InMemorySessionStore(
updateUserProfileResult = { _, _, _ -> },
),
featureFlagService = FakeFeatureFlagService(
initialState = mapOf(FeatureFlags.Space.key to true),
),
homeSpacesPresenter = homeSpacesPresenter,
announcementService = FakeAnnouncementService(
showAnnouncementResult = {},
)
)
presenter.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats)
assertThat(initialState.showNavigationBar).isTrue()
@ -241,7 +209,6 @@ internal fun createHomePresenter(
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) },
indicatorService: IndicatorService = FakeIndicatorService(),
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
homeSpacesPresenter: Presenter<HomeSpacesState> = Presenter { aHomeSpacesState() },
sessionStore: SessionStore = InMemorySessionStore(),
announcementService: AnnouncementService = FakeAnnouncementService(),
@ -250,11 +217,10 @@ internal fun createHomePresenter(
syncService = syncService,
snackbarDispatcher = snackbarDispatcher,
indicatorService = indicatorService,
logoutPresenter = { aDirectLogoutState() },
roomListPresenter = { aRoomListState() },
homeSpacesPresenter = homeSpacesPresenter,
logoutPresenter = { aDirectLogoutState() },
rageshakeFeatureAvailability = rageshakeFeatureAvailability,
featureFlagService = featureFlagService,
sessionStore = sessionStore,
announcementService = announcementService,
)

View file

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

View file

@ -25,10 +25,14 @@ class DefaultFeatureFlagService(
private val featuresProvider: FeaturesProvider,
) : FeatureFlagService {
override fun isFeatureEnabledFlow(feature: Feature): Flow<Boolean> {
return providers.filter { it.hasFeature(feature) }
.maxByOrNull(FeatureFlagProvider::priority)
?.isFeatureEnabledFlow(feature)
?: flowOf(feature.defaultValue(buildMeta))
return if (feature.isFinished) {
flowOf(feature.defaultValue(buildMeta))
} else {
providers.filter { it.hasFeature(feature) }
.maxByOrNull(FeatureFlagProvider::priority)
?.isFeatureEnabledFlow(feature)
?: flowOf(feature.defaultValue(buildMeta))
}
}
override suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean): Boolean {

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:29076d1c09d92943b1ba143d0ed3798fe92f7d37f87f45c0ae5f7326afe66f74
size 136708
oid sha256:cc3fcb72de86766e3b97ffe0802551d7597b688f2a52ef73938d91c9cfdf0633
size 141868

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1
size 61515
oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4
size 65455

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd257b64d9e91bedebcf4552e8b93d357304954ad844b7f7d52bc76fc1543747
size 29901
oid sha256:4eb7b8997069e2a4b37cd27c33e2862cba1871e1b58e85feb0b1bc4da6a3fce8
size 33631

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4e3e455fbe6e3a10ec1578e01dc3f10c3b2b0688f99a1855319143c8fc7044a8
size 25355
oid sha256:ff84f90db0deea1d8edc52a2067855cf277cc747f5c357dc0758ce72bbc6d0c8
size 28014

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:821cb6a2068561375d0988d4ba5404e52411a6d9b73cefbe1a6bd7bc6d467673
size 88367
oid sha256:e8cd2089f07a93e3dc62e41d80a3253d800b4463947276ccd461428280aff6b8
size 84644

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f9f5fef39d80aacb9666deeea43e4df48f7c70231bd8ec41edf2f3eed5f0aa42
size 81149
oid sha256:71f336f93dd3fe736187a38aba6c1f14420bb0da9d574603f6df2042bce8f8d1
size 83116

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c9e019924f41de0c16f1f403944b8fe390afa65d1ad604db3dd0baadbc30db5b
size 50953
oid sha256:d7840847edf48b171393418d6fc26d846d772fa8be919f55dfee086d85cab814
size 51404

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1
size 61515
oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4
size 65455

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1
size 61515
oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4
size 65455

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1
size 61515
oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4
size 65455

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a5a68b4d8951b7c516561d538c5d328a84948c66af7eb7c80ac77cd005620cf2
size 80977
oid sha256:9fb19cc1e169e81f301a12ff3e30b8118682248ec3c13ea29b54f87398a54c3e
size 82977

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e
size 58325
oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90
size 62152

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:496855b1b3186adcad8b35895ee51776dce00a8d3229b8dccac4d6e4482bdaff
size 26577
oid sha256:ab4a977d119ae80ddb92198b9c26b4b42d842eba0fd0543896f55914018d34f2
size 30548

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8b98678dc90bce52ab2293e5102794b4fc3b51fc667a6c061d771ea90212a0f2
size 22034
oid sha256:66824bcff1cf8fdd0fd88c3e0272bd11eaf6fdd16d24120c9346c99378226eee
size 24633

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:541740cdd54ef7b9a868c1409330a6ca7417bce9f022b22c3d395ac9b215d470
size 83939
oid sha256:7d1745b2665a9329808f69e2750b50d59eac2d92216a25bae03a52907b6c7681
size 80341

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a44897f23fc0e6a90779fe96638c560973caf7dbb9a7c92ec4d2f5b56de3ddcc
size 77280
oid sha256:9017e66bb482de6a517065efe2e9d66ce4eb561fb848ca29d3245a2abc02d4c0
size 79209

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8f0e5430bcd399d5a39c3d92e7551243f0e15bc315f9ec6ded43829d4672308c
size 47186
oid sha256:6fd8d9d809b65df1690bf132351eec86736224d50fdd1bc9f9d2e731a4669ad6
size 47687

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e
size 58325
oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90
size 62152

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e
size 58325
oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90
size 62152

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e
size 58325
oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90
size 62152

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:49ea33ae74532c350b4176355203561cfc5eb79c93c4993d6ffb0cf933f8ad2f
size 77167
oid sha256:6c7790afd67222ce61ea0b72f1af3c1877b7e88580a644524c33f18d6fe76137
size 79096