Merge pull request #7548 from thunderbird/settings_import_during_onboarding

Continue onboarding after settings import
This commit is contained in:
cketti 2024-01-25 12:33:27 +01:00 committed by GitHub
commit 6a47453465
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 111 additions and 90 deletions

View file

@ -7,7 +7,11 @@ import com.fsck.k9.activity.MessageList
class AccountSetupFinishedLauncher(
private val context: Context,
) : FeatureLauncherExternalContract.AccountSetupFinishedLauncher {
override fun launch(accountUuid: String) {
MessageList.launch(context, accountUuid)
override fun launch(accountUuid: String?) {
if (accountUuid != null) {
MessageList.launch(context, accountUuid)
} else {
MessageList.launch(context)
}
}
}

View file

@ -10,10 +10,4 @@ val featureModule = module {
context = androidContext(),
)
}
factory<FeatureLauncherExternalContract.ImportSettingsLauncher> {
ImportSettingsLauncher(
context = androidContext(),
)
}
}

View file

@ -1,18 +0,0 @@
package com.fsck.k9.feature
import android.content.Context
import android.content.Intent
import app.k9mail.feature.launcher.FeatureLauncherExternalContract
import com.fsck.k9.activity.FragmentLauncherActivity
class ImportSettingsLauncher(
private val context: Context,
) : FeatureLauncherExternalContract.ImportSettingsLauncher {
override fun launch() {
val intent = Intent(context, FragmentLauncherActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(FragmentLauncherActivity.EXTRA_FRAGMENT, FragmentLauncherActivity.FRAGMENT_IMPORT_SETTINGS)
}
context.startActivity(intent)
}
}

View file

@ -1,12 +1,10 @@
package com.fsck.k9.activity
import android.content.Intent
import android.os.Bundle
import app.k9mail.feature.settings.import.ui.SettingsImportFragment
import com.fsck.k9.ui.R
import com.fsck.k9.ui.base.K9Activity
import app.k9mail.feature.settings.importing.R as SettingsImportR
// Currently not used
class FragmentLauncherActivity : K9Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -14,40 +12,11 @@ class FragmentLauncherActivity : K9Activity() {
setLayout(R.layout.activity_fragment_launcher)
when (val fragment = intent.getStringExtra(EXTRA_FRAGMENT)) {
FRAGMENT_IMPORT_SETTINGS -> setupSettingsFragment()
else -> throw IllegalArgumentException("Unknown destination: $fragment")
}
}
private fun setupSettingsFragment() {
setTitle(SettingsImportR.string.settings_import_title)
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_launcher_container, SettingsImportFragment())
.commit()
supportFragmentManager.setFragmentResultListener(
SettingsImportFragment.FRAGMENT_RESULT_KEY,
this,
) { _, result: Bundle ->
if (result.getBoolean(SettingsImportFragment.FRAGMENT_RESULT_ACCOUNT_IMPORTED, false)) {
launchMessageList()
}
finish()
}
}
private fun launchMessageList() {
val intent = Intent(this, MessageList::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
startActivity(intent)
}
companion object {
const val EXTRA_FRAGMENT = "fragment"
const val FRAGMENT_IMPORT_SETTINGS = "import_settings"
}
}

View file

@ -3,10 +3,6 @@ package app.k9mail.feature.launcher
interface FeatureLauncherExternalContract {
fun interface AccountSetupFinishedLauncher {
fun launch(accountUuid: String)
}
fun interface ImportSettingsLauncher {
fun launch()
fun launch(accountUuid: String?)
}
}

View file

