diff --git a/changelog.d/2584.misc b/changelog.d/2584.misc new file mode 100644 index 0000000000..de85b9d90f --- /dev/null +++ b/changelog.d/2584.misc @@ -0,0 +1 @@ +Remove Welcome screen from the FTUE. diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt index 983e0c8db2..652b6dddd4 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt @@ -36,7 +36,6 @@ import io.element.android.features.ftue.api.FtueEntryPoint import io.element.android.features.ftue.impl.notifications.NotificationsOptInNode import io.element.android.features.ftue.impl.state.DefaultFtueState import io.element.android.features.ftue.impl.state.FtueStep -import io.element.android.features.ftue.impl.welcome.WelcomeNode import io.element.android.features.lockscreen.api.LockScreenEntryPoint import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode @@ -73,9 +72,6 @@ class FtueFlowNode @AssistedInject constructor( @Parcelize data object Placeholder : NavTarget - @Parcelize - data object WelcomeScreen : NavTarget - @Parcelize data object NotificationsOptIn : NavTarget @@ -110,15 +106,6 @@ class FtueFlowNode @AssistedInject constructor( NavTarget.Placeholder -> { createNode(buildContext) } - NavTarget.WelcomeScreen -> { - val callback = object : WelcomeNode.Callback { - override fun onContinueClicked() { - ftueState.setWelcomeScreenShown() - lifecycleScope.launch { moveToNextStep() } - } - } - createNode(buildContext, listOf(callback)) - } NavTarget.NotificationsOptIn -> { val callback = object : NotificationsOptInNode.Callback { override fun onNotificationsOptInFinished() { @@ -146,9 +133,6 @@ class FtueFlowNode @AssistedInject constructor( private fun moveToNextStep() { when (ftueState.getNextStep()) { - FtueStep.WelcomeScreen -> { - backstack.newRoot(NavTarget.WelcomeScreen) - } FtueStep.NotificationsOptIn -> { backstack.newRoot(NavTarget.NotificationsOptIn) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt index ce7a769187..f1a1c84545 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt @@ -21,7 +21,6 @@ import android.os.Build import androidx.annotation.VisibleForTesting import com.squareup.anvil.annotations.ContributesBinding import io.element.android.features.ftue.api.state.FtueState -import io.element.android.features.ftue.impl.welcome.state.WelcomeScreenState import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.libraries.di.SessionScope import io.element.android.libraries.permissions.api.PermissionStateProvider @@ -40,14 +39,12 @@ class DefaultFtueState @Inject constructor( private val sdkVersionProvider: BuildVersionSdkIntProvider, coroutineScope: CoroutineScope, private val analyticsService: AnalyticsService, - private val welcomeScreenState: WelcomeScreenState, private val permissionStateProvider: PermissionStateProvider, private val lockScreenService: LockScreenService, ) : FtueState { override val shouldDisplayFlow = MutableStateFlow(isAnyStepIncomplete()) override suspend fun reset() { - welcomeScreenState.reset() analyticsService.reset() if (sdkVersionProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { permissionStateProvider.resetPermission(Manifest.permission.POST_NOTIFICATIONS) @@ -62,12 +59,7 @@ class DefaultFtueState @Inject constructor( fun getNextStep(currentStep: FtueStep? = null): FtueStep? = when (currentStep) { - null -> if (shouldDisplayWelcomeScreen()) { - FtueStep.WelcomeScreen - } else { - getNextStep(FtueStep.WelcomeScreen) - } - FtueStep.WelcomeScreen -> if (shouldAskNotificationPermissions()) { + null -> if (shouldAskNotificationPermissions()) { FtueStep.NotificationsOptIn } else { getNextStep(FtueStep.NotificationsOptIn) @@ -87,7 +79,6 @@ class DefaultFtueState @Inject constructor( private fun isAnyStepIncomplete(): Boolean { return listOf( - { shouldDisplayWelcomeScreen() }, { shouldAskNotificationPermissions() }, { needsAnalyticsOptIn() }, { shouldDisplayLockscreenSetup() }, @@ -99,10 +90,6 @@ class DefaultFtueState @Inject constructor( return runBlocking { analyticsService.didAskUserConsent().first().not() } } - private fun shouldDisplayWelcomeScreen(): Boolean { - return welcomeScreenState.isWelcomeScreenNeeded() - } - private fun shouldAskNotificationPermissions(): Boolean { return if (sdkVersionProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { val permission = Manifest.permission.POST_NOTIFICATIONS @@ -120,11 +107,6 @@ class DefaultFtueState @Inject constructor( } } - fun setWelcomeScreenShown() { - welcomeScreenState.setWelcomeScreenShown() - updateState() - } - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun updateState() { shouldDisplayFlow.value = isAnyStepIncomplete() @@ -132,7 +114,6 @@ class DefaultFtueState @Inject constructor( } sealed interface FtueStep { - data object WelcomeScreen : FtueStep data object NotificationsOptIn : FtueStep data object AnalyticsOptIn : FtueStep data object LockscreenSetup : FtueStep diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt index 834aaa5c1f..1f0b817850 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt @@ -20,7 +20,6 @@ import android.os.Build import com.google.common.truth.Truth.assertThat import io.element.android.features.ftue.impl.state.DefaultFtueState import io.element.android.features.ftue.impl.state.FtueStep -import io.element.android.features.ftue.impl.welcome.state.FakeWelcomeState import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.features.lockscreen.test.FakeLockScreenService import io.element.android.libraries.permissions.impl.FakePermissionStateProvider @@ -47,7 +46,6 @@ class DefaultFtueStateTests { @Test fun `given all checks being true, should display flow is false`() = runTest { - val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() val permissionStateProvider = FakePermissionStateProvider(permissionGranted = true) val lockScreenService = FakeLockScreenService() @@ -55,13 +53,11 @@ class DefaultFtueStateTests { val state = createState( coroutineScope = coroutineScope, - welcomeState = welcomeState, analyticsService = analyticsService, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, ) - welcomeState.setWelcomeScreenShown() analyticsService.setDidAskUserConsent() permissionStateProvider.setPermissionGranted() lockScreenService.setIsPinSetup(true) @@ -75,7 +71,6 @@ class DefaultFtueStateTests { @Test fun `traverse flow`() = runTest { - val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() val permissionStateProvider = FakePermissionStateProvider(permissionGranted = false) val lockScreenService = FakeLockScreenService() @@ -83,26 +78,21 @@ class DefaultFtueStateTests { val state = createState( coroutineScope = coroutineScope, - welcomeState = welcomeState, analyticsService = analyticsService, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, ) val steps = mutableListOf() - // First step, welcome screen - steps.add(state.getNextStep(steps.lastOrNull())) - welcomeState.setWelcomeScreenShown() - - // Second step, notifications opt in + // Notifications opt in steps.add(state.getNextStep(steps.lastOrNull())) permissionStateProvider.setPermissionGranted() - // Third step, entering PIN code + // Entering PIN code steps.add(state.getNextStep(steps.lastOrNull())) lockScreenService.setIsPinSetup(true) - // Fourth step, analytics opt in + // Analytics opt in steps.add(state.getNextStep(steps.lastOrNull())) analyticsService.setDidAskUserConsent() @@ -110,7 +100,6 @@ class DefaultFtueStateTests { steps.add(state.getNextStep(steps.lastOrNull())) assertThat(steps).containsExactly( - FtueStep.WelcomeScreen, FtueStep.NotificationsOptIn, FtueStep.LockscreenSetup, FtueStep.AnalyticsOptIn, @@ -135,15 +124,14 @@ class DefaultFtueStateTests { lockScreenService = lockScreenService, ) - // Skip first 3 steps - state.setWelcomeScreenShown() + // Skip first 2 steps permissionStateProvider.setPermissionGranted() lockScreenService.setIsPinSetup(true) assertThat(state.getNextStep()).isEqualTo(FtueStep.AnalyticsOptIn) analyticsService.setDidAskUserConsent() - assertThat(state.getNextStep(FtueStep.WelcomeScreen)).isNull() + assertThat(state.getNextStep(null)).isNull() // Cleanup coroutineScope.cancel() @@ -162,14 +150,12 @@ class DefaultFtueStateTests { lockScreenService = lockScreenService, ) - assertThat(state.getNextStep()).isEqualTo(FtueStep.WelcomeScreen) - state.setWelcomeScreenShown() lockScreenService.setIsPinSetup(true) assertThat(state.getNextStep()).isEqualTo(FtueStep.AnalyticsOptIn) analyticsService.setDidAskUserConsent() - assertThat(state.getNextStep(FtueStep.WelcomeScreen)).isNull() + assertThat(state.getNextStep(null)).isNull() // Cleanup coroutineScope.cancel() @@ -177,7 +163,6 @@ class DefaultFtueStateTests { private fun createState( coroutineScope: CoroutineScope, - welcomeState: FakeWelcomeState = FakeWelcomeState(), analyticsService: AnalyticsService = FakeAnalyticsService(), permissionStateProvider: FakePermissionStateProvider = FakePermissionStateProvider(permissionGranted = false), lockScreenService: LockScreenService = FakeLockScreenService(), @@ -187,7 +172,6 @@ class DefaultFtueStateTests { sdkVersionProvider = FakeBuildVersionSdkIntProvider(sdkIntVersion), coroutineScope = coroutineScope, analyticsService = analyticsService, - welcomeScreenState = welcomeState, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, )