Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:56:56 +01:00
parent 75dc487a7a
commit 39c29d175b
6317 changed files with 388324 additions and 2 deletions

View file

@ -0,0 +1,27 @@
plugins {
id(ThunderbirdPlugins.Library.androidCompose)
}
android {
namespace = "app.k9mail.feature.launcher"
resourcePrefix = "launcher_"
}
dependencies {
implementation(projects.core.ui.compose.designsystem)
implementation(projects.legacy.ui.base)
implementation(projects.feature.onboarding.main)
implementation(projects.feature.settings.import)
implementation(projects.feature.account.edit)
implementation(projects.feature.account.settings.api)
implementation(projects.feature.account.setup)
implementation(projects.feature.funding.api)
implementation(libs.androidx.activity.compose)
testImplementation(projects.core.ui.compose.testing)
implementation(projects.feature.debugSettings)
}

View 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>

View file

@ -0,0 +1,36 @@
package app.k9mail.feature.launcher
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import app.k9mail.feature.launcher.ui.FeatureLauncherApp
import com.fsck.k9.ui.base.K9Activity
class FeatureLauncherActivity : K9Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FeatureLauncherApp()
}
}
companion object {
@JvmStatic
fun launch(context: Context, target: FeatureLauncherTarget) {
val intent = getIntent(context, target)
context.startActivity(intent)
}
@JvmStatic
fun getIntent(context: Context, target: FeatureLauncherTarget): Intent {
return Intent(context, FeatureLauncherActivity::class.java).apply {
data = target.deepLinkUri
if (target.flags != null) {
flags = target.flags
}
}
}
}
}

View file

@ -0,0 +1,11 @@
package app.k9mail.feature.launcher
/**
* Contract defining the external functionality of the feature launcher to be provided by the host application.
*/
interface FeatureLauncherExternalContract {
fun interface AccountSetupFinishedLauncher {
fun launch(accountUuid: String?)
}
}

View file

@ -0,0 +1,45 @@
package app.k9mail.feature.launcher
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import app.k9mail.feature.account.edit.navigation.AccountEditRoute
import app.k9mail.feature.account.setup.navigation.AccountSetupRoute
import app.k9mail.feature.funding.api.FundingRoute
import app.k9mail.feature.onboarding.main.navigation.OnboardingRoute
import net.thunderbird.feature.account.settings.api.AccountSettingsRoute
import net.thunderbird.feature.debug.settings.navigation.SecretDebugSettingsRoute
sealed class FeatureLauncherTarget(
val deepLinkUri: Uri,
val flags: Int? = null,
) {
data class AccountEditIncomingSettings(val accountUuid: String) : FeatureLauncherTarget(
deepLinkUri = AccountEditRoute.IncomingServerSettings(accountUuid).route().toUri(),
)
data class AccountEditOutgoingSettings(val accountUuid: String) : FeatureLauncherTarget(
deepLinkUri = AccountEditRoute.OutgoingServerSettings(accountUuid).route().toUri(),
)
data object AccountSetup : FeatureLauncherTarget(
deepLinkUri = AccountSetupRoute.AccountSetup().route().toUri(),
)
data class AccountSettings(val accountUuid: String) : FeatureLauncherTarget(
deepLinkUri = AccountSettingsRoute.GeneralSettings(accountUuid).route().toUri(),
)
data object Funding : FeatureLauncherTarget(
deepLinkUri = FundingRoute.Contribution.route().toUri(),
)
data object Onboarding : FeatureLauncherTarget(
deepLinkUri = OnboardingRoute.Onboarding().route().toUri(),
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK,
)
data object SecretDebugSettings : FeatureLauncherTarget(
deepLinkUri = SecretDebugSettingsRoute.Notification.route().toUri(),
)
}

View file

@ -0,0 +1,18 @@
package app.k9mail.feature.launcher.di
import app.k9mail.feature.account.edit.featureAccountEditModule
import app.k9mail.feature.account.setup.featureAccountSetupModule
import app.k9mail.feature.onboarding.main.featureOnboardingModule
import app.k9mail.feature.settings.import.featureSettingsImportModule
import net.thunderbird.feature.debug.settings.inject.featureDebugSettingsModule
import org.koin.dsl.module
val featureLauncherModule = module {
includes(
featureOnboardingModule,
featureSettingsImportModule,
featureAccountSetupModule,
featureAccountEditModule,
featureDebugSettingsModule,
)
}

