Merge pull request #7037 from thundernest/add_feature_launcher
Add feature launcher
This commit is contained in:
commit
0c1921539f
21 changed files with 231 additions and 68 deletions
|
@ -5,7 +5,6 @@ import app.k9mail.feature.account.setup.AccountSetupExternalContract
|
|||
import app.k9mail.feature.account.setup.featureAccountSetupModule
|
||||
import app.k9mail.feature.preview.account.AccountCreator
|
||||
import app.k9mail.feature.preview.account.AccountOwnerNameProvider
|
||||
import app.k9mail.feature.preview.account.AccountSetupFinishedLauncher
|
||||
import app.k9mail.feature.preview.auth.AndroidKeyStoreDirectoryProvider
|
||||
import app.k9mail.feature.preview.auth.AppOAuthConfigurationFactory
|
||||
import app.k9mail.feature.preview.auth.DefaultTrustedSocketFactory
|
||||
|
@ -13,27 +12,15 @@ import com.fsck.k9.mail.ssl.KeyStoreDirectoryProvider
|
|||
import com.fsck.k9.mail.ssl.LocalKeyStore
|
||||
import com.fsck.k9.mail.ssl.TrustManagerFactory
|
||||
import com.fsck.k9.mail.ssl.TrustedSocketFactory
|
||||
import okhttp3.OkHttpClient
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
|
||||
val accountModule: Module = module {
|
||||
factory<AccountSetupExternalContract.AccountOwnerNameProvider> { AccountOwnerNameProvider() }
|
||||
factory<AccountSetupExternalContract.AccountCreator> { AccountCreator() }
|
||||
factory<AccountSetupExternalContract.AccountSetupFinishedLauncher> {
|
||||
AccountSetupFinishedLauncher(
|
||||
context = androidContext(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val featureModule: Module = module {
|
||||
// TODO move to network module
|
||||
single<OkHttpClient> {
|
||||
OkHttpClient()
|
||||
}
|
||||
|
||||
single<OAuthConfigurationFactory> { AppOAuthConfigurationFactory() }
|
||||
|
||||
factory<KeyStoreDirectoryProvider> { AndroidKeyStoreDirectoryProvider(context = get()) }
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package app.k9mail.feature.preview.account
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import app.k9mail.feature.account.setup.AccountSetupExternalContract
|
||||
|
||||
class AccountSetupFinishedLauncher(
|
||||
private val context: Context,
|
||||
) : AccountSetupExternalContract.AccountSetupFinishedLauncher {
|
||||
override suspend fun launch(accountUuid: String) {
|
||||
Toast.makeText(context, "AccountSetupFinishedLauncher.launch($accountUuid)", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
|
@ -17,6 +17,9 @@ dependencies {
|
|||
implementation(projects.backend.pop3)
|
||||
debugImplementation(projects.backend.demo)
|
||||
|
||||
implementation(projects.feature.launcher)
|
||||
|
||||
// TODO remove account setup dependency
|
||||
implementation(projects.feature.account.setup)
|
||||
|
||||
implementation(libs.androidx.appcompat)
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.fsck.k9.backends.backendsModule
|
|||
import com.fsck.k9.controller.ControllerExtension
|
||||
import com.fsck.k9.crypto.EncryptionExtractor
|
||||
import com.fsck.k9.crypto.openpgp.OpenPgpEncryptionExtractor
|
||||
import com.fsck.k9.feature.featureModule
|
||||
import com.fsck.k9.notification.notificationModule
|
||||
import com.fsck.k9.preferences.K9StoragePersister
|
||||
import com.fsck.k9.preferences.StoragePersister
|
||||
|
@ -44,4 +45,5 @@ val appModules = listOf(
|
|||
backendsModule,
|
||||
storageModule,
|
||||
newAccountModule,
|
||||
featureModule,
|
||||
)
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.fsck.k9.account
|
|||
|
||||
import app.k9mail.feature.account.setup.AccountSetupExternalContract
|
||||
import org.koin.android.ext.koin.androidApplication
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
val newAccountModule = module {
|
||||
|
@ -20,11 +19,4 @@ val newAccountModule = module {
|
|||
context = androidApplication(),
|
||||
)
|
||||
}
|
||||
|
||||
factory<AccountSetupExternalContract.AccountSetupFinishedLauncher> {
|
||||
AccountSetupFinishedLauncher(
|
||||
context = androidContext(),
|
||||
preferences = get(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package com.fsck.k9.account
|
||||
|
||||
import android.content.Context
|
||||
import app.k9mail.feature.account.setup.AccountSetupExternalContract
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.activity.MessageList
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class AccountSetupFinishedLauncher(
|
||||
private val context: Context,
|
||||
private val preferences: Preferences,
|
||||
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
|
||||
) : AccountSetupExternalContract.AccountSetupFinishedLauncher {
|
||||
override suspend fun launch(accountUuid: String) {
|
||||
val account = withContext(coroutineDispatcher) {
|
||||
preferences.getAccount(accountUuid)
|
||||
}
|
||||
|
||||
if (account == null) {
|
||||
MessageList.launch(context)
|
||||
} else {
|
||||
MessageList.launch(context, account)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.fsck.k9.feature
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import app.k9mail.feature.launcher.FeatureLauncherExternalContract
|
||||
import com.fsck.k9.activity.MessageList
|
||||
|
||||
class AccountSetupFinishedLauncher(
|
||||
private val context: Context,
|
||||
) : FeatureLauncherExternalContract.AccountSetupFinishedLauncher {
|
||||
override fun launch(accountUuid: String) {
|
||||
val intent = Intent(context, MessageList::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
putExtra(MessageList.EXTRA_ACCOUNT, accountUuid)
|
||||
}
|
||||
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.fsck.k9.feature
|
||||
|
||||
import app.k9mail.feature.launcher.FeatureLauncherExternalContract
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
val featureModule = module {
|
||||
factory<FeatureLauncherExternalContract.AccountSetupFinishedLauncher> {
|
||||
AccountSetupFinishedLauncher(
|
||||
context = androidContext(),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -10,9 +10,11 @@ dependencies {
|
|||
implementation(projects.feature.autodiscovery.providersxml)
|
||||
implementation(projects.mail.common)
|
||||
implementation(projects.uiUtils.toolbarBottomSheet)
|
||||
|
||||
implementation(projects.feature.launcher)
|
||||
// TODO: Remove AccountOauth dependency
|
||||
implementation(projects.feature.account.oauth)
|
||||
|
||||
// Remove AccountSetupIncoming's dependency on these
|
||||
compileOnly(projects.mail.protocols.imap)
|
||||
|
||||
implementation(projects.plugins.openpgpApiLib.openpgpApi)
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.fsck.k9
|
|||
|
||||
import app.k9mail.autodiscovery.providersxml.autodiscoveryProvidersXmlModule
|
||||
import app.k9mail.feature.account.oauth.featureAccountOAuthModule
|
||||
import app.k9mail.feature.launcher.di.featureLauncherModule
|
||||
import com.fsck.k9.account.accountModule
|
||||
import com.fsck.k9.activity.activityModule
|
||||
import com.fsck.k9.contacts.contactsModule
|
||||
|
@ -42,4 +43,5 @@ val uiModules = listOf(
|
|||
messageDetailsUiModule,
|
||||
messageViewUiModule,
|
||||
identityUiModule,
|
||||
featureLauncherModule,
|
||||
)
|
||||
|
|
|
@ -28,6 +28,7 @@ import androidx.fragment.app.commit
|
|||
import androidx.fragment.app.commitNow
|
||||
import app.k9mail.core.android.common.contact.CachingRepository
|
||||
import app.k9mail.core.android.common.contact.ContactRepository
|
||||
import app.k9mail.feature.launcher.FeatureLauncherActivity
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.K9
|
||||
import com.fsck.k9.K9.SplitViewMode
|
||||
|
@ -153,7 +154,12 @@ open class MessageList :
|
|||
deleteIncompleteAccounts(accounts)
|
||||
val hasAccountSetup = accounts.any { it.isFinishedSetup }
|
||||
if (!hasAccountSetup) {
|
||||
OnboardingActivity.launch(this)
|
||||
val useNewOnboarding = false
|
||||
if (useNewOnboarding) {
|
||||
FeatureLauncherActivity.launchOnboarding(this)
|
||||
} else {
|
||||
OnboardingActivity.launch(this)
|
||||
}
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
@ -1392,7 +1398,7 @@ open class MessageList :
|
|||
private const val ACTION_SHORTCUT = "shortcut"
|
||||
private const val EXTRA_SPECIAL_FOLDER = "special_folder"
|
||||
|
||||
private const val EXTRA_ACCOUNT = "account_uuid"
|
||||
const val EXTRA_ACCOUNT = "account_uuid"
|
||||
private const val EXTRA_MESSAGE_REFERENCE = "message_reference"
|
||||
private const val EXTRA_MESSAGE_VIEW_ONLY = "message_view_only"
|
||||
|
||||
|
|
|
@ -16,8 +16,4 @@ interface AccountSetupExternalContract {
|
|||
fun interface AccountOwnerNameProvider {
|
||||
suspend fun getOwnerName(): String?
|
||||
}
|
||||
|
||||
fun interface AccountSetupFinishedLauncher {
|
||||
suspend fun launch(accountUuid: String)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,17 @@ import app.k9mail.feature.account.setup.ui.outgoing.AccountOutgoingConfigViewMod
|
|||
import com.fsck.k9.mail.store.imap.ImapServerSettingsValidator
|
||||
import com.fsck.k9.mail.store.pop3.Pop3ServerSettingsValidator
|
||||
import com.fsck.k9.mail.transport.smtp.SmtpServerSettingsValidator
|
||||
import okhttp3.OkHttpClient
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
|
||||
val featureAccountSetupModule: Module = module {
|
||||
|
||||
single<OkHttpClient> {
|
||||
OkHttpClient()
|
||||
}
|
||||
|
||||
single<AutoDiscoveryService> {
|
||||
RealAutoDiscoveryService(
|
||||
okHttpClient = get(),
|
||||
|
|
25
feature/launcher/build.gradle.kts
Normal file
25
feature/launcher/build.gradle.kts
Normal file
|
@ -0,0 +1,25 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.Library.androidCompose)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "app.k9mail.feature.launcher"
|
||||
resourcePrefix = "launcher_"
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
manifestPlaceholders["appAuthRedirectScheme"] = "FIXME: override this in your app project"
|
||||
}
|
||||
release {
|
||||
manifestPlaceholders["appAuthRedirectScheme"] = "FIXME: override this in your app project"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.core.ui.compose.designsystem)
|
||||
implementation(projects.feature.onboarding)
|
||||
implementation(projects.feature.account.setup)
|
||||
|
||||
testImplementation(projects.core.ui.compose.testing)
|
||||
}
|
13
feature/launcher/src/main/AndroidManifest.xml
Normal file
13
feature/launcher/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application android:supportsRtl="true">
|
||||
|
||||
<activity
|
||||
android:name=".FeatureLauncherActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,49 @@
|
|||
package app.k9mail.feature.launcher
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.core.view.WindowCompat
|
||||
import app.k9mail.feature.account.setup.navigation.NAVIGATION_ROUTE_ACCOUNT_SETUP
|
||||
import app.k9mail.feature.launcher.ui.FeatureLauncherApp
|
||||
import app.k9mail.feature.onboarding.navigation.NAVIGATION_ROUTE_ONBOARDING
|
||||
|
||||
class FeatureLauncherActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
val destination = intent.getStringExtra(EXTRA_DESTINATION)
|
||||
|
||||
setContent {
|
||||
FeatureLauncherApp(startDestination = destination)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_DESTINATION = "destination"
|
||||
private const val DESTINATION_ONBOARDING = NAVIGATION_ROUTE_ONBOARDING
|
||||
private const val DESTINATION_SETUP_ACCOUNT = NAVIGATION_ROUTE_ACCOUNT_SETUP
|
||||
|
||||
@JvmStatic
|
||||
fun launchOnboarding(context: Activity) {
|
||||
val intent = Intent(context, FeatureLauncherActivity::class.java).apply {
|
||||
putExtra(EXTRA_DESTINATION, DESTINATION_ONBOARDING)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
}
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun launchSetupAccount(context: Activity) {
|
||||
val intent = Intent(context, FeatureLauncherActivity::class.java).apply {
|
||||
putExtra(EXTRA_DESTINATION, DESTINATION_SETUP_ACCOUNT)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package app.k9mail.feature.launcher
|
||||
|
||||
interface FeatureLauncherExternalContract {
|
||||
|
||||
fun interface AccountSetupFinishedLauncher {
|
||||
fun launch(accountUuid: String)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package app.k9mail.feature.launcher.di
|
||||
|
||||
import app.k9mail.feature.account.setup.featureAccountSetupModule
|
||||
import org.koin.dsl.module
|
||||
|
||||
val featureLauncherModule = module {
|
||||
includes(
|
||||
featureAccountSetupModule,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package app.k9mail.feature.launcher.navigation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import app.k9mail.feature.account.setup.navigation.accountSetupRoute
|
||||
import app.k9mail.feature.account.setup.navigation.navigateToAccountSetup
|
||||
import app.k9mail.feature.launcher.FeatureLauncherExternalContract.AccountSetupFinishedLauncher
|
||||
import app.k9mail.feature.onboarding.navigation.NAVIGATION_ROUTE_ONBOARDING
|
||||
import app.k9mail.feature.onboarding.navigation.onboardingRoute
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
fun FeatureLauncherNavHost(
|
||||
navController: NavHostController,
|
||||
startDestination: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
accountSetupFinishedLauncher: AccountSetupFinishedLauncher = koinInject(),
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = startDestination ?: NAVIGATION_ROUTE_ONBOARDING,
|
||||
modifier = modifier,
|
||||
) {
|
||||
onboardingRoute(
|
||||
onStart = { navController.navigateToAccountSetup() },
|
||||
onImport = { /* TODO */ },
|
||||
)
|
||||
accountSetupRoute(
|
||||
onBack = navController::popBackStack,
|
||||
onFinish = { accountSetupFinishedLauncher.launch(it) },
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package app.k9mail.feature.launcher.ui
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Background
|
||||
import app.k9mail.core.ui.compose.theme.K9Theme
|
||||
import app.k9mail.feature.launcher.navigation.FeatureLauncherNavHost
|
||||
|
||||
@Composable
|
||||
fun FeatureLauncherApp(
|
||||
startDestination: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
|
||||
K9Theme {
|
||||
Background(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.safeDrawingPadding()
|
||||
.then(modifier),
|
||||
) {
|
||||
FeatureLauncherNavHost(
|
||||
navController = navController,
|
||||
startDestination = startDestination,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ include(
|
|||
)
|
||||
|
||||
include(
|
||||
":feature:launcher",
|
||||
":feature:account:setup",
|
||||
":feature:account:oauth",
|
||||
":feature:onboarding",
|
||||
|
|
Loading…
Reference in a new issue