Change last onboarding step

This commit is contained in:
Rafał Kobyłko 2023-10-21 20:44:25 +02:00
parent 225c623177
commit 77ff6c5d05
9 changed files with 83 additions and 105 deletions

View File

@ -52,7 +52,6 @@ import com.twofasapp.feature.home.ui.services.focus.FocusServiceModal
import com.twofasapp.feature.home.ui.services.focus.FocusServiceModalNavArg
import com.twofasapp.feature.security.navigation.securityNavigation
import com.twofasapp.feature.security.ui.lock.LockActivity
import com.twofasapp.feature.startup.navigation.StartupBackupRoute
import com.twofasapp.feature.startup.navigation.StartupRoute
import com.twofasapp.feature.trash.navigation.DisposeRoute
import com.twofasapp.feature.trash.navigation.TrashRoute
@ -104,16 +103,13 @@ internal fun MainNavHost(
composable(Screen.Startup.route) {
StartupRoute(
openStartupBackup = {
openHome = {
navController.navigate(Screen.Services.route) { popUpTo(0) }
navController.navigate(Screen.StartupBackup.route) { popUpTo(Screen.Services.route) }
})
}
composable(Screen.StartupBackup.route) {
StartupBackupRoute(
openHome = { navController.popBackStack()},
openBackup = { navController.navigate(Screen.Backup.routeWithArgs(NavArg.TurnOnBackup to true)) { popUpTo(Screen.Services.route) } },
},
openBackup = {
navController.navigate(Screen.Services.route) { popUpTo(0) }
navController.navigate(Screen.Backup.routeWithArgs(NavArg.TurnOnBackup to true)) { popUpTo(Screen.Services.route) }
},
)
}

View File

@ -54,7 +54,7 @@ internal fun Project.applyKotlinAndroid(
)
}
packagingOptions {
packaging {
resources.excludes.add("META-INF/DEPENDENCIES")
resources.excludes.add("META-INF/LICENSE")
resources.excludes.add("META-INF/LICENSE.txt")

View File

@ -9,7 +9,6 @@ sealed class Screen(val route: String) {
}
data object Startup : Screen("startup")
data object StartupBackup : Screen("startup/backup")
data object Services : Screen("services")
data object Settings : Screen("settings")
data object EditService : Screen("services/{${NavArg.ServiceId.name}}")

View File

@ -47,7 +47,6 @@ class Strings(c: Context) {
val startupStepThreeBody = c.getString(R.string.introduction__page_3_content)
val startupStepFourHeader = c.getString(R.string.introduction__page_4_title)
val startupStepFourBody = c.getString(R.string.introduction__page_4_content_android)
val startupStartCta = c.getString(R.string.introduction__title)
val startupBackupBody = c.getString(R.string.introduction__backup_description)
val startupBackupSuccessMsg = c.getString(R.string.introduction__backup_success)
val startupBackupCloseCta = c.getString(R.string.introduction__backup_take_risk_cta)

View File

@ -2,21 +2,13 @@ package com.twofasapp.feature.startup.navigation
import androidx.compose.runtime.Composable
import com.twofasapp.feature.startup.ui.startup.StartupScreen
import com.twofasapp.feature.startup.ui.startupbackup.StartupBackupScreen
@Composable
fun StartupRoute(
openStartupBackup: () -> Unit
openHome: () -> Unit = {},
openBackup: () -> Unit = {},
) {
StartupScreen(openStartupBackup = openStartupBackup)
}
@Composable
fun StartupBackupRoute(
openHome: () -> Unit,
openBackup: () -> Unit,
) {
StartupBackupScreen(
StartupScreen(
openHome = openHome,
openBackup = openBackup,
)

View File

@ -32,6 +32,7 @@ import androidx.compose.ui.unit.dp
import com.google.accompanist.pager.HorizontalPagerIndicator
import com.twofasapp.designsystem.TwTheme
import com.twofasapp.designsystem.common.TwButton
import com.twofasapp.designsystem.common.TwTextButton
import com.twofasapp.designsystem.ktx.openSafely
import com.twofasapp.feature.startup.R
import com.twofasapp.locale.TwLocale
@ -40,24 +41,36 @@ import org.koin.androidx.compose.koinViewModel
@Composable
internal fun StartupScreen(
openHome: () -> Unit = {},
openBackup: () -> Unit = {},
viewModel: StartupViewModel = koinViewModel(),
openStartupBackup: () -> Unit
) {
val scope = rememberCoroutineScope()
ScreenContent(
onStartUsingClick = {
viewModel.onStartUsingClicked()
openStartupBackup()
openHome = {
scope.launch {
viewModel.finishOnboarding()
openHome()
}
},
openBackup = {
scope.launch {
viewModel.finishOnboarding()
openBackup()
}
}
)
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun ScreenContent(
onStartUsingClick: () -> Unit,
openHome: () -> Unit = {},
openBackup: () -> Unit = {},
) {
val scope = rememberCoroutineScope()
val pagerState = rememberPagerState(pageCount = { 4 })
val pagerState = rememberPagerState(pageCount = { 5 })
val uriHandler = LocalUriHandler.current
val context = LocalContext.current
@ -83,24 +96,36 @@ internal fun ScreenContent(
headerText = TwLocale.strings.startupStepOneHeader,
bodyText = TwLocale.strings.startupStepOneBody,
imageSize = 60.dp,
openHome = openHome,
)
1 -> Step(
image = painterResource(id = R.drawable.onboarding_step_two),
headerText = TwLocale.strings.startupStepTwoHeader,
bodyText = TwLocale.strings.startupStepTwoBody,
openHome = openHome,
)
2 -> Step(
image = painterResource(id = R.drawable.onboarding_step_three),
headerText = TwLocale.strings.startupStepThreeHeader,
bodyText = TwLocale.strings.startupStepThreeBody,
openHome = openHome,
)
3 -> Step(
image = painterResource(id = R.drawable.onboarding_step_four),
headerText = TwLocale.strings.startupStepFourHeader,
bodyText = TwLocale.strings.startupStepFourBody,
openHome = openHome,
)
4 -> Step(
image = painterResource(id = com.twofasapp.designsystem.R.drawable.illustration_2fas_backup),
headerText = null,
bodyText = TwLocale.strings.startupBackupBody,
showBackupSkip = true,
openHome = openHome,
)
}
}
@ -125,19 +150,19 @@ internal fun ScreenContent(
)
}
Spacer(modifier = Modifier.height(12.dp))
Spacer(modifier = Modifier.height(36.dp))
TwButton(
text = when (pagerState.currentPage) {
1 -> TwLocale.strings.commonNext
2 -> TwLocale.strings.commonNext
3 -> TwLocale.strings.startupStartCta
3 -> TwLocale.strings.commonNext
4 -> TwLocale.strings.commonContinue
else -> TwLocale.strings.commonContinue
},
modifier = Modifier.padding(vertical = 24.dp),
onClick = {
if (pagerState.canScrollForward.not()) {
onStartUsingClick()
openBackup()
}
scope.launch {
@ -145,6 +170,8 @@ internal fun ScreenContent(
}
}
)
Spacer(modifier = Modifier.height(16.dp))
}
}
}
@ -152,10 +179,12 @@ internal fun ScreenContent(
@Composable
private fun Step(
image: Painter,
headerText: String,
headerText: String?,
bodyText: String,
modifier: Modifier = Modifier,
imageSize: Dp = 220.dp,
imageSize: Dp = 180.dp,
showBackupSkip: Boolean = false,
openHome: () -> Unit = {},
) {
Column(
modifier = modifier,
@ -178,26 +207,37 @@ private fun Step(
Spacer(modifier = Modifier.height(24.dp))
// Header
Text(
text = headerText,
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
textAlign = TextAlign.Center
)
if (headerText != null) {
Text(
text = headerText,
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
textAlign = TextAlign.Center
)
}
Spacer(modifier = Modifier.height(16.dp))
// Body
Text(
text = bodyText,
style = MaterialTheme.typography.bodyMedium,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp),
textAlign = TextAlign.Center
)
if (showBackupSkip) {
Spacer(modifier = Modifier.height(16.dp))
TwTextButton(
text = TwLocale.strings.startupBackupCloseCta,
onClick = openHome,
)
}
}
}
}

View File

@ -1,16 +1,13 @@
package com.twofasapp.feature.startup.ui.startup
import androidx.lifecycle.ViewModel
import com.twofasapp.common.ktx.launchScoped
import com.twofasapp.data.session.SessionRepository
class StartupViewModel(
private val sessionRepository: SessionRepository
) : ViewModel() {
fun onStartUsingClicked() {
launchScoped {
sessionRepository.setOnboardingDisplayed(true)
}
suspend fun finishOnboarding() {
sessionRepository.setOnboardingDisplayed(true)
}
}

View File

@ -1,44 +0,0 @@
package com.twofasapp.feature.startup.ui.startupbackup
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.twofasapp.designsystem.TwTheme
import com.twofasapp.designsystem.screen.CommonContent
import com.twofasapp.locale.TwLocale
@Composable
internal fun StartupBackupScreen(
openHome: () -> Unit = {},
openBackup: () -> Unit = {},
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(TwTheme.color.background)
.padding(16.dp)
) {
CommonContent(
modifier = Modifier
.fillMaxSize(),
image = painterResource(id = com.twofasapp.designsystem.R.drawable.illustration_2fas_backup),
descriptionText = TwLocale.strings.startupBackupBody,
ctaPrimaryText = TwLocale.strings.commonContinue,
ctaSecondaryText = TwLocale.strings.startupBackupCloseCta,
ctaPrimaryClick = openBackup,
ctaSecondaryClick = openHome,
)
}
}
@Preview
@Composable
private fun Preview() {
StartupBackupScreen()
}

View File

@ -1,25 +1,24 @@
[versions]
accompanist = "0.32.0"
agp = "8.2.0-beta05"
appcompat = "1.6.1"
cameraX = "1.2.3"
agp = "8.2.0-beta06"
cameraX = "1.3.0"
coil = "2.4.0"
commonmark = "0.21.0"
compose = "1.5.1"
composeActivity = "1.7.2"
compose = "1.5.3"
composeActivity = "1.8.0"
composeCompiler = "1.5.3"
core = "1.12.0"
firebase = "32.3.1"
glance = "1.0.0"
junit = "4.13.2"
koin = "3.4.3"
koinAndroid = "3.4.6"
koin = "3.5.0"
koinAndroid = "3.5.0"
kotlin = "1.9.10"
kotlinCoroutines = "1.7.3"
kotlinKsp = "1.9.10-1.0.13"
ktor = "2.3.4"
lifecycle = "2.7.0-alpha02"
material3 = "1.2.0-alpha08"
material3 = "1.2.0-alpha09"
room = "2.5.2"
[libraries]
@ -29,7 +28,7 @@ accompanistPermissions = { module = "com.google.accompanist:accompanist-permissi
accompanistSystemUi = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
activityX = { module = "androidx.activity:activity-ktx", version.ref = "composeActivity" }
apacheCommonsCodec = "commons-codec:commons-codec:1.15"
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
appcompat = "androidx.appcompat:appcompat:1.6.1"
barcodeScanning = "com.google.mlkit:barcode-scanning:17.2.0"
biometric = "androidx.biometric:biometric:1.1.0"
camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraX" }
@ -45,7 +44,7 @@ composeActivity = { module = "androidx.activity:activity-compose", version.ref =
composeAnimation = { module = "androidx.compose.animation:animation", version.ref = "compose" }
composeCompiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" }
composeMaterial2 = { module = "androidx.compose.material:material", version.ref = "compose" }
composeNavigation = "androidx.navigation:navigation-compose:2.7.3"
composeNavigation = "androidx.navigation:navigation-compose:2.7.4"
composeUi = { module = "androidx.compose.ui:ui", version.ref = "compose" }
composeUiTooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
composeUiUtil = { module = "androidx.compose.ui:ui-util", version.ref = "compose" }
@ -82,7 +81,7 @@ lifecycleLifecycle = { module = "androidx.lifecycle:lifecycle-runtime-ktx", vers
lifecycleProcess = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle" }
lifecycleSavedstate = { module = "androidx.lifecycle:lifecycle-viewmodel-savedstate", version.ref = "lifecycle" }
lottie = "com.airbnb.android:lottie-compose:5.0.3"
material2 = { module = "com.google.android.material:material", version.ref = "appcompat" }
material2 = "com.google.android.material:material:1.10.0"
material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
material3Window = { module = "androidx.compose.material3:material3-window-size-class", version.ref = "material3" }
playReview = "com.google.android.play:review:2.0.1"