View file

@ -0,0 +1,89 @@
package app.k9mail.feature.launcher.navigation
import androidx.activity.ComponentActivity
import androidx.activity.compose.LocalActivity
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import app.k9mail.feature.account.edit.navigation.AccountEditNavigation
import app.k9mail.feature.account.setup.navigation.AccountSetupNavigation
import app.k9mail.feature.account.setup.navigation.AccountSetupRoute
import app.k9mail.feature.funding.api.FundingNavigation
import app.k9mail.feature.launcher.FeatureLauncherExternalContract.AccountSetupFinishedLauncher
import app.k9mail.feature.onboarding.main.navigation.OnboardingNavigation
import app.k9mail.feature.onboarding.main.navigation.OnboardingRoute
import net.thunderbird.feature.account.settings.api.AccountSettingsNavigation
import net.thunderbird.feature.debug.settings.navigation.SecretDebugSettingsNavigation
import org.koin.compose.koinInject
@Composable
fun FeatureLauncherNavHost(
navController: NavHostController,
onBack: () -> Unit,
modifier: Modifier = Modifier,
accountSetupFinishedLauncher: AccountSetupFinishedLauncher = koinInject(),
accountEditNavigation: AccountEditNavigation = koinInject(),
accountSettingsNavigation: AccountSettingsNavigation = koinInject(),
accountSetupNavigation: AccountSetupNavigation = koinInject(),
onboardingNavigation: OnboardingNavigation = koinInject(),
fundingNavigation: FundingNavigation = koinInject(),
secretDebugSettingsNavigation: SecretDebugSettingsNavigation = koinInject(),
) {
val activity = LocalActivity.current as ComponentActivity
NavHost(
navController = navController,
startDestination = OnboardingRoute.Onboarding(),
modifier = modifier,
) {
onboardingNavigation.registerRoutes(
navGraphBuilder = this,
onBack = onBack,
onFinish = {
when (it) {
is OnboardingRoute.Onboarding -> {
accountSetupFinishedLauncher.launch(it.accountId)
activity.finish()
}
}
},
)
accountSetupNavigation.registerRoutes(
navGraphBuilder = this,
onBack = onBack,
onFinish = {
when (it) {
is AccountSetupRoute.AccountSetup -> {
accountSetupFinishedLauncher.launch(it.accountId)
}
}
},
)
accountEditNavigation.registerRoutes(
navGraphBuilder = this,
onBack = onBack,
onFinish = { activity.finish() },
)
accountSettingsNavigation.registerRoutes(
navGraphBuilder = this,
onBack = onBack,
onFinish = { onBack() },
)
fundingNavigation.registerRoutes(
navGraphBuilder = this,
onBack = onBack,
onFinish = { onBack() },
)
secretDebugSettingsNavigation.registerRoutes(
navGraphBuilder = this,
onBack = onBack,
onFinish = { onBack() },
)
}
}

View file

@ -0,0 +1,37 @@
package app.k9mail.feature.launcher.ui
import androidx.activity.ComponentActivity
import androidx.activity.compose.LocalActivity
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.Surface
import app.k9mail.feature.launcher.navigation.FeatureLauncherNavHost
import net.thunderbird.core.ui.theme.api.FeatureThemeProvider
import org.koin.compose.koinInject
@Composable
fun FeatureLauncherApp(
modifier: Modifier = Modifier,
themeProvider: FeatureThemeProvider = koinInject<FeatureThemeProvider>(),
) {
val navController = rememberNavController()
themeProvider.WithTheme {
Surface(
modifier = Modifier
.fillMaxSize()
.safeDrawingPadding()
.then(modifier),
) {
val activity = LocalActivity.current as ComponentActivity
FeatureLauncherNavHost(
navController = navController,
onBack = { activity.finish() },
)
}
}
}