Announcement for Spaces

This commit is contained in:
Benoit Marty 2025-10-02 23:13:43 +02:00
parent 8664b2ce90
commit e40451463b
30 changed files with 690 additions and 1 deletions

View file

@ -34,6 +34,7 @@ import io.element.android.appnav.intent.ResolvedIntent
import io.element.android.appnav.root.RootNavStateFlowFactory
import io.element.android.appnav.root.RootPresenter
import io.element.android.appnav.root.RootView
import io.element.android.features.announcement.api.AnnouncementService
import io.element.android.features.login.api.LoginParams
import io.element.android.features.login.api.accesscontrol.AccountProviderAccessControl
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
@ -81,6 +82,7 @@ class RootFlowNode(
private val oidcActionFlow: OidcActionFlow,
private val bugReporter: BugReporter,
private val featureFlagService: FeatureFlagService,
private val announcementService: AnnouncementService,
) : BaseFlowNode<RootFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.SplashScreen,
@ -172,6 +174,9 @@ class RootFlowNode(
state = state,
modifier = modifier,
onOpenBugReport = this::onOpenBugReport,
announcementRenderer = { state, announcementModifier ->
announcementService.Render(state, announcementModifier)
}
) {
val backstackSlider = rememberBackstackSlider<NavTarget>(
transitionSpec = { spring(stiffness = Spring.StiffnessMediumLow) },

View file

@ -13,6 +13,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.SuperProperties
import io.element.android.features.announcement.api.AnnouncementState
import io.element.android.features.rageshake.api.crash.CrashDetectionState
import io.element.android.features.rageshake.api.detection.RageshakeDetectionState
import io.element.android.libraries.architecture.Presenter
@ -24,6 +25,7 @@ import io.element.android.services.apperror.api.AppErrorStateService
class RootPresenter(
private val crashDetectionPresenter: Presenter<CrashDetectionState>,
private val rageshakeDetectionPresenter: Presenter<RageshakeDetectionState>,
private val announcementPresenter: Presenter<AnnouncementState>,
private val appErrorStateService: AppErrorStateService,
private val analyticsService: AnalyticsService,
private val sdkMetadata: SdkMetadata,
@ -32,6 +34,7 @@ class RootPresenter(
override fun present(): RootState {
val rageshakeDetectionState = rageshakeDetectionPresenter.present()
val crashDetectionState = crashDetectionPresenter.present()
val announcementState = announcementPresenter.present()
val appErrorState by appErrorStateService.appErrorStateFlow.collectAsState()
LaunchedEffect(Unit) {
@ -48,6 +51,7 @@ class RootPresenter(
rageshakeDetectionState = rageshakeDetectionState,
crashDetectionState = crashDetectionState,
errorState = appErrorState,
announcementState = announcementState,
)
}
}

View file

@ -8,6 +8,7 @@
package io.element.android.appnav.root
import androidx.compose.runtime.Immutable
import io.element.android.features.announcement.api.AnnouncementState
import io.element.android.features.rageshake.api.crash.CrashDetectionState
import io.element.android.features.rageshake.api.detection.RageshakeDetectionState
import io.element.android.services.apperror.api.AppErrorState
@ -17,4 +18,5 @@ data class RootState(
val rageshakeDetectionState: RageshakeDetectionState,
val crashDetectionState: CrashDetectionState,
val errorState: AppErrorState,
val announcementState: AnnouncementState,
)

View file

@ -8,6 +8,7 @@
package io.element.android.appnav.root
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.announcement.api.anAnnouncementState
import io.element.android.features.rageshake.api.crash.aCrashDetectionState
import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState
import io.element.android.services.apperror.api.AppErrorState
@ -33,5 +34,6 @@ open class RootStateProvider : PreviewParameterProvider<RootState> {
fun aRootState() = RootState(
rageshakeDetectionState = aRageshakeDetectionState(),
crashDetectionState = aCrashDetectionState(),
announcementState = anAnnouncementState(),
errorState = AppErrorState.NoError,
)

View file

@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.announcement.api.AnnouncementState
import io.element.android.features.rageshake.api.crash.CrashDetectionEvents
import io.element.android.features.rageshake.api.crash.CrashDetectionView
import io.element.android.features.rageshake.api.detection.RageshakeDetectionEvents
@ -27,6 +28,7 @@ import io.element.android.services.apperror.impl.AppErrorView
fun RootView(
state: RootState,
onOpenBugReport: () -> Unit,
announcementRenderer: @Composable (AnnouncementState, Modifier) -> Unit,
modifier: Modifier = Modifier,
children: @Composable BoxScope.() -> Unit,
) {
@ -43,6 +45,11 @@ fun RootView(
onOpenBugReport.invoke()
}
announcementRenderer(
state.announcementState,
Modifier,
)
RageshakeDetectionView(
state = state.rageshakeDetectionState,
onOpenBugReport = ::onOpenBugReport,
@ -63,6 +70,7 @@ internal fun RootViewPreview(@PreviewParameter(RootStateProvider::class) rootSta
RootView(
state = rootState,
onOpenBugReport = {},
announcementRenderer = { _, _ -> },
) {
Text("Children")
}

View file

@ -12,6 +12,7 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.appnav.root.RootPresenter
import io.element.android.features.announcement.api.anAnnouncementState
import io.element.android.features.rageshake.api.crash.aCrashDetectionState
import io.element.android.features.rageshake.api.detection.aRageshakeDetectionState
import io.element.android.libraries.matrix.test.FakeSdkMetadata
@ -71,6 +72,7 @@ class RootPresenterTest {
return RootPresenter(
crashDetectionPresenter = { aCrashDetectionState() },
rageshakeDetectionPresenter = { aRageshakeDetectionState() },
announcementPresenter = { anAnnouncementState() },
appErrorStateService = appErrorService,
analyticsService = FakeAnalyticsService(),
sdkMetadata = FakeSdkMetadata("sha")