diff --git a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt index 0bf35650a0..a83d167ee2 100644 --- a/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt +++ b/features/announcement/api/src/main/kotlin/io/element/android/features/announcement/api/Announcement.kt @@ -8,7 +8,10 @@ package io.element.android.features.announcement.api -enum class Announcement { - Space, - NewNotificationSound, +sealed interface Announcement { + sealed interface Fullscreen : Announcement { + data object Space : Fullscreen + } + + data object NewNotificationSound : Announcement } diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementEvent.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementEvent.kt new file mode 100644 index 0000000000..947a3ceeba --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementEvent.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.announcement.impl + +import io.element.android.features.announcement.api.Announcement + +sealed interface AnnouncementEvent { + data class Continue( + val announcement: Announcement.Fullscreen, + ) : AnnouncementEvent +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt index 508f1e44a0..bd45ddb956 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenter.kt @@ -12,12 +12,16 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import dev.zacsweers.metro.Inject import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.impl.store.AnnouncementStatus import io.element.android.features.announcement.impl.store.AnnouncementStore import io.element.android.libraries.architecture.Presenter +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch @Inject class AnnouncementPresenter( @@ -25,13 +29,39 @@ class AnnouncementPresenter( ) : Presenter { @Composable override fun present(): AnnouncementState { - val showSpaceAnnouncement by remember { - announcementStore.announcementStatusFlow(Announcement.Space).map { - it == AnnouncementStatus.Show + val coroutineScope = rememberCoroutineScope() + + val fullscreenAnnouncementToShow by remember { + combine( + flowOf(Unit), + announcementStore.announcementStatusFlow(Announcement.Fullscreen.Space).map { + it == AnnouncementStatus.Show + }, + // Add other announcements here when needed + ) { _, showFullscreenSpace -> + when { + showFullscreenSpace -> Announcement.Fullscreen.Space + else -> { + null + } + } } - }.collectAsState(false) + }.collectAsState(null) + + fun handle(event: AnnouncementEvent) { + when (event) { + is AnnouncementEvent.Continue -> coroutineScope.launch { + announcementStore.setAnnouncementStatus( + announcement = event.announcement, + status = AnnouncementStatus.Shown, + ) + } + } + } + return AnnouncementState( - showSpaceAnnouncement = showSpaceAnnouncement, + announcement = fullscreenAnnouncementToShow, + eventSink = ::handle, ) } } diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt index e762dd607f..3ef47d6ed0 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementState.kt @@ -8,12 +8,9 @@ package io.element.android.features.announcement.impl -data class AnnouncementState( - val showSpaceAnnouncement: Boolean, -) +import io.element.android.features.announcement.api.Announcement -fun anAnnouncementState( - showSpaceAnnouncement: Boolean = false, -) = AnnouncementState( - showSpaceAnnouncement = showSpaceAnnouncement, +data class AnnouncementState( + val announcement: Announcement.Fullscreen? = null, + val eventSink: (AnnouncementEvent) -> Unit, ) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementStateProvider.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementStateProvider.kt new file mode 100644 index 0000000000..2412fee167 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/AnnouncementStateProvider.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.announcement.impl + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.announcement.api.Announcement + +open class AnnouncementStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + anAnnouncementState(), + anAnnouncementState( + announcement = Announcement.Fullscreen.Space, + ), + ) +} + +fun anAnnouncementState( + announcement: Announcement.Fullscreen? = null, + eventSink: (AnnouncementEvent) -> Unit = {}, +) = AnnouncementState( + announcement = announcement, + eventSink = eventSink, +) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt index 0e5c30178c..adb81db61a 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementService.kt @@ -8,35 +8,28 @@ package io.element.android.features.announcement.impl -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService -import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState -import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementView +import io.element.android.features.announcement.impl.fullscreen.FullscreenAnnouncementView import io.element.android.features.announcement.impl.store.AnnouncementStatus import io.element.android.features.announcement.impl.store.AnnouncementStore -import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf @ContributesBinding(AppScope::class) class DefaultAnnouncementService( private val announcementStore: AnnouncementStore, - private val announcementPresenter: Presenter, - private val spaceAnnouncementPresenter: Presenter, + private val announcementPresenter: AnnouncementPresenter, ) : AnnouncementService { override suspend fun showAnnouncement(announcement: Announcement) { when (announcement) { - Announcement.Space -> showSpaceAnnouncement() + is Announcement.Fullscreen -> showFullscreenAnnouncement(announcement) Announcement.NewNotificationSound -> { announcementStore.setAnnouncementStatus(Announcement.NewNotificationSound, AnnouncementStatus.Show) } @@ -49,13 +42,10 @@ class DefaultAnnouncementService( override fun announcementsToShowFlow(): Flow> { return combine( - announcementStore.announcementStatusFlow(Announcement.Space), + flowOf(Unit), announcementStore.announcementStatusFlow(Announcement.NewNotificationSound), - ) { spaceAnnouncementStatus, newNotificationSoundStatus -> + ) { _, newNotificationSoundStatus -> buildList { - if (spaceAnnouncementStatus == AnnouncementStatus.Show) { - add(Announcement.Space) - } if (newNotificationSoundStatus == AnnouncementStatus.Show) { add(Announcement.NewNotificationSound) } @@ -63,27 +53,19 @@ class DefaultAnnouncementService( } } - private suspend fun showSpaceAnnouncement() { - val currentValue = announcementStore.announcementStatusFlow(Announcement.Space).first() + private suspend fun showFullscreenAnnouncement(announcement: Announcement.Fullscreen) { + val currentValue = announcementStore.announcementStatusFlow(announcement).first() if (currentValue == AnnouncementStatus.NeverShown) { - announcementStore.setAnnouncementStatus(Announcement.Space, AnnouncementStatus.Show) + announcementStore.setAnnouncementStatus(announcement, AnnouncementStatus.Show) } } @Composable override fun Render(modifier: Modifier) { val announcementState = announcementPresenter.present() - Box(modifier = modifier.fillMaxSize()) { - AnimatedVisibility( - visible = announcementState.showSpaceAnnouncement, - enter = fadeIn(), - exit = fadeOut(), - ) { - val spaceAnnouncementState = spaceAnnouncementPresenter.present() - SpaceAnnouncementView( - state = spaceAnnouncementState, - ) - } - } + FullscreenAnnouncementView( + state = announcementState, + modifier = modifier, + ) } } diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt deleted file mode 100644 index 4cfc073271..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/di/AnnouncementModule.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.di - -import dev.zacsweers.metro.AppScope -import dev.zacsweers.metro.BindingContainer -import dev.zacsweers.metro.Binds -import dev.zacsweers.metro.ContributesTo -import io.element.android.features.announcement.impl.AnnouncementPresenter -import io.element.android.features.announcement.impl.AnnouncementState -import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementPresenter -import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState -import io.element.android.libraries.architecture.Presenter - -@ContributesTo(AppScope::class) -@BindingContainer -interface AnnouncementModule { - @Binds - fun bindAnnouncementPresenter(presenter: AnnouncementPresenter): Presenter - - @Binds - fun bindSpaceAnnouncementPresenter(presenter: SpaceAnnouncementPresenter): Presenter -} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/fullscreen/FullscreenAnnouncementView.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/fullscreen/FullscreenAnnouncementView.kt new file mode 100644 index 0000000000..c544fd4914 --- /dev/null +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/fullscreen/FullscreenAnnouncementView.kt @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.announcement.impl.fullscreen + +import androidx.activity.compose.BackHandler +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.announcement.api.Announcement +import io.element.android.features.announcement.impl.AnnouncementEvent +import io.element.android.features.announcement.impl.AnnouncementState +import io.element.android.features.announcement.impl.AnnouncementStateProvider +import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule +import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule +import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem +import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism +import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +/** + * Ref: https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=4593-40181 + */ +@Composable +fun FullscreenAnnouncementView( + state: AnnouncementState, + modifier: Modifier = Modifier, +) { + // Ensure that the content stays visible during the exit animation + var fullscreenAnnouncement by remember { mutableStateOf(null) } + if (state.announcement != null) { + fullscreenAnnouncement = state.announcement + } + Box(modifier = modifier.fillMaxSize()) { + AnimatedVisibility( + visible = state.announcement != null, + enter = fadeIn(), + exit = fadeOut(), + ) { + fullscreenAnnouncement?.let { + FullscreenAnnouncementView( + announcement = it, + eventSink = state.eventSink, + ) + } + } + } +} + +@Composable +private fun FullscreenAnnouncementView( + announcement: Announcement.Fullscreen, + eventSink: (AnnouncementEvent) -> Unit, + modifier: Modifier = Modifier +) { + fun onContinue() { + eventSink(AnnouncementEvent.Continue(announcement)) + } + + BackHandler(onBack = ::onContinue) + HeaderFooterPage( + modifier = modifier, + isScrollable = true, + contentPadding = PaddingValues(top = 24.dp, start = 16.dp, end = 16.dp, bottom = 24.dp), + header = { + FullscreenAnnouncementHeader(announcement) + }, + content = { + FullscreenAnnouncementContent( + modifier = Modifier.padding(horizontal = 8.dp), + announcement = announcement, + ) + }, + footer = { + FullscreenAnnouncementFooter( + onContinue = ::onContinue, + ) + } + ) +} + +@Composable +private fun FullscreenAnnouncementHeader( + announcement: Announcement.Fullscreen, + modifier: Modifier = Modifier, +) { + IconTitleSubtitleMolecule( + modifier = modifier.padding(top = 16.dp, bottom = 16.dp), + title = announcement.title(), + showBetaLabel = true, + subTitle = announcement.subtitle(), + iconStyle = BigIcon.Style.Default( + vectorIcon = announcement.icon(), + usePrimaryTint = true, + ), + ) +} + +@Composable +private fun FullscreenAnnouncementContent( + announcement: Announcement.Fullscreen, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier.fillMaxSize(), + ) { + InfoListOrganism( + modifier = Modifier.fillMaxWidth(), + items = announcement.items(), + textStyle = ElementTheme.typography.fontBodyLgMedium, + iconTint = ElementTheme.colors.iconSecondary, + iconSize = 24.dp + ) + announcement.notice()?.let { notice -> + Text( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp), + text = notice, + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textSecondary, + textAlign = TextAlign.Center, + ) + } + } +} + +@Composable +private fun FullscreenAnnouncementFooter( + onContinue: () -> Unit, +) { + ButtonColumnMolecule( + modifier = Modifier.padding(bottom = 8.dp) + ) { + Button( + text = stringResource(id = CommonStrings.action_continue), + onClick = onContinue, + modifier = Modifier.fillMaxWidth(), + ) + } +} + +@Composable +private fun Announcement.Fullscreen.title() = when (this) { + Announcement.Fullscreen.Space -> "Introducing Spaces" +} + +@Composable +private fun Announcement.Fullscreen.subtitle() = when (this) { + Announcement.Fullscreen.Space -> "Welcome to the beta version of Spaces! With this first version you can:" +} + +@Composable +private fun Announcement.Fullscreen.icon() = when (this) { + Announcement.Fullscreen.Space -> CompoundIcons.SpaceSolid() +} + +@Composable +private fun Announcement.Fullscreen.items(): ImmutableList = when (this) { + Announcement.Fullscreen.Space -> persistentListOf( + InfoListItem( + message = "View spaces you\'ve created or joined", + iconVector = CompoundIcons.VisibilityOn(), + ), + InfoListItem( + message = "Accept or decline invites to spaces", + iconVector = CompoundIcons.Email(), + ), + InfoListItem( + message = "Discover any rooms you can join in your spaces", + iconVector = CompoundIcons.Search(), + ), + InfoListItem( + message = "Join public spaces", + iconVector = CompoundIcons.Explore(), + ), + InfoListItem( + message = "Leave any spaces you’ve joined", + iconVector = CompoundIcons.Leave(), + ), + ) +} + +@Composable +private fun Announcement.Fullscreen.notice(): String? = when (this) { + Announcement.Fullscreen.Space -> "Filtering, creating and managing spaces is coming soon." +} + +@PreviewsDayNight +@Composable +internal fun FullscreenAnnouncementViewPreview(@PreviewParameter(AnnouncementStateProvider::class) state: AnnouncementState) = ElementPreview { + FullscreenAnnouncementView( + state = state, + ) +} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt deleted file mode 100644 index 3b968d09a6..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementEvents.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.spaces - -sealed interface SpaceAnnouncementEvents { - data object Continue : SpaceAnnouncementEvents -} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt deleted file mode 100644 index 7c4bc7b5eb..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenter.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.spaces - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.rememberCoroutineScope -import dev.zacsweers.metro.Inject -import io.element.android.features.announcement.api.Announcement -import io.element.android.features.announcement.impl.store.AnnouncementStatus -import io.element.android.features.announcement.impl.store.AnnouncementStore -import io.element.android.libraries.architecture.Presenter -import kotlinx.coroutines.launch - -@Inject -class SpaceAnnouncementPresenter( - private val announcementStore: AnnouncementStore, -) : Presenter { - @Composable - override fun present(): SpaceAnnouncementState { - val localCoroutineScope = rememberCoroutineScope() - - fun handleEvent(event: SpaceAnnouncementEvents) { - when (event) { - SpaceAnnouncementEvents.Continue -> localCoroutineScope.launch { - announcementStore.setAnnouncementStatus(Announcement.Space, AnnouncementStatus.Shown) - } - } - } - - return SpaceAnnouncementState( - eventSink = ::handleEvent, - ) - } -} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt deleted file mode 100644 index 9407fad872..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementState.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.spaces - -data class SpaceAnnouncementState( - val eventSink: (SpaceAnnouncementEvents) -> Unit -) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt deleted file mode 100644 index 27f48cc7ed..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementStateProvider.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.spaces - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider - -open class SpaceAnnouncementStateProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - aSpaceAnnouncementState(), - ) -} - -fun aSpaceAnnouncementState( - eventSink: (SpaceAnnouncementEvents) -> Unit = {}, -) = SpaceAnnouncementState( - eventSink = eventSink, -) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt deleted file mode 100644 index 3fe6ec4456..0000000000 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.spaces - -import androidx.activity.compose.BackHandler -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.CompoundIcons -import io.element.android.features.announcement.impl.R -import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule -import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule -import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem -import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism -import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage -import io.element.android.libraries.designsystem.components.BigIcon -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.Button -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.ui.strings.CommonStrings -import kotlinx.collections.immutable.persistentListOf - -/** - * Ref: https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=4593-40181 - */ -@Composable -fun SpaceAnnouncementView( - state: SpaceAnnouncementState, - modifier: Modifier = Modifier, -) { - val eventSink = state.eventSink - - fun onContinue() { - eventSink(SpaceAnnouncementEvents.Continue) - } - - BackHandler(onBack = ::onContinue) - HeaderFooterPage( - modifier = modifier, - isScrollable = true, - contentPadding = PaddingValues(top = 24.dp, start = 16.dp, end = 16.dp, bottom = 24.dp), - header = { - SpaceAnnouncementHeader() - }, - content = { - SpaceAnnouncementContent( - modifier = Modifier.padding(horizontal = 8.dp), - ) - }, - footer = { - SpaceAnnouncementFooter( - onContinue = ::onContinue, - ) - } - ) -} - -@Composable -private fun SpaceAnnouncementHeader( - modifier: Modifier = Modifier, -) { - IconTitleSubtitleMolecule( - modifier = modifier.padding(top = 16.dp, bottom = 16.dp), - title = stringResource(id = R.string.screen_space_announcement_title), - showBetaLabel = true, - subTitle = stringResource(id = R.string.screen_space_announcement_subtitle), - iconStyle = BigIcon.Style.Default( - vectorIcon = CompoundIcons.SpaceSolid(), - usePrimaryTint = true, - ), - ) -} - -@Composable -private fun SpaceAnnouncementContent( - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier.fillMaxSize(), - ) { - InfoListOrganism( - modifier = Modifier.fillMaxWidth(), - items = persistentListOf( - InfoListItem( - message = stringResource(id = R.string.screen_space_announcement_item1), - iconVector = CompoundIcons.VisibilityOn(), - ), - InfoListItem( - message = stringResource(id = R.string.screen_space_announcement_item2), - iconVector = CompoundIcons.Email(), - ), - InfoListItem( - message = stringResource(id = R.string.screen_space_announcement_item3), - iconVector = CompoundIcons.Search(), - ), - InfoListItem( - message = stringResource(id = R.string.screen_space_announcement_item4), - iconVector = CompoundIcons.Explore(), - ), - InfoListItem( - message = stringResource(id = R.string.screen_space_announcement_item5), - iconVector = CompoundIcons.Leave(), - ), - ), - textStyle = ElementTheme.typography.fontBodyLgMedium, - iconTint = ElementTheme.colors.iconSecondary, - iconSize = 24.dp - ) - Text( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp), - text = stringResource(id = R.string.screen_space_announcement_notice), - style = ElementTheme.typography.fontBodyMdRegular, - color = ElementTheme.colors.textSecondary, - textAlign = TextAlign.Center, - ) - } -} - -@Composable -private fun SpaceAnnouncementFooter( - onContinue: () -> Unit, -) { - ButtonColumnMolecule( - modifier = Modifier.padding(bottom = 8.dp) - ) { - Button( - text = stringResource(id = CommonStrings.action_continue), - onClick = onContinue, - modifier = Modifier.fillMaxWidth(), - ) - } -} - -@PreviewsDayNight -@Composable -internal fun SpaceAnnouncementViewPreview(@PreviewParameter(SpaceAnnouncementStateProvider::class) state: SpaceAnnouncementState) = ElementPreview { - SpaceAnnouncementView( - state = state, - ) -} diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt index ad166e4ef5..d24e9ed26e 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/store/DefaultAnnouncementStore.kt @@ -17,7 +17,6 @@ import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFac import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -private val spaceAnnouncementKey = intPreferencesKey("spaceAnnouncement") private val newNotificationSoundKey = intPreferencesKey("newNotificationSound") @ContributesBinding(AppScope::class) @@ -35,9 +34,10 @@ class DefaultAnnouncementStore( override fun announcementStatusFlow(announcement: Announcement): Flow { val key = announcement.toKey() + // Announcement.Fullscreen.Space is disabled, consider it's shown // For NewNotificationSound, a migration will set it to Show on application upgrade (see AppMigration08) val defaultStatus = when (announcement) { - Announcement.Space -> AnnouncementStatus.NeverShown + Announcement.Fullscreen.Space -> AnnouncementStatus.Shown Announcement.NewNotificationSound -> AnnouncementStatus.Shown } return store.data.map { prefs -> @@ -52,6 +52,6 @@ class DefaultAnnouncementStore( } private fun Announcement.toKey() = when (this) { - Announcement.Space -> spaceAnnouncementKey + is Announcement.Fullscreen -> intPreferencesKey("fullscreen_" + this::class.simpleName) Announcement.NewNotificationSound -> newNotificationSoundKey } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt index 18deb8b2fd..bcfd80942d 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/AnnouncementPresenterTest.kt @@ -23,25 +23,25 @@ class AnnouncementPresenterTest { val presenter = createAnnouncementPresenter() presenter.test { val state = awaitItem() - assertThat(state.showSpaceAnnouncement).isFalse() + assertThat(state.announcement).isNull() } } @Test - fun `present - showSpaceAnnouncement value depends on the value in the store`() = runTest { + fun `present - showFullscreen value depends on the value in the store`() = runTest { val store = InMemoryAnnouncementStore() val presenter = createAnnouncementPresenter( announcementStore = store, ) presenter.test { val state = awaitItem() - assertThat(state.showSpaceAnnouncement).isFalse() - store.setAnnouncementStatus(Announcement.Space, AnnouncementStatus.Show) + assertThat(state.announcement).isNull() + store.setAnnouncementStatus(Announcement.Fullscreen.Space, AnnouncementStatus.Show) val updatedState = awaitItem() - assertThat(updatedState.showSpaceAnnouncement).isTrue() - store.setAnnouncementStatus(Announcement.Space, AnnouncementStatus.Shown) + assertThat(updatedState.announcement).isEqualTo(Announcement.Fullscreen.Space) + store.setAnnouncementStatus(Announcement.Fullscreen.Space, AnnouncementStatus.Shown) val finalState = awaitItem() - assertThat(finalState.showSpaceAnnouncement).isFalse() + assertThat(finalState.announcement).isNull() } } } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt index e16619129c..c72d147c1d 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/DefaultAnnouncementServiceTest.kt @@ -11,31 +11,28 @@ package io.element.android.features.announcement.impl import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.announcement.api.Announcement -import io.element.android.features.announcement.impl.spaces.SpaceAnnouncementState -import io.element.android.features.announcement.impl.spaces.aSpaceAnnouncementState import io.element.android.features.announcement.impl.store.AnnouncementStatus import io.element.android.features.announcement.impl.store.AnnouncementStore import io.element.android.features.announcement.impl.store.InMemoryAnnouncementStore -import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Test class DefaultAnnouncementServiceTest { @Test - fun `when showing Space announcement, space announcement is set to show only if it was never shown`() = runTest { + fun `when showing Fullscreen announcement, Fullscreen announcement is set to show only if it was never shown`() = runTest { val announcementStore = InMemoryAnnouncementStore() val sut = createDefaultAnnouncementService( announcementStore = announcementStore, ) - assertThat(announcementStore.announcementStatusFlow(Announcement.Space).first()).isEqualTo(AnnouncementStatus.NeverShown) - sut.showAnnouncement(Announcement.Space) - assertThat(announcementStore.announcementStatusFlow(Announcement.Space).first()).isEqualTo(AnnouncementStatus.Show) + assertThat(announcementStore.announcementStatusFlow(Announcement.Fullscreen.Space).first()).isEqualTo(AnnouncementStatus.NeverShown) + sut.showAnnouncement(Announcement.Fullscreen.Space) + assertThat(announcementStore.announcementStatusFlow(Announcement.Fullscreen.Space).first()).isEqualTo(AnnouncementStatus.Show) // Simulate user close the announcement - sut.onAnnouncementDismissed(Announcement.Space) + sut.onAnnouncementDismissed(Announcement.Fullscreen.Space) // Entering again the space tab should not change the value - sut.showAnnouncement(Announcement.Space) - assertThat(announcementStore.announcementStatusFlow(Announcement.Space).first()).isEqualTo(AnnouncementStatus.Shown) + sut.showAnnouncement(Announcement.Fullscreen.Space) + assertThat(announcementStore.announcementStatusFlow(Announcement.Fullscreen.Space).first()).isEqualTo(AnnouncementStatus.Shown) } @Test @@ -62,11 +59,7 @@ class DefaultAnnouncementServiceTest { ) sut.announcementsToShowFlow().test { assertThat(awaitItem()).isEmpty() - announcementStore.setAnnouncementStatus(Announcement.Space, AnnouncementStatus.Show) - assertThat(awaitItem()).containsExactly(Announcement.Space) announcementStore.setAnnouncementStatus(Announcement.NewNotificationSound, AnnouncementStatus.Show) - assertThat(awaitItem()).containsExactly(Announcement.Space, Announcement.NewNotificationSound) - announcementStore.setAnnouncementStatus(Announcement.Space, AnnouncementStatus.Shown) assertThat(awaitItem()).containsExactly(Announcement.NewNotificationSound) announcementStore.setAnnouncementStatus(Announcement.NewNotificationSound, AnnouncementStatus.Shown) assertThat(awaitItem()).isEmpty() @@ -75,11 +68,9 @@ class DefaultAnnouncementServiceTest { private fun createDefaultAnnouncementService( announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), - announcementPresenter: Presenter = Presenter { anAnnouncementState() }, - spaceAnnouncementPresenter: Presenter = Presenter { aSpaceAnnouncementState() }, + announcementPresenter: AnnouncementPresenter = AnnouncementPresenter(announcementStore), ) = DefaultAnnouncementService( announcementStore = announcementStore, announcementPresenter = announcementPresenter, - spaceAnnouncementPresenter = spaceAnnouncementPresenter, ) } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/fullscreen/FullscreenAnnouncementViewTest.kt similarity index 51% rename from features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt rename to features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/fullscreen/FullscreenAnnouncementViewTest.kt index ad3d83f1b5..b69037e61a 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementViewTest.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/fullscreen/FullscreenAnnouncementViewTest.kt @@ -6,12 +6,16 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.announcement.impl.spaces +package io.element.android.features.announcement.impl.fullscreen import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.announcement.api.Announcement +import io.element.android.features.announcement.impl.AnnouncementEvent +import io.element.android.features.announcement.impl.AnnouncementState +import io.element.android.features.announcement.impl.anAnnouncementState import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.clickOn @@ -22,39 +26,41 @@ import org.junit.rules.TestRule import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) -class SpaceAnnouncementViewTest { +class FullscreenAnnouncementViewTest { @get:Rule val rule = createAndroidComposeRule() @Test - fun `clicking on back sends a SpaceAnnouncementEvents`() { - val eventsRecorder = EventsRecorder() - rule.setSpaceAnnouncementView( - aSpaceAnnouncementState( + fun `clicking on back sends a AnnouncementEvent`() { + val eventsRecorder = EventsRecorder() + rule.setFullscreenAnnouncementView( + anAnnouncementState( + announcement = Announcement.Fullscreen.Space, eventSink = eventsRecorder, ), ) rule.pressBackKey() - eventsRecorder.assertSingle(SpaceAnnouncementEvents.Continue) + eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space)) } @Test - fun `clicking on Continue sends a SpaceAnnouncementEvents`() { - val eventsRecorder = EventsRecorder() - rule.setSpaceAnnouncementView( - aSpaceAnnouncementState( + fun `clicking on Continue sends a AnnouncementEvent`() { + val eventsRecorder = EventsRecorder() + rule.setFullscreenAnnouncementView( + anAnnouncementState( + announcement = Announcement.Fullscreen.Space, eventSink = eventsRecorder, ), ) rule.clickOn(CommonStrings.action_continue) - eventsRecorder.assertSingle(SpaceAnnouncementEvents.Continue) + eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space)) } } -private fun AndroidComposeTestRule.setSpaceAnnouncementView( - state: SpaceAnnouncementState, +private fun AndroidComposeTestRule.setFullscreenAnnouncementView( + state: AnnouncementState, ) { setContent { - SpaceAnnouncementView( + FullscreenAnnouncementView( state = state, ) } diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt deleted file mode 100644 index 672f677407..0000000000 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementPresenterTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.announcement.impl.spaces - -import com.google.common.truth.Truth.assertThat -import io.element.android.features.announcement.api.Announcement -import io.element.android.features.announcement.impl.store.AnnouncementStatus -import io.element.android.features.announcement.impl.store.AnnouncementStore -import io.element.android.features.announcement.impl.store.InMemoryAnnouncementStore -import io.element.android.tests.testutils.test -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.test.runTest -import org.junit.Test - -class SpaceAnnouncementPresenterTest { - @Test - fun `present - when user continues, the store is updated`() = runTest { - val store = InMemoryAnnouncementStore() - val presenter = createSpaceAnnouncementPresenter( - announcementStore = store, - ) - presenter.test { - assertThat(store.announcementStatusFlow(Announcement.Space).first()).isEqualTo(AnnouncementStatus.NeverShown) - val state = awaitItem() - state.eventSink(SpaceAnnouncementEvents.Continue) - assertThat(store.announcementStatusFlow(Announcement.Space).first()).isEqualTo(AnnouncementStatus.Shown) - } - } -} - -private fun createSpaceAnnouncementPresenter( - announcementStore: AnnouncementStore = InMemoryAnnouncementStore(), -) = SpaceAnnouncementPresenter( - announcementStore = announcementStore, -) diff --git a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt index ab3e85124f..ed6dfec850 100644 --- a/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt +++ b/features/announcement/impl/src/test/kotlin/io/element/android/features/announcement/impl/store/InMemoryAnnouncementStore.kt @@ -14,10 +14,10 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow class InMemoryAnnouncementStore( - initialSpaceAnnouncementStatus: AnnouncementStatus = AnnouncementStatus.NeverShown, + initialFullscreenAnnouncementStatus: AnnouncementStatus = AnnouncementStatus.NeverShown, initialNewNotificationSoundAnnouncementStatus: AnnouncementStatus = AnnouncementStatus.NeverShown, ) : AnnouncementStore { - private val spaceAnnouncement = MutableStateFlow(initialSpaceAnnouncementStatus) + private val fullScreenAnnouncement = MutableStateFlow(initialFullscreenAnnouncementStatus) private val newNotificationSoundAnnouncement = MutableStateFlow(initialNewNotificationSoundAnnouncementStatus) override suspend fun setAnnouncementStatus(announcement: Announcement, status: AnnouncementStatus) { @@ -29,12 +29,12 @@ class InMemoryAnnouncementStore( } override suspend fun reset() { - spaceAnnouncement.value = AnnouncementStatus.NeverShown + fullScreenAnnouncement.value = AnnouncementStatus.NeverShown newNotificationSoundAnnouncement.value = AnnouncementStatus.NeverShown } private fun Announcement.toMutableStateFlow() = when (this) { - Announcement.Space -> spaceAnnouncement + is Announcement.Fullscreen -> fullScreenAnnouncement Announcement.NewNotificationSound -> newNotificationSoundAnnouncement } } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt index 5985e33127..1e49b1aa70 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt @@ -19,8 +19,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject -import io.element.android.features.announcement.api.Announcement -import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.roomlist.RoomListState import io.element.android.features.home.impl.spaces.HomeSpacesState import io.element.android.features.logout.api.direct.DirectLogoutState @@ -47,7 +45,6 @@ class HomePresenter( private val logoutPresenter: Presenter, private val rageshakeFeatureAvailability: RageshakeFeatureAvailability, private val sessionStore: SessionStore, - private val announcementService: AnnouncementService, ) : Presenter { private val currentUserWithNeighborsBuilder = CurrentUserWithNeighborsBuilder() @@ -82,10 +79,7 @@ class HomePresenter( fun handleEvent(event: HomeEvent) { when (event) { - is HomeEvent.SelectHomeNavigationBarItem -> coroutineState.launch { - if (event.item == HomeNavigationBarItem.Spaces) { - announcementService.showAnnouncement(Announcement.Space) - } + is HomeEvent.SelectHomeNavigationBarItem -> { currentHomeNavigationBarItemOrdinal = event.item.ordinal } is HomeEvent.SwitchToAccount -> coroutineState.launch { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt index 90cf160cc6..371a718523 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt @@ -9,14 +9,11 @@ package io.element.android.features.home.impl import com.google.common.truth.Truth.assertThat -import io.element.android.features.announcement.api.Announcement -import io.element.android.features.announcement.api.AnnouncementService 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.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.indicator.api.IndicatorService @@ -34,8 +31,6 @@ import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore import io.element.android.libraries.sessionstorage.test.aSessionData import io.element.android.tests.testutils.WarmUpRule -import io.element.android.tests.testutils.lambda.lambdaRecorder -import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -137,14 +132,10 @@ class HomePresenterTest { @Test fun `present - NavigationBar change`() = runTest { - val showAnnouncementResult = lambdaRecorder { } val presenter = createHomePresenter( sessionStore = InMemorySessionStore( updateUserProfileResult = { _, _, _ -> }, ), - announcementService = FakeAnnouncementService( - showAnnouncementResult = showAnnouncementResult, - ) ) presenter.test { val initialState = awaitItem() @@ -152,8 +143,6 @@ class HomePresenterTest { initialState.eventSink(HomeEvent.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces)) val finalState = awaitItem() assertThat(finalState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Spaces) - showAnnouncementResult.assertions().isCalledOnce() - .with(value(Announcement.Space)) } } } @@ -166,7 +155,6 @@ internal fun createHomePresenter( indicatorService: IndicatorService = FakeIndicatorService(), homeSpacesPresenter: Presenter = Presenter { aHomeSpacesState() }, sessionStore: SessionStore = InMemorySessionStore(), - announcementService: AnnouncementService = FakeAnnouncementService(), ) = HomePresenter( client = client, syncService = syncService, @@ -177,5 +165,4 @@ internal fun createHomePresenter( logoutPresenter = { aDirectLogoutState() }, rageshakeFeatureAvailability = rageshakeFeatureAvailability, sessionStore = sessionStore, - announcementService = announcementService, )