aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-02 20:50:22 +0100
committerDanilo M. <danix@danix.xyz>2026-11-02 20:50:22 +0100
commit2b9a095cbf4720f056532bded1be9f2584f8447a (patch)
tree58c2224d23a646352de7f72467555afaf70bffcb /app/src/main/java
parent4a011721261bd46da3e84d443154d8e360494ece (diff)
downloadHardenedPass-2b9a095cbf4720f056532bded1be9f2584f8447a.tar.gz
HardenedPass-2b9a095cbf4720f056532bded1be9f2584f8447a.zip
feat(app): add the single-activity Compose host
Its two routes hand off to the legacy list and decrypt activities until those screens are ported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/app/passwordstore/ui/main/MainActivity.kt77
1 files changed, 77 insertions, 0 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/main/MainActivity.kt b/app/src/main/java/app/passwordstore/ui/main/MainActivity.kt
new file mode 100644
index 00000000..018deae3
--- /dev/null
+++ b/app/src/main/java/app/passwordstore/ui/main/MainActivity.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package app.passwordstore.ui.main
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.fragment.app.FragmentActivity
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import androidx.navigation.toRoute
+import app.passwordstore.data.repo.PasswordRepository
+import app.passwordstore.ui.compose.theme.APSTheme
+import app.passwordstore.ui.crypto.BasePGPActivity
+import app.passwordstore.ui.crypto.DecryptActivity
+import app.passwordstore.ui.passwords.PasswordStore
+import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.serialization.Serializable
+
+/** The password list, at the store root. */
+@Serializable data object ListRoute
+
+/** One entry. [filePath] was checked with [LaunchActivity.isFileInRepo] before routing here. */
+@Serializable data class EntryRoute(val filePath: String)
+
+/**
+ * Single-activity host for the Compose UI. Not exported: it is only started by [LaunchActivity],
+ * after its biometric gate and path check. Extends [FragmentActivity] only because BiometricPrompt
+ * needs one; it hosts no fragments.
+ */
+@AndroidEntryPoint
+class MainActivity : FragmentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val filePath = intent.getStringExtra(BasePGPActivity.EXTRA_FILE_PATH)
+ val start: Any = if (filePath != null) EntryRoute(filePath) else ListRoute
+ setContent {
+ APSTheme {
+ NavHost(rememberNavController(), startDestination = start) {
+ composable<ListRoute> {
+ LegacyScreen(
+ Intent(this@MainActivity, PasswordStore::class.java).setAction(Intent.ACTION_VIEW)
+ )
+ }
+ composable<EntryRoute> { entry ->
+ val route = entry.toRoute<EntryRoute>()
+ LegacyScreen(
+ Intent(this@MainActivity, DecryptActivity::class.java)
+ .putExtra(BasePGPActivity.EXTRA_FILE_PATH, route.filePath)
+ .putExtra(
+ BasePGPActivity.EXTRA_REPO_PATH,
+ PasswordRepository.getRepositoryDirectory().absolutePath,
+ )
+ )
+ }
+ }
+ }
+ }
+ }
+
+ // ponytail: trampoline to a screen not yet ported; each port replaces one call with the
+ // real composable, and the last port deletes this function.
+ @Composable
+ private fun LegacyScreen(intent: Intent) {
+ LaunchedEffect(Unit) {
+ startActivity(intent)
+ finish()
+ }
+ }
+}