aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/app/passwordstore/ui/onboarding/activity/OnboardingActivity.kt2
-rw-r--r--app/src/main/java/app/passwordstore/ui/onboarding/fragments/KeySelectionFragment.kt51
-rw-r--r--app/src/main/java/app/passwordstore/ui/pgp/PGPKeyList.kt23
-rw-r--r--app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt40
-rw-r--r--app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt10
-rw-r--r--app/src/main/res/values/strings.xml4
6 files changed, 105 insertions, 25 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/onboarding/activity/OnboardingActivity.kt b/app/src/main/java/app/passwordstore/ui/onboarding/activity/OnboardingActivity.kt
index f5257530..ad609391 100644
--- a/app/src/main/java/app/passwordstore/ui/onboarding/activity/OnboardingActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/onboarding/activity/OnboardingActivity.kt
@@ -9,7 +9,9 @@ import android.os.Bundle
import androidx.activity.addCallback
import androidx.appcompat.app.AppCompatActivity
import app.passwordstore.R
+import dagger.hilt.android.AndroidEntryPoint
+@AndroidEntryPoint
class OnboardingActivity : AppCompatActivity(R.layout.activity_onboarding) {
override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/app/src/main/java/app/passwordstore/ui/onboarding/fragments/KeySelectionFragment.kt b/app/src/main/java/app/passwordstore/ui/onboarding/fragments/KeySelectionFragment.kt
index 43dc7f4c..b5facaf3 100644
--- a/app/src/main/java/app/passwordstore/ui/onboarding/fragments/KeySelectionFragment.kt
+++ b/app/src/main/java/app/passwordstore/ui/onboarding/fragments/KeySelectionFragment.kt
@@ -5,21 +5,68 @@
package app.passwordstore.ui.onboarding.fragments
+import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.edit
import androidx.fragment.app.Fragment
+import androidx.lifecycle.lifecycleScope
import app.passwordstore.R
+import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.databinding.FragmentKeySelectionBinding
+import app.passwordstore.injection.prefs.SettingsPreferences
+import app.passwordstore.ui.pgp.PGPKeyListActivity
+import app.passwordstore.util.coroutines.DispatcherProvider
+import app.passwordstore.util.extensions.commitChange
+import app.passwordstore.util.extensions.finish
+import app.passwordstore.util.extensions.snackbar
import app.passwordstore.util.extensions.viewBinding
+import app.passwordstore.util.settings.PreferenceKeys
+import com.google.android.material.snackbar.Snackbar
+import dagger.hilt.android.AndroidEntryPoint
+import java.io.File
+import javax.inject.Inject
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+@AndroidEntryPoint
class KeySelectionFragment : Fragment(R.layout.fragment_key_selection) {
+ @Inject @SettingsPreferences lateinit var settings: SharedPreferences
+ @Inject lateinit var dispatcherProvider: DispatcherProvider
private val binding by viewBinding(FragmentKeySelectionBinding::bind)
+ private val gpgKeySelectAction =
+ registerForActivityResult(StartActivityForResult()) { result ->
+ if (result.resultCode == AppCompatActivity.RESULT_OK) {
+ val data = result.data ?: return@registerForActivityResult
+ val selectedKey =
+ data.getStringExtra(PGPKeyListActivity.EXTRA_SELECTED_KEY)
+ ?: return@registerForActivityResult
+ lifecycleScope.launch {
+ withContext(dispatcherProvider.io()) {
+ val gpgIdentifierFile = File(PasswordRepository.getRepositoryDirectory(), ".gpg-id")
+ gpgIdentifierFile.writeText(selectedKey)
+ }
+ settings.edit { putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, true) }
+ requireActivity()
+ .commitChange(getString(R.string.git_commit_gpg_id, getString(R.string.app_name)))
+ finish()
+ }
+ } else {
+ requireActivity()
+ .snackbar(
+ message = getString(R.string.gpg_key_select_mandatory),
+ length = Snackbar.LENGTH_LONG,
+ )
+ }
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.selectKey.setOnClickListener {
- // TODO(msfjarvis): Restore this functionality
- // gpgKeySelectAction.launch(Intent(requireContext(), GetKeyIdsActivity::class.java))
+ gpgKeySelectAction.launch(PGPKeyListActivity.newSelectionActivity(requireContext()))
}
}
diff --git a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyList.kt b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyList.kt
index a67d0f32..34cc70a1 100644
--- a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyList.kt
+++ b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyList.kt
@@ -1,6 +1,7 @@
package app.passwordstore.ui.pgp
import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -28,12 +29,14 @@ import androidx.compose.ui.unit.dp
import app.passwordstore.R
import app.passwordstore.crypto.GpgIdentifier
import app.passwordstore.ui.compose.theme.APSThemePreview
+import app.passwordstore.util.extensions.conditional
@Composable
fun KeyList(
identifiers: List<GpgIdentifier>,
onItemClick: (identifier: GpgIdentifier) -> Unit,
modifier: Modifier = Modifier,
+ onKeySelected: ((identifier: GpgIdentifier) -> Unit)? = null,
) {
if (identifiers.isEmpty()) {
Column(
@@ -50,7 +53,7 @@ fun KeyList(
} else {
LazyColumn(modifier = modifier) {
items(identifiers) { identifier ->
- KeyItem(identifier = identifier, onItemClick = onItemClick)
+ KeyItem(identifier = identifier, onItemClick = onItemClick, onKeySelected = onKeySelected)
}
}
}
@@ -61,6 +64,7 @@ private fun KeyItem(
identifier: GpgIdentifier,
onItemClick: (identifier: GpgIdentifier) -> Unit,
modifier: Modifier = Modifier,
+ onKeySelected: ((identifier: GpgIdentifier) -> Unit)? = null,
) {
var isDeleting by remember { mutableStateOf(false) }
DeleteConfirmationDialog(
@@ -77,16 +81,21 @@ private fun KeyItem(
is GpgIdentifier.UserId -> identifier.email
}
Row(
- modifier = modifier.padding(16.dp).fillMaxWidth(),
+ modifier =
+ modifier.padding(16.dp).fillMaxWidth().conditional(onKeySelected != null) {
+ clickable { onKeySelected?.invoke(identifier) }
+ },
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = label)
- IconButton(onClick = { isDeleting = true }) {
- Icon(
- painter = painterResource(R.drawable.ic_delete_24dp),
- stringResource(id = R.string.delete)
- )
+ if (onKeySelected == null) {
+ IconButton(onClick = { isDeleting = true }) {
+ Icon(
+ painter = painterResource(R.drawable.ic_delete_24dp),
+ stringResource(id = R.string.delete)
+ )
+ }
}
}
}
diff --git a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt
index 6916e28b..6a65daaf 100644
--- a/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/pgp/PGPKeyListActivity.kt
@@ -1,5 +1,6 @@
package app.passwordstore.ui.pgp
+import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
@@ -12,12 +13,10 @@ import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
-import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.lifecycle.viewmodel.compose.viewModel
import app.passwordstore.R
import app.passwordstore.ui.APSAppBar
import app.passwordstore.ui.compose.theme.APSTheme
@@ -39,6 +38,7 @@ class PGPKeyListActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ val isSelecting = intent.extras?.getBoolean(EXTRA_KEY_SELECTION) ?: false
setContent {
val context = LocalContext.current
APSTheme(colors = decideColorScheme(context)) {
@@ -62,21 +62,33 @@ class PGPKeyListActivity : ComponentActivity() {
}
}
) { paddingValues ->
- PGPKeyList(viewModel = viewModel, modifier = Modifier.padding(paddingValues))
+ KeyList(
+ identifiers = viewModel.keys,
+ onItemClick = viewModel::deleteKey,
+ modifier = Modifier.padding(paddingValues),
+ onKeySelected =
+ if (isSelecting) {
+ { identifier ->
+ val result = Intent()
+ result.putExtra(EXTRA_SELECTED_KEY, identifier.toString())
+ setResult(RESULT_OK, result)
+ finish()
+ }
+ } else null,
+ )
}
}
}
}
-}
-@Composable
-fun PGPKeyList(
- modifier: Modifier = Modifier,
- viewModel: PGPKeyListViewModel = viewModel(),
-) {
- KeyList(
- identifiers = viewModel.keys,
- onItemClick = viewModel::deleteKey,
- modifier = modifier,
- )
+ companion object {
+ const val EXTRA_SELECTED_KEY = "SELECTED_KEY"
+ private const val EXTRA_KEY_SELECTION = "KEY_SELECTION_MODE"
+
+ fun newSelectionActivity(context: Context): Intent {
+ val intent = Intent(context, PGPKeyListActivity::class.java)
+ intent.putExtra(EXTRA_KEY_SELECTION, true)
+ return intent
+ }
+ }
}
diff --git a/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt b/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt
index d3e840c7..a780163d 100644
--- a/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt
+++ b/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt
@@ -22,6 +22,7 @@ import android.view.View
import android.view.autofill.AutofillManager
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
+import androidx.compose.ui.Modifier
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.fragment.app.FragmentActivity
@@ -153,3 +154,12 @@ fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int): Ap
@Suppress("DEPRECATION") getApplicationInfo(packageName, flags)
}
}
+
+/** Allows conditionally applying the given [modifier] if [isEnabled] is `true`. */
+fun Modifier.conditional(isEnabled: Boolean, modifier: Modifier.() -> Modifier): Modifier {
+ return if (isEnabled) {
+ then(modifier())
+ } else {
+ this
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c5569929..f3e2dbd0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -43,6 +43,7 @@
<string name="git_commit_remove_text">Remove %1$s from store.</string>
<string name="git_commit_move_text">Rename %1$s to %2$s.</string>
<string name="git_commit_move_multiple_text">Move multiple passwords to %1$s.</string>
+ <string name="git_commit_gpg_id">Initialize GPG IDs in %1$s.</string>
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copied to clipboard</string>
@@ -318,9 +319,8 @@
<string name="git_break_out_of_detached_success">There was a conflict when trying to rebase. Your local %1$s branch was pushed to another branch named %2$s\n Use this branch to resolve conflict on your computer</string>
<string name="git_break_out_of_detached_unneeded">The repository is not rebasing, no need to push to another branch</string>
- <!-- OpenKeychain not installed -->
-
<!-- GPG key selection in folder creation -->
+ <string name="gpg_key_select_mandatory">Selecting a GPG key is necessary to proceed</string>
<string name="folder_creation_err_file_exists">A file by that name already exists</string>
<string name="folder_creation_err_folder_exists">A folder by that name already exists</string>