@ -8,7 +8,6 @@ import app.k9mail.core.ui.compose.common.activity.LocalActivity
import app.k9mail.feature.account.edit.navigation.accountEditRoute
import app.k9mail.feature.account.setup.navigation.accountSetupRoute
import app.k9mail.feature.launcher.FeatureLauncherExternalContract.AccountSetupFinishedLauncher
import app.k9mail.feature.launcher.FeatureLauncherExternalContract.ImportSettingsLauncher
import app.k9mail.feature.onboarding.main.navigation.NAVIGATION_ROUTE_ONBOARDING
import app.k9mail.feature.onboarding.main.navigation.onboardingRoute
import org.koin.compose.koinInject
@ -18,7 +17,6 @@ fun FeatureLauncherNavHost(
navController: NavHostController,
onBack: () -> Unit,
modifier: Modifier = Modifier,
importSettingsLauncher: ImportSettingsLauncher = koinInject(),
accountSetupFinishedLauncher: AccountSetupFinishedLauncher = koinInject(),
) {
val activity = LocalActivity.current
@ -29,8 +27,8 @@ fun FeatureLauncherNavHost(
modifier = modifier,
) {
onboardingRoute(
onImport = { importSettingsLauncher.launch() },
) { accountUuid -> accountSetupFinishedLauncher.launch(accountUuid) }
onFinish = { accountUuid -> accountSetupFinishedLauncher.launch(accountUuid) },
)
accountSetupRoute(
onBack = onBack,
onFinish = { accountSetupFinishedLauncher.launch(it) },

View file

@ -20,5 +20,6 @@ dependencies {
implementation(projects.core.ui.compose.designsystem)
implementation(projects.feature.onboarding.welcome)
implementation(projects.feature.account.setup)
implementation(projects.feature.settings.import)
implementation(projects.feature.onboarding.permissions)
}

View file

@ -6,7 +6,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.navigation.NavController
import androidx.navigation.NavOptionsBuilder
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
@ -14,24 +13,33 @@ import app.k9mail.feature.account.setup.navigation.AccountSetupNavHost
import app.k9mail.feature.onboarding.permissions.domain.PermissionsDomainContract.UseCase.HasRuntimePermissions
import app.k9mail.feature.onboarding.permissions.ui.PermissionsScreen
import app.k9mail.feature.onboarding.welcome.ui.WelcomeScreen
import app.k9mail.feature.settings.import.ui.SettingsImportScreen
import org.koin.compose.koinInject
private const val NESTED_NAVIGATION_ROUTE_WELCOME = "welcome"
private const val NESTED_NAVIGATION_ROUTE_ACCOUNT_SETUP = "account_setup"
private const val NESTED_NAVIGATION_ROUTE_SETTINGS_IMPORT = "settings_import"
private const val NESTED_NAVIGATION_ROUTE_PERMISSIONS = "permissions"
private fun NavController.navigateToAccountSetup() {
navigate(NESTED_NAVIGATION_ROUTE_ACCOUNT_SETUP)
}
private fun NavController.navigateToPermissions(builder: NavOptionsBuilder.() -> Unit) {
navigate(NESTED_NAVIGATION_ROUTE_PERMISSIONS, builder)
private fun NavController.navigateToSettingsImport() {
navigate(NESTED_NAVIGATION_ROUTE_SETTINGS_IMPORT)
}
private fun NavController.navigateToPermissions() {
navigate(NESTED_NAVIGATION_ROUTE_PERMISSIONS) {
popUpTo(NESTED_NAVIGATION_ROUTE_WELCOME) {
inclusive = true
}
}
}
@Composable
fun OnboardingNavHost(
onImport: () -> Unit,
onFinish: (String) -> Unit,
onFinish: (String?) -> Unit,
hasRuntimePermissions: HasRuntimePermissions = koinInject(),
) {
val navController = rememberNavController()
@ -44,7 +52,7 @@ fun OnboardingNavHost(
composable(route = NESTED_NAVIGATION_ROUTE_WELCOME) {
WelcomeScreen(
onStartClick = { navController.navigateToAccountSetup() },
onImportClick = onImport,
onImportClick = { navController.navigateToSettingsImport() },
)
}
@ -54,11 +62,7 @@ fun OnboardingNavHost(
onFinish = { createdAccountUuid: String ->
accountUuid = createdAccountUuid
if (hasRuntimePermissions()) {
navController.navigateToPermissions {
popUpTo(NESTED_NAVIGATION_ROUTE_WELCOME) {
inclusive = true
}
}
navController.navigateToPermissions()
} else {
onFinish(createdAccountUuid)
}
@ -66,9 +70,22 @@ fun OnboardingNavHost(
)
}
composable(route = NESTED_NAVIGATION_ROUTE_SETTINGS_IMPORT) {
SettingsImportScreen(
onImportSuccess = {
if (hasRuntimePermissions()) {
navController.navigateToPermissions()
} else {
onFinish(null)
}
},
onBack = { navController.popBackStack() },
)
}
composable(route = NESTED_NAVIGATION_ROUTE_PERMISSIONS) {
PermissionsScreen(
onNext = { onFinish(requireNotNull(accountUuid)) },
onNext = { onFinish(accountUuid) },
)
}
}

View file

@ -1,25 +1,15 @@
package app.k9mail.feature.onboarding.main.navigation
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import app.k9mail.core.ui.compose.common.navigation.deepLinkComposable
const val NAVIGATION_ROUTE_ONBOARDING = "onboarding"
fun NavController.navigateToOnboarding(
navOptions: NavOptions? = null,
) {
navigate(NAVIGATION_ROUTE_ONBOARDING, navOptions)
}
fun NavGraphBuilder.onboardingRoute(
onImport: () -> Unit,
onFinish: (String) -> Unit,
onFinish: (String?) -> Unit,
) {
deepLinkComposable(route = NAVIGATION_ROUTE_ONBOARDING) {
OnboardingNavHost(
onImport = onImport,
onFinish = onFinish,
)
}

View file

@ -21,6 +21,7 @@ android {
dependencies {
implementation(projects.app.core)
implementation(projects.app.ui.base)
implementation(projects.core.ui.compose.designsystem)
implementation(projects.feature.account.oauth)
implementation(libs.appauth)

View file

@ -0,0 +1,69 @@
package app.k9mail.feature.settings.import.ui
import android.os.Bundle
import androidx.compose.foundation.layout.PaddingValues
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.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.FragmentActivity
import app.k9mail.core.ui.compose.common.activity.LocalActivity
import app.k9mail.core.ui.compose.common.fragment.FragmentView
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
import app.k9mail.core.ui.compose.designsystem.organism.TopAppBar
import app.k9mail.core.ui.compose.designsystem.template.Scaffold
import app.k9mail.core.ui.compose.theme.Icons
import app.k9mail.feature.settings.importing.R
@Composable
fun SettingsImportScreen(
onImportSuccess: () -> Unit,
onBack: () -> Unit,
modifier: Modifier = Modifier,
) {
Scaffold(
topBar = {
TopAppBar(
title = stringResource(R.string.settings_import_title),
navigationIcon = {
ButtonIcon(
onClick = onBack,
imageVector = Icons.Outlined.arrowBack,
)
},
)
},
modifier = modifier,
) { innerPadding ->
SettingsImportContent(onImportSuccess, onBack, innerPadding)
}
}
@Composable
private fun SettingsImportContent(
onImportSuccess: () -> Unit,
onBack: () -> Unit,
paddingValues: PaddingValues,
) {
val activity = LocalActivity.current as FragmentActivity
activity.supportFragmentManager.setFragmentResultListener(
SettingsImportFragment.FRAGMENT_RESULT_KEY,
LocalLifecycleOwner.current,
) { _, result: Bundle ->
if (result.getBoolean(SettingsImportFragment.FRAGMENT_RESULT_ACCOUNT_IMPORTED, false)) {
onImportSuccess()
} else {
onBack()
}
}
FragmentView(
fragmentFactory = { SettingsImportFragment() },
modifier = Modifier
.fillMaxSize()
.padding(paddingValues),
)
}