aboutsummaryrefslogtreecommitdiffstats
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rw-r--r--app/src/main/AndroidManifest.xml9
-rw-r--r--app/src/main/java/app/passwordstore/injection/pwgen/DicewareModule.kt3
-rw-r--r--app/src/main/java/app/passwordstore/ui/adapters/PasswordItemRecyclerAdapter.kt99
-rw-r--r--app/src/main/java/app/passwordstore/ui/crypto/BasePGPActivity.kt8
-rw-r--r--app/src/main/java/app/passwordstore/ui/crypto/EditPasswordScreen.kt105
-rw-r--r--app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt510
-rw-r--r--app/src/main/java/app/passwordstore/ui/dialogs/DicewarePasswordGeneratorDialogFragment.kt90
-rw-r--r--app/src/main/java/app/passwordstore/ui/dialogs/OtpImportDialogFragment.kt47
-rw-r--r--app/src/main/java/app/passwordstore/ui/dialogs/PasswordGeneratorDialogFragment.kt148
-rw-r--r--app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderActivity.kt51
-rw-r--r--app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderFragment.kt98
-rw-r--r--app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt7
-rw-r--r--app/src/main/res/drawable/ic_done_24dp.xml15
-rw-r--r--app/src/main/res/drawable/ic_save_24dp.xml15
-rw-r--r--app/src/main/res/drawable/ic_save_copy_24dp.xml15
-rw-r--r--app/src/main/res/layout/fragment_manual_otp_entry.xml53
-rw-r--r--app/src/main/res/layout/fragment_pwgen.xml115
-rw-r--r--app/src/main/res/layout/fragment_pwgen_diceware.xml73
-rw-r--r--app/src/main/res/layout/password_creation_activity.xml147
-rw-r--r--app/src/main/res/layout/password_recycler_view.xml38
-rw-r--r--app/src/main/res/layout/password_row_layout.xml50
-rw-r--r--app/src/main/res/layout/select_folder_layout.xml16
-rw-r--r--app/src/main/res/menu/pgp_handler_new_password.xml20
-rw-r--r--app/src/main/res/menu/pgp_handler_select_folder.xml15
-rw-r--r--app/src/main/res/values-de/strings.xml8
-rw-r--r--app/src/main/res/values-fr/strings.xml8
-rw-r--r--app/src/main/res/values-gl/strings.xml8
-rw-r--r--app/src/main/res/values-it/strings.xml8
-rw-r--r--app/src/main/res/values-ko-rKR/strings.xml8
-rw-r--r--app/src/main/res/values-pl-rPL/strings.xml8
-rw-r--r--app/src/main/res/values-pt-rBR/strings.xml8
-rw-r--r--app/src/main/res/values-ru/strings.xml8
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml8
-rw-r--r--app/src/main/res/values/strings.xml8
34 files changed, 2 insertions, 1825 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4859c0e..0429b2ac 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -95,12 +95,6 @@
android:label="@string/action_settings"
android:parentActivityName=".ui.main.MainActivity" />
- <activity
- android:name=".ui.crypto.PasswordCreationActivity"
- android:exported="false"
- android:label="@string/new_password_title"
- android:windowSoftInputMode="adjustResize" />
-
<service
android:name=".util.services.ClipboardService"
android:exported="false"
@@ -124,9 +118,6 @@
</service>
<activity
- android:name=".ui.folderselect.SelectFolderActivity"
- android:exported="false" />
- <activity
android:name=".ui.sshkeygen.SshKeyImportActivity"
android:exported="false"
android:theme="@style/NoBackgroundThemeM3"
diff --git a/app/src/main/java/app/passwordstore/injection/pwgen/DicewareModule.kt b/app/src/main/java/app/passwordstore/injection/pwgen/DicewareModule.kt
index 8572e3b8..c9c4e928 100644
--- a/app/src/main/java/app/passwordstore/injection/pwgen/DicewareModule.kt
+++ b/app/src/main/java/app/passwordstore/injection/pwgen/DicewareModule.kt
@@ -13,7 +13,6 @@ import app.passwordstore.passgen.diceware.RandomIntGenerator
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
-import dagger.hilt.android.components.FragmentComponent
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import java.io.InputStream
@@ -21,7 +20,7 @@ import java.security.SecureRandom
import javax.inject.Qualifier
@Module
-@InstallIn(FragmentComponent::class, ViewModelComponent::class)
+@InstallIn(ViewModelComponent::class)
object DicewareModule {
@Provides
diff --git a/app/src/main/java/app/passwordstore/ui/adapters/PasswordItemRecyclerAdapter.kt b/app/src/main/java/app/passwordstore/ui/adapters/PasswordItemRecyclerAdapter.kt
deleted file mode 100644
index 54be64d6..00000000
--- a/app/src/main/java/app/passwordstore/ui/adapters/PasswordItemRecyclerAdapter.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package app.passwordstore.ui.adapters
-
-import android.text.SpannableString
-import android.text.style.RelativeSizeSpan
-import android.view.MotionEvent
-import android.view.View
-import androidx.appcompat.widget.AppCompatImageView
-import androidx.appcompat.widget.AppCompatTextView
-import androidx.recyclerview.selection.ItemDetailsLookup
-import androidx.recyclerview.selection.Selection
-import androidx.recyclerview.widget.RecyclerView
-import app.passwordstore.R
-import app.passwordstore.data.password.PasswordItem
-import app.passwordstore.util.coroutines.DispatcherProvider
-import app.passwordstore.util.viewmodel.SearchableRepositoryAdapter
-import app.passwordstore.util.viewmodel.stableId
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.withContext
-
-open class PasswordItemRecyclerAdapter(
- coroutineScope: CoroutineScope,
- dispatcherProvider: DispatcherProvider,
-) :
- SearchableRepositoryAdapter<PasswordItemRecyclerAdapter.PasswordItemViewHolder>(
- R.layout.password_row_layout,
- ::PasswordItemViewHolder,
- coroutineScope,
- dispatcherProvider,
- PasswordItemViewHolder::bind,
- ) {
-
- fun makeSelectable(recyclerView: RecyclerView) {
- makeSelectable(recyclerView, ::PasswordItemDetailsLookup)
- }
-
- override fun onItemClicked(
- listener: (holder: PasswordItemViewHolder, item: PasswordItem) -> Unit
- ): PasswordItemRecyclerAdapter {
- return super.onItemClicked(listener) as PasswordItemRecyclerAdapter
- }
-
- override fun onSelectionChanged(
- listener: (selection: Selection<String>) -> Unit
- ): PasswordItemRecyclerAdapter {
- return super.onSelectionChanged(listener) as PasswordItemRecyclerAdapter
- }
-
- class PasswordItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
-
- private val name: AppCompatTextView = itemView.findViewById(R.id.label)
- private val childCount: AppCompatTextView = itemView.findViewById(R.id.child_count)
- private val folderIndicator: AppCompatImageView = itemView.findViewById(R.id.folder_indicator)
- var itemDetails: ItemDetailsLookup.ItemDetails<String>? = null
-
- suspend fun bind(item: PasswordItem, dispatcherProvider: DispatcherProvider) {
- val parentPath = item.fullPathToParent.replace("(^/)|(/$)".toRegex(), "")
- val source =
- if (parentPath.isNotEmpty()) {
- "$parentPath\n$item"
- } else {
- "$item"
- }
- val spannable = SpannableString(source)
- spannable.setSpan(RelativeSizeSpan(0.7f), 0, parentPath.length, 0)
- name.text = spannable
- if (item.type == PasswordItem.TYPE_CATEGORY) {
- folderIndicator.visibility = View.VISIBLE
- val count =
- withContext(dispatcherProvider.io()) {
- item.file.listFiles { path -> path.isDirectory || path.extension == "gpg" }?.size ?: 0
- }
- childCount.visibility = if (count > 0) View.VISIBLE else View.GONE
- childCount.text = "$count"
- } else {
- childCount.visibility = View.GONE
- folderIndicator.visibility = View.GONE
- }
- itemDetails =
- object : ItemDetailsLookup.ItemDetails<String>() {
- override fun getPosition() = absoluteAdapterPosition
-
- override fun getSelectionKey() = item.stableId
- }
- }
- }
-
- class PasswordItemDetailsLookup(private val recyclerView: RecyclerView) :
- ItemDetailsLookup<String>() {
-
- override fun getItemDetails(event: MotionEvent): ItemDetails<String>? {
- val view = recyclerView.findChildViewUnder(event.x, event.y) ?: return null
- return (recyclerView.getChildViewHolder(view) as PasswordItemViewHolder).itemDetails
- }
- }
-}
diff --git a/app/src/main/java/app/passwordstore/ui/crypto/BasePGPActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/BasePGPActivity.kt
index ba49a62c..ccd3bf08 100644
--- a/app/src/main/java/app/passwordstore/ui/crypto/BasePGPActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/crypto/BasePGPActivity.kt
@@ -29,7 +29,6 @@ import app.passwordstore.util.extensions.clipboard
import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.sharedPrefs
import app.passwordstore.util.extensions.snackbar
-import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.services.ClipboardService
import app.passwordstore.util.settings.Constants
import app.passwordstore.util.settings.PreferenceKeys
@@ -44,12 +43,6 @@ import kotlinx.coroutines.withContext
@AndroidEntryPoint
open class BasePGPActivity : AppCompatActivity() {
- /** Full path to the repository */
- val repoPath by unsafeLazy { intent.getStringExtra("REPO_PATH")!! }
-
- /** Full path to the password file being worked on */
- val fullPath by unsafeLazy { intent.getStringExtra("FILE_PATH")!! }
-
/** Action to invoke if [keyImportAction] succeeds. */
private var onKeyImport: (() -> Unit)? = null
private val keyImportAction =
@@ -103,7 +96,6 @@ open class BasePGPActivity : AppCompatActivity() {
companion object {
const val EXTRA_FILE_PATH = "FILE_PATH"
- const val EXTRA_REPO_PATH = "REPO_PATH"
/** Gets the relative path to the repository */
fun getRelativePath(fullPath: String, repositoryPath: String): String =
diff --git a/app/src/main/java/app/passwordstore/ui/crypto/EditPasswordScreen.kt b/app/src/main/java/app/passwordstore/ui/crypto/EditPasswordScreen.kt
deleted file mode 100644
index d8610307..00000000
--- a/app/src/main/java/app/passwordstore/ui/crypto/EditPasswordScreen.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.ui.crypto
-
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
-import androidx.compose.material3.TextField
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import app.passwordstore.R
-import app.passwordstore.data.passfile.PasswordEntry
-import app.passwordstore.ui.APSAppBar
-import app.passwordstore.ui.compose.PasswordField
-import app.passwordstore.ui.compose.theme.APSTheme
-import app.passwordstore.ui.compose.theme.SpacingLarge
-import app.passwordstore.ui.compose.theme.SpacingMedium
-import app.passwordstore.util.time.UserClock
-import app.passwordstore.util.totp.UriTotpFinder
-
-/** Composable to show allow editing an existing [PasswordEntry]. */
-@Composable
-fun EditPasswordScreen(
- entryName: String,
- entry: PasswordEntry,
- onNavigateUp: () -> Unit,
- @Suppress("UNUSED_PARAMETER") onSave: (PasswordEntry) -> Unit,
- modifier: Modifier = Modifier,
-) {
- Scaffold(
- topBar = {
- APSAppBar(
- title = entryName,
- navigationIcon = painterResource(R.drawable.ic_arrow_back_black_24dp),
- onNavigationIconClick = onNavigateUp,
- backgroundColor = MaterialTheme.colorScheme.surface,
- )
- }
- ) { paddingValues ->
- Box(modifier = modifier.padding(paddingValues)) {
- Column(
- modifier =
- Modifier.padding(vertical = SpacingMedium, horizontal = SpacingLarge).fillMaxSize()
- ) {
- if (entry.password != null) {
- PasswordField(
- value = entry.password!!,
- label = stringResource(R.string.password),
- initialVisibility = false,
- modifier = Modifier.padding(bottom = SpacingMedium).fillMaxWidth(),
- )
- }
- ExtraContent(entry = entry)
- }
- }
- }
-}
-
-@Composable
-private fun ExtraContent(entry: PasswordEntry, modifier: Modifier = Modifier) {
- TextField(
- value = entry.extraContentString,
- onValueChange = {},
- label = { Text("Extra content") },
- modifier = modifier.fillMaxWidth(),
- )
-}
-
-@Preview
-@Composable
-private fun EditPasswordScreenPreview() {
- APSTheme {
- EditPasswordScreen(
- entryName = "Test Entry",
- entry = createTestEntry(),
- onNavigateUp = {},
- onSave = {},
- )
- }
-}
-
-private fun createTestEntry() =
- PasswordEntry(
- UserClock(),
- UriTotpFinder(),
- """
- |My Password
- |otpauth://totp/ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30
- |login: msfjarvis
- |URL: example.com
- """
- .trimMargin()
- .encodeToByteArray(),
- )
diff --git a/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt
deleted file mode 100644
index 7652c98e..00000000
--- a/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.ui.crypto
-
-import android.content.Context
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.graphics.Bitmap
-import android.graphics.ImageDecoder
-import android.os.Build
-import android.os.Bundle
-import android.provider.MediaStore
-import android.text.InputType
-import android.view.Menu
-import android.view.MenuItem
-import android.view.View
-import androidx.activity.result.contract.ActivityResultContracts
-import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
-import androidx.core.content.edit
-import androidx.core.view.isVisible
-import androidx.core.widget.doAfterTextChanged
-import androidx.lifecycle.lifecycleScope
-import app.passwordstore.R
-import app.passwordstore.data.passfile.PasswordEntry
-import app.passwordstore.databinding.PasswordCreationActivityBinding
-import app.passwordstore.ui.dialogs.DicewarePasswordGeneratorDialogFragment
-import app.passwordstore.ui.dialogs.OtpImportDialogFragment
-import app.passwordstore.ui.dialogs.PasswordGeneratorDialogFragment
-import app.passwordstore.util.autofill.AutofillPreferences
-import app.passwordstore.util.extensions.asLog
-import app.passwordstore.util.extensions.base64
-import app.passwordstore.util.extensions.commitChange
-import app.passwordstore.util.extensions.getString
-import app.passwordstore.util.extensions.isInsideRepository
-import app.passwordstore.util.extensions.snackbar
-import app.passwordstore.util.extensions.unsafeLazy
-import app.passwordstore.util.extensions.viewBinding
-import app.passwordstore.util.settings.DirectoryStructure
-import app.passwordstore.util.settings.PreferenceKeys
-import com.github.michaelbull.result.getOrElse
-import com.github.michaelbull.result.onFailure
-import com.github.michaelbull.result.onSuccess
-import com.github.michaelbull.result.runCatching
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.google.zxing.BinaryBitmap
-import com.google.zxing.LuminanceSource
-import com.google.zxing.RGBLuminanceSource
-import com.google.zxing.common.HybridBinarizer
-import com.google.zxing.integration.android.IntentIntegrator
-import com.google.zxing.integration.android.IntentIntegrator.QR_CODE
-import com.google.zxing.qrcode.QRCodeReader
-import dagger.hilt.android.AndroidEntryPoint
-import java.io.ByteArrayOutputStream
-import java.io.IOException
-import java.nio.file.Paths
-import javax.inject.Inject
-import kotlin.io.path.absolutePathString
-import kotlin.io.path.createDirectories
-import kotlin.io.path.deleteIfExists
-import kotlin.io.path.exists
-import kotlin.io.path.isSameFileAs
-import kotlin.io.path.nameWithoutExtension
-import kotlin.io.path.pathString
-import kotlin.io.path.relativeTo
-import kotlin.io.path.writeBytes
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import logcat.LogPriority.ERROR
-import logcat.asLog
-import logcat.logcat
-
-@AndroidEntryPoint
-class PasswordCreationActivity : BasePGPActivity() {
-
- private val binding by viewBinding(PasswordCreationActivityBinding::inflate)
- @Inject lateinit var passwordEntryFactory: PasswordEntry.Factory
-
- private val suggestedName by unsafeLazy { intent.getStringExtra(EXTRA_FILE_NAME) }
- private val suggestedUsername by unsafeLazy { intent.getStringExtra(EXTRA_USERNAME) }
- private val suggestedPass by unsafeLazy { intent.getStringExtra(EXTRA_PASSWORD) }
- private val suggestedExtra by unsafeLazy { intent.getStringExtra(EXTRA_EXTRA_CONTENT) }
- private val shouldGeneratePassword by unsafeLazy {
- intent.getBooleanExtra(EXTRA_GENERATE_PASSWORD, false)
- }
- private val editing by unsafeLazy { intent.getBooleanExtra(EXTRA_EDITING, false) }
- private var oldCategory: String? = null
- private var copy: Boolean = false
-
- private val otpImportAction =
- registerForActivityResult(StartActivityForResult()) { result ->
- if (result.resultCode == RESULT_OK) {
- binding.otpImportButton.isVisible = false
- val intentResult = IntentIntegrator.parseActivityResult(RESULT_OK, result.data)
- val contents = "${intentResult.contents}\n"
- val currentExtras = binding.extraContent.text.toString()
- if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
- binding.extraContent.append("\n$contents")
- else binding.extraContent.append(contents)
- snackbar(message = getString(R.string.otp_import_success))
- } else {
- snackbar(message = getString(R.string.otp_import_failure_generic))
- }
- }
-
- private val imageImportAction =
- registerForActivityResult(ActivityResultContracts.GetContent()) { imageUri ->
- if (imageUri == null) {
- snackbar(message = getString(R.string.otp_import_failure_no_selection))
- return@registerForActivityResult
- }
- val bitmap =
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- ImageDecoder.decodeBitmap(ImageDecoder.createSource(contentResolver, imageUri))
- .copy(Bitmap.Config.ARGB_8888, true)
- } else {
- @Suppress("DEPRECATION") MediaStore.Images.Media.getBitmap(contentResolver, imageUri)
- }
- val intArray = IntArray(bitmap.width * bitmap.height)
- // copy pixel data from the Bitmap into the 'intArray' array
- bitmap.getPixels(intArray, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
- val source: LuminanceSource = RGBLuminanceSource(bitmap.width, bitmap.height, intArray)
- val binaryBitmap = BinaryBitmap(HybridBinarizer(source))
-
- val reader = QRCodeReader()
- runCatching {
- val result = reader.decode(binaryBitmap)
- val text = result.text
- val currentExtras = binding.extraContent.text.toString()
- if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
- binding.extraContent.append("\n$text")
- else binding.extraContent.append(text)
- snackbar(message = getString(R.string.otp_import_success))
- binding.otpImportButton.isVisible = false
- }
- .onFailure { snackbar(message = getString(R.string.otp_import_failure_generic)) }
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
- title =
- if (editing) getString(R.string.edit_password) else getString(R.string.new_password_title)
- with(binding) {
- setContentView(root)
- generatePassword.setOnClickListener { generatePassword() }
- otpImportButton.setOnClickListener {
- supportFragmentManager.setFragmentResultListener(
- OTP_RESULT_REQUEST_KEY,
- this@PasswordCreationActivity,
- ) { requestKey, bundle ->
- if (requestKey == OTP_RESULT_REQUEST_KEY) {
- val contents = bundle.getString(RESULT)
- val currentExtras = binding.extraContent.text.toString()
- if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
- binding.extraContent.append("\n$contents")
- else binding.extraContent.append(contents)
- }
- }
- val hasCamera = packageManager?.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) == true
- if (hasCamera) {
- val items =
- arrayOf(
- getString(R.string.otp_import_qr_code),
- getString(R.string.otp_import_from_file),
- getString(R.string.otp_import_manual_entry),
- )
- MaterialAlertDialogBuilder(this@PasswordCreationActivity)
- .setItems(items) { _, index ->
- when (index) {
- 0 ->
- otpImportAction.launch(
- IntentIntegrator(this@PasswordCreationActivity)
- .setOrientationLocked(false)
- .setBeepEnabled(false)
- .setDesiredBarcodeFormats(QR_CODE)
- .createScanIntent()
- )
- 1 -> imageImportAction.launch("image/*")
- 2 -> OtpImportDialogFragment().show(supportFragmentManager, "OtpImport")
- }
- }
- .show()
- } else {
- OtpImportDialogFragment().show(supportFragmentManager, "OtpImport")
- }
- }
-
- directoryInputLayout.apply {
- if (suggestedName != null || suggestedPass != null || shouldGeneratePassword) {
- isEnabled = true
- } else {
- setBackgroundColor(getColor(android.R.color.transparent))
- }
- val path = getRelativePath(fullPath, repoPath)
- // Keep empty path field visible if it is editable.
- if (path.isEmpty() && !isEnabled) visibility = View.GONE
- else {
- directory.setText(path)
- oldCategory = path
- }
- }
- if (suggestedName != null) {
- filename.setText(suggestedName)
- } else {
- filename.requestFocus()
- }
-
- if (
- AutofillPreferences.directoryStructure(this@PasswordCreationActivity) ==
- DirectoryStructure.EncryptedUsername || suggestedUsername != null
- ) {
- usernameInputLayout.visibility = View.VISIBLE
- if (suggestedUsername != null) username.setText(suggestedUsername)
- else if (suggestedName != null) username.requestFocus()
- }
-
- // Allow the user to quickly switch between storing the username as the filename or
- // in the encrypted extras. This only makes sense if the directory structure is
- // FileBased.
- if (
- suggestedName == null &&
- AutofillPreferences.directoryStructure(this@PasswordCreationActivity) ==
- DirectoryStructure.FileBased
- ) {
- encryptUsername.apply {
- visibility = View.VISIBLE
- setOnClickListener {
- if (isChecked) {
- // User wants to enable username encryption, so we use the filename
- // as username and insert it into the username input field.
- val login = filename.text.toString()
- filename.text?.clear()
- username.setText(login)
- usernameInputLayout.apply { visibility = View.VISIBLE }
- } else {
- // User wants to disable username encryption, so we take the username
- // from the username text field and insert it into the filename input field.
- val login = username.text.toString()
- username.text?.clear()
- filename.setText(login)
- usernameInputLayout.apply { visibility = View.GONE }
- }
- }
- }
- }
- suggestedPass?.let {
- password.setText(it)
- password.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
- }
- suggestedExtra?.let { extraContent.setText(it) }
- if (shouldGeneratePassword) {
- generatePassword()
- password.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
- }
- }
- listOf(binding.filename, binding.username, binding.extraContent).forEach {
- it.doAfterTextChanged { updateViewState() }
- }
- updateViewState()
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.pgp_handler_new_password, menu)
- return true
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- android.R.id.home -> {
- setResult(RESULT_CANCELED)
- onBackPressedDispatcher.onBackPressed()
- }
- R.id.save_password -> {
- copy = false
- requireKeysExist { encrypt() }
- }
- R.id.save_and_copy_password -> {
- copy = true
- requireKeysExist { encrypt() }
- }
- else -> return super.onOptionsItemSelected(item)
- }
- return true
- }
-
- private fun generatePassword() {
- supportFragmentManager.setFragmentResultListener(PASSWORD_RESULT_REQUEST_KEY, this) {
- requestKey,
- bundle ->
- if (requestKey == PASSWORD_RESULT_REQUEST_KEY) {
- binding.password.setText(bundle.getString(RESULT))
- }
- }
- when (settings.getString(PreferenceKeys.PREF_KEY_PWGEN_TYPE) ?: KEY_PWGEN_TYPE_DICEWARE) {
- KEY_PWGEN_TYPE_CLASSIC ->
- PasswordGeneratorDialogFragment().show(supportFragmentManager, "generator")
- KEY_PWGEN_TYPE_DICEWARE ->
- DicewarePasswordGeneratorDialogFragment().show(supportFragmentManager, "generator")
- }
- }
-
- private fun updateViewState() =
- with(binding) {
- encryptUsername.apply {
- if (visibility != View.VISIBLE) return@apply
- val hasUsernameInFileName = filename.text.toString().isNotBlank()
- val usernameIsEncrypted = username.text.toString().isNotEmpty()
- isEnabled = hasUsernameInFileName xor usernameIsEncrypted
- isChecked = usernameIsEncrypted
- }
- // Use PasswordEntry to parse extras for OTP
- val entry =
- passwordEntryFactory.create("PLACEHOLDER\n${extraContent.text}".encodeToByteArray())
- otpImportButton.isVisible = !entry.hasTotp()
- }
-
- /** Encrypts the password and the extra content */
- private fun encrypt() {
- with(binding) {
- val oldName = suggestedName
- val editName = filename.text.toString().trim()
- var editUsername = username.text.toString()
- val editPass = password.text.toString()
- val editExtra = extraContent.text.toString()
-
- if (editName.isEmpty()) {
- snackbar(message = resources.getString(R.string.file_toast_text))
- return@with
- } else if (editName.contains('/')) {
- snackbar(message = resources.getString(R.string.invalid_filename_text))
- return@with
- }
-
- if (!editUsername.isEmpty()) {
- editUsername = "\nusername: $editUsername"
- }
-
- if (editPass.isEmpty() && editExtra.isEmpty()) {
- snackbar(message = resources.getString(R.string.empty_toast_text))
- return@with
- }
-
- if (copy) {
- copyPasswordToClipboard(editPass)
- }
-
- // pass enters the key ID into `.gpg-id`.
- val gpgIdentifiers = getPGPIdentifiers(directory.text.toString()) ?: return@with
- val content = "$editPass$editUsername\n$editExtra"
- val path =
- when {
- // If we allowed the user to edit the relative path, we have to consider it here
- // instead of fullPath.
- directoryInputLayout.isEnabled -> {
- val editRelativePath = directory.text.toString().trim()
- if (editRelativePath.isEmpty()) {
- snackbar(message = resources.getString(R.string.path_toast_text))
- return
- }
- val passwordDirectory = Paths.get(repoPath, editRelativePath.trim('/'))
- passwordDirectory.createDirectories()
- if (!passwordDirectory.exists()) {
- snackbar(
- message =
- "Failed to create directory ${passwordDirectory.relativeTo(Paths.get(repoPath)).pathString}"
- )
- return
- }
-
- "${passwordDirectory.pathString}/$editName.gpg"
- }
- else -> "$fullPath/$editName.gpg"
- }
-
- lifecycleScope.launch(dispatcherProvider.main()) {
- runCatching {
- val result =
- withContext(dispatcherProvider.io()) {
- val outputStream = ByteArrayOutputStream()
- repository.encrypt(gpgIdentifiers, content.byteInputStream(), outputStream)
- }
- .getOrElse { e ->
- logcat(ERROR) { e.asLog("Failed to encrypt password file") }
- MaterialAlertDialogBuilder(this@PasswordCreationActivity)
- .setTitle(R.string.password_creation_file_fail_title)
- .setMessage(
- getString(R.string.password_creation_encrypt_fail_message, e.message)
- )
- .setPositiveButton(android.R.string.ok, null)
- .show()
- return@runCatching
- }
- val passwordFile = Paths.get(path)
- // If we're not editing, this file should not already exist!
- // Additionally, if we were editing and the incoming and outgoing
- // filenames differ, it means we renamed. Ensure that the target
- // doesn't already exist to prevent an accidental overwrite.
- if (
- (!editing || (editing && suggestedName != passwordFile.nameWithoutExtension)) &&
- passwordFile.exists()
- ) {
- snackbar(message = getString(R.string.password_creation_duplicate_error))
- return@runCatching
- }
-
- if (!passwordFile.toFile().isInsideRepository()) {
- snackbar(message = getString(R.string.message_error_destination_outside_repo))
- return@runCatching
- }
-
- withContext(dispatcherProvider.io()) { passwordFile.writeBytes(result.toByteArray()) }
-
- // associate the new password name with the last name's timestamp in history
- val preference = getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
- val oldFilePathHash = "$repoPath/${oldCategory?.trim('/')}/$suggestedName.gpg".base64()
- val timestamp = preference.getString(oldFilePathHash)
- if (timestamp != null) {
- preference.edit {
- remove(oldFilePathHash)
- putString(passwordFile.absolutePathString().base64(), timestamp)
- }
- }
-
- val returnIntent = Intent()
- returnIntent.putExtra(RETURN_EXTRA_CREATED_FILE, path)
- returnIntent.putExtra(RETURN_EXTRA_NAME, editName)
- returnIntent.putExtra(RETURN_EXTRA_LONG_NAME, getLongName(fullPath, repoPath, editName))
-
- if (shouldGeneratePassword) {
- val directoryStructure = AutofillPreferences.directoryStructure(applicationContext)
- val entry = passwordEntryFactory.create(content.encodeToByteArray())
- returnIntent.putExtra(RETURN_EXTRA_PASSWORD, entry.password)
- val username =
- entry.username ?: directoryStructure.getUsernameFor(passwordFile.toFile())
- returnIntent.putExtra(RETURN_EXTRA_USERNAME, username)
- }
-
- if (
- directoryInputLayout.isVisible &&
- directoryInputLayout.isEnabled &&
- oldName != editName
- ) {
- val oldPath = Paths.get(repoPath, oldCategory?.trim('/') ?: "", "$oldName.gpg")
- if (!oldPath.isSameFileAs(passwordFile) && !oldPath.deleteIfExists()) {
- setResult(RESULT_CANCELED)
- MaterialAlertDialogBuilder(this@PasswordCreationActivity)
- .setTitle(R.string.password_creation_file_fail_title)
- .setMessage(
- getString(R.string.password_creation_file_delete_fail_message, oldName)
- )
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
- .show()
- return@runCatching
- }
- }
-
- val commitMessageRes =
- if (editing) R.string.git_commit_edit_text else R.string.git_commit_add_text
- lifecycleScope.launch {
- commitChange(
- resources.getString(commitMessageRes, getLongName(fullPath, repoPath, editName))
- )
- .onSuccess {
- setResult(RESULT_OK, returnIntent)
- finish()
- }
- }
- }
- .onFailure { e ->
- if (e is IOException) {
- logcat(ERROR) { e.asLog("Failed to write password file") }
- setResult(RESULT_CANCELED)
- MaterialAlertDialogBuilder(this@PasswordCreationActivity)
- .setTitle(getString(R.string.password_creation_file_fail_title))
- .setMessage(getString(R.string.password_creation_file_write_fail_message))
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
- .show()
- } else {
- logcat(ERROR) { e.asLog() }
- }
- }
- }
- }
- }
-
- companion object {
-
- private const val KEY_PWGEN_TYPE_CLASSIC = "classic"
- private const val KEY_PWGEN_TYPE_DICEWARE = "diceware"
- const val PASSWORD_RESULT_REQUEST_KEY = "PASSWORD_GENERATOR"
- const val OTP_RESULT_REQUEST_KEY = "OTP_IMPORT"
- const val RESULT = "RESULT"
- const val RETURN_EXTRA_CREATED_FILE = "CREATED_FILE"
- const val RETURN_EXTRA_NAME = "NAME"
- const val RETURN_EXTRA_LONG_NAME = "LONG_NAME"
- const val RETURN_EXTRA_USERNAME = "USERNAME"
- const val RETURN_EXTRA_PASSWORD = "PASSWORD"
- const val EXTRA_FILE_NAME = "FILENAME"
- const val EXTRA_USERNAME = "USERNAME"
- const val EXTRA_PASSWORD = "PASSWORD"
- const val EXTRA_EXTRA_CONTENT = "EXTRA_CONTENT"
- const val EXTRA_GENERATE_PASSWORD = "GENERATE_PASSWORD"
- const val EXTRA_EDITING = "EDITING"
- }
-}
diff --git a/app/src/main/java/app/passwordstore/ui/dialogs/DicewarePasswordGeneratorDialogFragment.kt b/app/src/main/java/app/passwordstore/ui/dialogs/DicewarePasswordGeneratorDialogFragment.kt
deleted file mode 100644
index 2605e0ef..00000000
--- a/app/src/main/java/app/passwordstore/ui/dialogs/DicewarePasswordGeneratorDialogFragment.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.ui.dialogs
-
-import android.app.AlertDialog
-import android.app.Dialog
-import android.content.SharedPreferences
-import android.graphics.Typeface
-import android.os.Bundle
-import androidx.core.content.edit
-import androidx.core.os.bundleOf
-import androidx.fragment.app.DialogFragment
-import androidx.fragment.app.setFragmentResult
-import androidx.lifecycle.lifecycleScope
-import app.passwordstore.R
-import app.passwordstore.databinding.FragmentPwgenDicewareBinding
-import app.passwordstore.injection.prefs.PasswordGeneratorPreferences
-import app.passwordstore.passgen.diceware.DicewarePassphraseGenerator
-import app.passwordstore.ui.crypto.PasswordCreationActivity
-import app.passwordstore.util.extensions.getString
-import app.passwordstore.util.settings.PreferenceKeys.DICEWARE_LENGTH
-import app.passwordstore.util.settings.PreferenceKeys.DICEWARE_SEPARATOR
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import dagger.hilt.android.AndroidEntryPoint
-import javax.inject.Inject
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.launch
-import reactivecircus.flowbinding.android.widget.afterTextChanges
-
-@AndroidEntryPoint
-class DicewarePasswordGeneratorDialogFragment : DialogFragment() {
-
- @Inject lateinit var dicewareGenerator: DicewarePassphraseGenerator
- @Inject @PasswordGeneratorPreferences lateinit var prefs: SharedPreferences
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val builder = MaterialAlertDialogBuilder(requireContext())
-
- val binding = FragmentPwgenDicewareBinding.inflate(layoutInflater)
- builder.setView(binding.root)
-
- binding.passwordSeparatorText.setText(prefs.getString(DICEWARE_SEPARATOR) ?: "-")
- binding.passwordLengthText.setText(prefs.getInt(DICEWARE_LENGTH, 5).toString())
- binding.passwordText.typeface = Typeface.MONOSPACE
-
- lifecycleScope.launch {
- merge(
- binding.passwordLengthText.afterTextChanges(),
- binding.passwordSeparatorText.afterTextChanges(),
- )
- .collect { _ -> generatePassword(binding) }
- }
- return builder
- .run {
- setTitle(R.string.pwgen_title)
- setPositiveButton(R.string.dialog_ok) { _, _ ->
- setFragmentResult(
- PasswordCreationActivity.PASSWORD_RESULT_REQUEST_KEY,
- bundleOf(PasswordCreationActivity.RESULT to "${binding.passwordText.text}"),
- )
- }
- setNeutralButton(R.string.dialog_cancel) { _, _ -> }
- setNegativeButton(R.string.pwgen_generate, null)
- create()
- }
- .apply {
- setOnShowListener {
- generatePassword(binding)
- getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener { generatePassword(binding) }
- }
- }
- }
-
- private fun generatePassword(binding: FragmentPwgenDicewareBinding) {
- val length = binding.passwordLengthText.text?.toString()?.toIntOrNull() ?: 5
- val separator = binding.passwordSeparatorText.text?.toString()?.getOrNull(0) ?: '-'
- setPreferences(length, separator)
- binding.passwordText.text = dicewareGenerator.generatePassphrase(length, separator)
- }
-
- private fun setPreferences(length: Int, separator: Char) {
- prefs.edit {
- putInt(DICEWARE_LENGTH, length)
- putString(DICEWARE_SEPARATOR, separator.toString())
- }
- }
-}
diff --git a/app/src/main/java/app/passwordstore/ui/dialogs/OtpImportDialogFragment.kt b/app/src/main/java/app/passwordstore/ui/dialogs/OtpImportDialogFragment.kt
deleted file mode 100644
index 1a75175b..00000000
--- a/app/src/main/java/app/passwordstore/ui/dialogs/OtpImportDialogFragment.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.ui.dialogs
-
-import android.app.Dialog
-import android.net.Uri
-import android.os.Bundle
-import android.view.WindowManager
-import androidx.core.os.bundleOf
-import androidx.fragment.app.DialogFragment
-import androidx.fragment.app.setFragmentResult
-import app.passwordstore.databinding.FragmentManualOtpEntryBinding
-import app.passwordstore.ui.crypto.PasswordCreationActivity
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-
-class OtpImportDialogFragment : DialogFragment() {
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val builder = MaterialAlertDialogBuilder(requireContext())
- val binding = FragmentManualOtpEntryBinding.inflate(layoutInflater)
- builder.setView(binding.root)
- builder.setPositiveButton(android.R.string.ok) { _, _ ->
- setFragmentResult(
- PasswordCreationActivity.OTP_RESULT_REQUEST_KEY,
- bundleOf(PasswordCreationActivity.RESULT to getTOTPUri(binding)),
- )
- }
- val dialog = builder.create()
- dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
- return dialog
- }
-
- private fun getTOTPUri(binding: FragmentManualOtpEntryBinding): String {
- val secret = binding.secret.text.toString()
- val account = binding.account.text.toString()
- if (secret.isBlank()) return ""
- val builder = Uri.Builder()
- builder.scheme("otpauth")
- builder.authority("totp")
- builder.appendQueryParameter("secret", secret)
- if (account.isNotBlank()) builder.appendQueryParameter("issuer", account)
- return builder.build().toString()
- }
-}
diff --git a/app/src/main/java/app/passwordstore/ui/dialogs/PasswordGeneratorDialogFragment.kt b/app/src/main/java/app/passwordstore/ui/dialogs/PasswordGeneratorDialogFragment.kt
deleted file mode 100644
index d4a2372b..00000000
--- a/app/src/main/java/app/passwordstore/ui/dialogs/PasswordGeneratorDialogFragment.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package app.passwordstore.ui.dialogs
-
-import android.app.AlertDialog
-import android.app.Dialog
-import android.content.Context
-import android.graphics.Typeface
-import android.os.Bundle
-import android.widget.CheckBox
-import android.widget.EditText
-import android.widget.Toast
-import androidx.annotation.IdRes
-import androidx.appcompat.widget.AppCompatTextView
-import androidx.core.content.edit
-import androidx.core.os.bundleOf
-import androidx.fragment.app.DialogFragment
-import androidx.fragment.app.setFragmentResult
-import androidx.lifecycle.lifecycleScope
-import app.passwordstore.R
-import app.passwordstore.databinding.FragmentPwgenBinding
-import app.passwordstore.passgen.random.MaxIterationsExceededException
-import app.passwordstore.passgen.random.NoCharactersIncludedException
-import app.passwordstore.passgen.random.PasswordGenerator
-import app.passwordstore.passgen.random.PasswordLengthTooShortException
-import app.passwordstore.passgen.random.PasswordOption
-import app.passwordstore.ui.crypto.PasswordCreationActivity
-import app.passwordstore.util.settings.PreferenceKeys
-import com.github.michaelbull.result.getOrElse
-import com.github.michaelbull.result.runCatching
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.launch
-import reactivecircus.flowbinding.android.widget.afterTextChanges
-import reactivecircus.flowbinding.android.widget.checkedChanges
-
-class PasswordGeneratorDialogFragment : DialogFragment() {
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val prefs = requireContext().getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE)
- val builder = MaterialAlertDialogBuilder(requireContext())
-
- val binding = FragmentPwgenBinding.inflate(layoutInflater)
- builder.setView(binding.root)
-
- binding.numerals.isChecked = !prefs.getBoolean(PasswordOption.NoDigits.key, false)
- binding.symbols.isChecked = prefs.getBoolean(PasswordOption.AtLeastOneSymbol.key, false)
- binding.uppercase.isChecked = !prefs.getBoolean(PasswordOption.NoUppercaseLetters.key, false)
- binding.lowercase.isChecked = !prefs.getBoolean(PasswordOption.NoLowercaseLetters.key, false)
- binding.ambiguous.isChecked = !prefs.getBoolean(PasswordOption.NoAmbiguousCharacters.key, false)
- binding.pronounceable.isChecked = !prefs.getBoolean(PasswordOption.FullyRandom.key, true)
- binding.lengthNumber.setText(prefs.getInt(PreferenceKeys.LENGTH, 20).toString())
- binding.passwordText.typeface = Typeface.MONOSPACE
-
- lifecycleScope.launch {
- merge(
- binding.numerals.checkedChanges().skipInitialValue(),
- binding.symbols.checkedChanges().skipInitialValue(),
- binding.uppercase.checkedChanges().skipInitialValue(),
- binding.lowercase.checkedChanges().skipInitialValue(),
- binding.ambiguous.checkedChanges().skipInitialValue(),
- binding.pronounceable.checkedChanges().skipInitialValue(),
- binding.lengthNumber.afterTextChanges().skipInitialValue(),
- )
- .collect { generate(binding.passwordText) }
- }
-
- return builder
- .run {
- setTitle(R.string.pwgen_title)
- setPositiveButton(R.string.dialog_ok) { _, _ ->
- setFragmentResult(
- PasswordCreationActivity.PASSWORD_RESULT_REQUEST_KEY,
- bundleOf(PasswordCreationActivity.RESULT to "${binding.passwordText.text}"),
- )
- }
- setNeutralButton(R.string.dialog_cancel) { _, _ -> }
- setNegativeButton(R.string.pwgen_generate, null)
- create()
- }
- .apply {
- setOnShowListener {
- generate(binding.passwordText)
- getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener {
- generate(binding.passwordText)
- }
- }
- }
- }
-
- private fun generate(passwordField: AppCompatTextView) {
- val passwordOptions = getSelectedOptions()
- val passwordLength = getLength()
- setPrefs(requireContext(), passwordOptions, passwordLength)
- passwordField.text =
- runCatching { PasswordGenerator.generate(passwordOptions, passwordLength) }
- .getOrElse { exception ->
- val errorText =
- when (exception) {
- is MaxIterationsExceededException ->
- requireContext().getString(R.string.pwgen_max_iterations_exceeded)
- is NoCharactersIncludedException ->
- requireContext().getString(R.string.pwgen_no_chars_error)
- is PasswordLengthTooShortException ->
- requireContext().getString(R.string.pwgen_length_too_short_error)
- else -> requireContext().getString(R.string.pwgen_some_error_occurred)
- }
- Toast.makeText(requireActivity(), errorText, Toast.LENGTH_SHORT).show()
- ""
- }
- }
-
- private fun isChecked(@IdRes id: Int): Boolean {
- return requireDialog().findViewById<CheckBox>(id).isChecked
- }
-
- private fun getSelectedOptions(): List<PasswordOption> {
- return listOfNotNull(
- PasswordOption.NoDigits.takeIf { !isChecked(R.id.numerals) },
- PasswordOption.AtLeastOneSymbol.takeIf { isChecked(R.id.symbols) },
- PasswordOption.NoUppercaseLetters.takeIf { !isChecked(R.id.uppercase) },
- PasswordOption.NoAmbiguousCharacters.takeIf { !isChecked(R.id.ambiguous) },
- PasswordOption.FullyRandom.takeIf { !isChecked(R.id.pronounceable) },
- PasswordOption.NoLowercaseLetters.takeIf { !isChecked(R.id.lowercase) },
- )
- }
-
- private fun getLength(): Int {
- val lengthText = requireDialog().findViewById<EditText>(R.id.lengthNumber).text.toString()
- return lengthText.toIntOrNull()?.takeIf { it >= 0 } ?: PasswordGenerator.DEFAULT_LENGTH
- }
-
- /**
- * Enables the [PasswordOption]s in [options] and sets [targetLength] as the length for generated
- * passwords.
- */
- private fun setPrefs(ctx: Context, options: List<PasswordOption>, targetLength: Int): Boolean {
- ctx.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE).edit {
- for (possibleOption in PasswordOption.entries) {
- putBoolean(possibleOption.key, possibleOption in options)
- }
- putInt("length", targetLength)
- }
- return true
- }
-}
diff --git a/app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderActivity.kt b/app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderActivity.kt
deleted file mode 100644
index 2139d7d2..00000000
--- a/app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderActivity.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package app.passwordstore.ui.folderselect
-
-import android.os.Bundle
-import android.view.Menu
-import android.view.MenuItem
-import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.commit
-import app.passwordstore.R
-import dagger.hilt.android.AndroidEntryPoint
-
-@AndroidEntryPoint
-class SelectFolderActivity : AppCompatActivity(R.layout.select_folder_layout) {
-
- private lateinit var passwordList: SelectFolderFragment
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- passwordList = SelectFolderFragment()
- supportActionBar?.show()
- supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
- supportFragmentManager.commit { replace(R.id.pgp_handler_linearlayout, passwordList) }
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.pgp_handler_select_folder, menu)
- return true
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- android.R.id.home -> {
- setResult(RESULT_CANCELED)
- onBackPressedDispatcher.onBackPressed()
- }
- R.id.crypto_select -> selectFolder()
- else -> return super.onOptionsItemSelected(item)
- }
- return true
- }
-
- private fun selectFolder() {
- intent.putExtra("SELECTED_FOLDER_PATH", passwordList.currentDir.absolutePath)
- setResult(RESULT_OK, intent)
- finish()
- }
-}
diff --git a/app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderFragment.kt b/app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderFragment.kt
deleted file mode 100644
index acf4b56d..00000000
--- a/app/src/main/java/app/passwordstore/ui/folderselect/SelectFolderFragment.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package app.passwordstore.ui.folderselect
-
-import android.content.Context
-import android.os.Bundle
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.flowWithLifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.recyclerview.widget.LinearLayoutManager
-import app.passwordstore.R
-import app.passwordstore.data.password.PasswordItem
-import app.passwordstore.data.repo.PasswordRepository
-import app.passwordstore.databinding.PasswordRecyclerViewBinding
-import app.passwordstore.ui.adapters.PasswordItemRecyclerAdapter
-import app.passwordstore.util.coroutines.DispatcherProvider
-import app.passwordstore.util.extensions.viewBinding
-import app.passwordstore.util.viewmodel.ListMode
-import app.passwordstore.util.viewmodel.SearchableRepositoryViewModel
-import com.github.michaelbull.result.onFailure
-import com.github.michaelbull.result.runCatching
-import dagger.hilt.android.AndroidEntryPoint
-import java.io.File
-import javax.inject.Inject
-import kotlinx.coroutines.launch
-import me.zhanghai.android.fastscroll.FastScrollerBuilder
-
-@AndroidEntryPoint
-class SelectFolderFragment : Fragment(R.layout.password_recycler_view) {
-
- @Inject lateinit var dispatcherProvider: DispatcherProvider
- private val binding by viewBinding(PasswordRecyclerViewBinding::bind)
- private lateinit var recyclerAdapter: PasswordItemRecyclerAdapter
- private lateinit var listener: OnFragmentInteractionListener
-
- private val model: SearchableRepositoryViewModel by activityViewModels()
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- binding.fab.hide()
- recyclerAdapter =
- PasswordItemRecyclerAdapter(lifecycleScope, dispatcherProvider).onItemClicked { _, item ->
- listener.onFragmentInteraction(item)
- }
- binding.passRecycler.apply {
- layoutManager = LinearLayoutManager(requireContext())
- itemAnimator = null
- adapter = recyclerAdapter
- }
-
- FastScrollerBuilder(binding.passRecycler).build()
- registerForContextMenu(binding.passRecycler)
-
- model.navigateTo(
- PasswordRepository.getRepositoryDirectory(),
- listMode = ListMode.DirectoriesOnly,
- pushPreviousLocation = false,
- )
- lifecycleScope.launch {
- model.searchResult.flowWithLifecycle(lifecycle).collect { result ->
- recyclerAdapter.submitList(result.passwordItems)
- }
- }
- }
-
- override fun onAttach(context: Context) {
- super.onAttach(context)
- runCatching {
- listener =
- object : OnFragmentInteractionListener {
- override fun onFragmentInteraction(item: PasswordItem) {
- if (item.type == PasswordItem.TYPE_CATEGORY) {
- model.navigateTo(item.file, listMode = ListMode.DirectoriesOnly)
- (requireActivity() as AppCompatActivity)
- .supportActionBar
- ?.setDisplayHomeAsUpEnabled(true)
- }
- }
- }
- }
- .onFailure {
- throw ClassCastException("$context must implement OnFragmentInteractionListener")
- }
- }
-
- val currentDir: File
- get() = model.currentDir.value
-
- interface OnFragmentInteractionListener {
-
- fun onFragmentInteraction(item: PasswordItem)
- }
-}
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 a13484c6..bad55de4 100644
--- a/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt
+++ b/app/src/main/java/app/passwordstore/util/extensions/AndroidExtensions.kt
@@ -95,18 +95,13 @@ fun FragmentActivity.isPermissionGranted(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
-/**
- * Show a [Snackbar] in a [FragmentActivity] and correctly anchor it to a
- * [com.google.android.material.floatingactionbutton.FloatingActionButton] if one exists in the
- * [view]
- */
+/** Show a [Snackbar] in a [FragmentActivity]. */
fun FragmentActivity.snackbar(
view: View = findViewById(android.R.id.content),
message: String,
length: Int = Snackbar.LENGTH_SHORT,
): Snackbar {
val snackbar = Snackbar.make(view, message, length)
- snackbar.anchorView = findViewById(R.id.fab)
snackbar.show()
return snackbar
}
diff --git a/app/src/main/res/drawable/ic_done_24dp.xml b/app/src/main/res/drawable/ic_done_24dp.xml
deleted file mode 100644
index f8b6cef6..00000000
--- a/app/src/main/res/drawable/ic_done_24dp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:tint="?attr/colorControlNormal"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z" />
-</vector>
diff --git a/app/src/main/res/drawable/ic_save_24dp.xml b/app/src/main/res/drawable/ic_save_24dp.xml
deleted file mode 100644
index 8a4276c4..00000000
--- a/app/src/main/res/drawable/ic_save_24dp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:tint="?attr/colorControlNormal"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM19,19L5,19L5,5h11.17L19,7.83L19,19zM12,12c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3zM6,6h9v4L6,10z" />
-</vector>
diff --git a/app/src/main/res/drawable/ic_save_copy_24dp.xml b/app/src/main/res/drawable/ic_save_copy_24dp.xml
deleted file mode 100644
index 06419aac..00000000
--- a/app/src/main/res/drawable/ic_save_copy_24dp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:tint="?attr/colorControlNormal"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M19,5L7,5A2,2 0,0 0,5 7L5,21a2,2 0,0 0,2 2L21,23a2,2 0,0 0,2 -2L23,9ZM21,21L7,21L7,7L18.17,7L21,9.83ZM14,14a3,3 0,1 0,3 3A3,3 0,0 0,14 14ZM8,8h9v4L8,12ZM15,1L3,1A2,2 0,0 0,1 3L1,17L3,17L3,3L15,3Z" />
-</vector>
diff --git a/app/src/main/res/layout/fragment_manual_otp_entry.xml b/app/src/main/res/layout/fragment_manual_otp_entry.xml
deleted file mode 100644
index 7d7ea832..00000000
--- a/app/src/main/res/layout/fragment_manual_otp_entry.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/secret_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/otp_import_manual_hint_secret"
- android:paddingStart="16dp"
- android:paddingTop="16dp"
- android:paddingEnd="16dp"
- app:hintEnabled="true"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/secret"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:inputType="textPassword" />
-
- <requestFocus />
-
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/account_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/otp_import_manual_hint_account"
- android:paddingStart="16dp"
- android:paddingTop="16dp"
- android:paddingEnd="16dp"
- android:paddingBottom="16dp"
- app:hintEnabled="true"
- app:layout_constraintTop_toBottomOf="@id/secret_layout">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/account"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- </com.google.android.material.textfield.TextInputLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_pwgen.xml b/app/src/main/res/layout/fragment_pwgen.xml
deleted file mode 100644
index 02eadff5..00000000
--- a/app/src/main/res/layout/fragment_pwgen.xml
+++ /dev/null
@@ -1,115 +0,0 @@
-<!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingLeft="24dp"
- android:paddingTop="20dp"
- android:paddingRight="24dp"
- android:paddingBottom="20dp"
- tools:context=".MainActivityFragment">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/passwordText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textIsSelectable="true" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:baselineAligned="false"
- android:orientation="horizontal"
- android:weightSum="2">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="vertical">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="8dp"
- android:text="@string/pwgen_include"
- android:textAppearance="?android:attr/textAppearanceSmall" />
-
- <CheckBox
- android:id="@+id/numerals"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/pwgen_numerals" />
-
-
- <CheckBox
- android:id="@+id/symbols"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/pwgen_symbols" />
-
- <CheckBox
- android:id="@+id/uppercase"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/pwgen_uppercase" />
-
- <CheckBox
- android:id="@+id/lowercase"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/pwgen_lowercase" />
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="vertical">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/length"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="8dp"
- android:labelFor="@id/lengthNumber"
- android:text="@string/pwgen_length"
- android:textAppearance="?android:attr/textAppearanceSmall" />
-
- <EditText
- android:id="@+id/lengthNumber"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="8dp"
- android:autofillHints="notApplicable"
- android:ems="10"
- android:inputType="number" />
-
- <CheckBox
- android:id="@+id/pronounceable"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/pwgen_pronounceable" />
-
- <CheckBox
- android:id="@+id/ambiguous"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/pwgen_ambiguous" />
-
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
-</ScrollView>
diff --git a/app/src/main/res/layout/fragment_pwgen_diceware.xml b/app/src/main/res/layout/fragment_pwgen_diceware.xml
deleted file mode 100644
index b8627670..00000000
--- a/app/src/main/res/layout/fragment_pwgen_diceware.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingLeft="24dp"
- android:paddingTop="20dp"
- android:paddingRight="24dp"
- android:paddingBottom="20dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/password_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/password_length"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="4dp"
- android:hint="@string/pwgen_length"
- android:labelFor="@id/password_length_text"
- app:hintAnimationEnabled="true"
- app:hintEnabled="true"
- app:layout_constraintEnd_toStartOf="@id/password_separator"
- app:layout_constraintHorizontal_weight="0.5"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/password_text">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/password_length_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:inputType="number"
- android:maxLength="2" />
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/password_separator"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="4dp"
- android:layout_marginTop="8dp"
- android:hint="@string/pwgen_separator"
- android:labelFor="@id/password_separator_text"
- app:hintAnimationEnabled="true"
- app:hintEnabled="true"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_weight="0.5"
- app:layout_constraintStart_toEndOf="@id/password_length"
- app:layout_constraintTop_toBottomOf="@id/password_text">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/password_separator_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:autofillHints=""
- android:importantForAutofill="no"
- android:inputType="text"
- android:maxLength="1" />
- </com.google.android.material.textfield.TextInputLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/password_creation_activity.xml b/app/src/main/res/layout/password_creation_activity.xml
deleted file mode 100644
index c0692753..00000000
--- a/app/src/main/res/layout/password_creation_activity.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fillViewport="false"
- tools:context="app.passwordstore.ui.crypto.PasswordCreationActivity">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:padding="@dimen/activity_horizontal_margin">
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/directory_input_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_margin="8dp"
- android:enabled="false"
- android:hint="@string/directory_hint"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/directory"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:inputType="textNoSuggestions"
- android:nextFocusForward="@id/password"
- tools:text="CATEGORY HERE" />
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/name_input_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_margin="8dp"
- android:hint="@string/crypto_name_hint"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/directory_input_layout">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/filename"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:inputType="textNoSuggestions"
- android:nextFocusForward="@id/username" />
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:visibility="gone"
- tools:visibility="visible"
- android:id="@+id/username_input_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:hint="@string/crypto_username_hint"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/name_input_layout">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/username"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:inputType="textNoSuggestions"
- android:nextFocusForward="@id/password" />
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/password_input_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:hint="@string/crypto_pass_label"
- app:endIconMode="password_toggle"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/username_input_layout">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/password"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="actionDone"
- android:inputType="textVisiblePassword" />
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.button.MaterialButton
- android:id="@+id/generate_password"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="@string/pwd_generate_button"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/password_input_layout" />
-
- <com.google.android.material.textfield.TextInputLayout
- android:id="@+id/extra_input_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:hint="@string/crypto_extra_label"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/generate_password">
-
- <com.google.android.material.textfield.TextInputEditText
- android:id="@+id/extra_content"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:inputType="textMultiLine|textVisiblePassword" />
-
- </com.google.android.material.textfield.TextInputLayout>
-
- <com.google.android.material.button.MaterialButton
- android:id="@+id/otp_import_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="@string/add_otp"
- app:icon="@drawable/ic_qr_code_scanner"
- app:iconTint="?attr/colorOnSecondary"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/extra_input_layout" />
-
- <com.google.android.material.switchmaterial.SwitchMaterial
- android:id="@+id/encrypt_username"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="@string/crypto_encrypt_username_label"
- android:visibility="gone"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/otp_import_button"
- tools:visibility="visible" />
- </androidx.constraintlayout.widget.ConstraintLayout>
-</ScrollView>
diff --git a/app/src/main/res/layout/password_recycler_view.xml b/app/src/main/res/layout/password_recycler_view.xml
deleted file mode 100644
index c2b5114f..00000000
--- a/app/src/main/res/layout/password_recycler_view.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical">
-
- <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
- android:id="@+id/swipe_refresher"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <me.zhanghai.android.fastscroll.FixOnItemTouchListenerRecyclerView
- android:id="@+id/pass_recycler"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scrollbars="none"
- tools:itemCount="20"
- tools:listitem="@layout/password_row_layout" />
- </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
-
- <com.google.android.material.floatingactionbutton.FloatingActionButton
- android:id="@+id/fab"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_alignParentBottom="true"
- android:layout_gravity="bottom|end"
- android:layout_margin="@dimen/fab_compat_margin"
- android:contentDescription="@string/password_list_fab_content_description"
- android:src="@drawable/ic_add_48dp" />
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/password_row_layout.xml b/app/src/main/res/layout/password_row_layout.xml
deleted file mode 100644
index 5c042839..00000000
--- a/app/src/main/res/layout/password_row_layout.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/password_row_background"
- android:paddingTop="12dp"
- android:paddingBottom="12dp">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/label"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginStart="@dimen/activity_horizontal_margin"
- android:textSize="18sp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/child_count"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- tools:text="FILE_NAME" />
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/child_count"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
- android:textSize="18sp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/folder_indicator"
- app:layout_constraintTop_toTopOf="parent"
- tools:text="12" />
-
- <androidx.appcompat.widget.AppCompatImageView
- android:id="@+id/folder_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/activity_horizontal_margin"
- android:contentDescription="@null"
- android:src="@drawable/ic_keyboard_arrow_right_24dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/select_folder_layout.xml b/app/src/main/res/layout/select_folder_layout.xml
deleted file mode 100644
index 78b03579..00000000
--- a/app/src/main/res/layout/select_folder_layout.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <LinearLayout
- android:id="@+id/pgp_handler_linearlayout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" />
-</LinearLayout>
diff --git a/app/src/main/res/menu/pgp_handler_new_password.xml b/app/src/main/res/menu/pgp_handler_new_password.xml
deleted file mode 100644
index 6c61fb55..00000000
--- a/app/src/main/res/menu/pgp_handler_new_password.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:pwstore="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- tools:context=".ui.crypto.PgpActivity">
- <item
- android:id="@+id/save_password"
- android:icon="@drawable/ic_save_24dp"
- android:title="@string/crypto_save"
- pwstore:showAsAction="ifRoom" />
- <item
- android:id="@+id/save_and_copy_password"
- android:icon="@drawable/ic_save_copy_24dp"
- android:title="@string/crypto_save_and_copy"
- pwstore:showAsAction="ifRoom" />
-</menu>
diff --git a/app/src/main/res/menu/pgp_handler_select_folder.xml b/app/src/main/res/menu/pgp_handler_select_folder.xml
deleted file mode 100644
index d9505814..00000000
--- a/app/src/main/res/menu/pgp_handler_select_folder.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- ~ SPDX-License-Identifier: GPL-3.0-only
- -->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:pwstore="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- tools:context="app.passwordstore.SelectFolderActivity">
- <item
- android:id="@+id/crypto_select"
- android:icon="@drawable/ic_done_24dp"
- android:title="@string/crypto_select"
- pwstore:showAsAction="ifRoom" />
-</menu>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index d13ab19f..a9fa4b00 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -39,7 +39,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">In die Zwischenablage kopiert</string>
<string name="file_toast_text">Bitte setzen Sie einen Dateinamen.</string>
- <string name="path_toast_text">Bitte setzen Sie einen Pfad.</string>
<string name="empty_toast_text">Sie können kein leeres Passwort oder leere Extra-Angaben setzen.</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Es ist ein Fehler während der Git-Operation aufgetreten.</string>
@@ -63,7 +62,6 @@
<string name="crypto_name_hint">Name</string>
<string name="crypto_pass_label">Passwort</string>
<string name="crypto_extra_label">Zusätzliche Angaben</string>
- <string name="crypto_encrypt_username_label">Benutzername verschlüsseln</string>
<string name="crypto_select">Auswählen</string>
<string name="crypto_save">Speichern</string>
<string name="crypto_save_and_copy">Speichern und kopieren</string>
@@ -125,7 +123,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Passwort erstellen</string>
<string name="pwgen_generate">Erstellen</string>
- <string name="pwgen_include">Einschließen</string>
<string name="pwgen_length">Länge</string>
<string name="pwgen_numerals">Nummern</string>
<string name="pwgen_symbols">Symbole</string>
@@ -173,7 +170,6 @@
<string name="git_log">Commit-Log anzeigen</string>
<string name="show_password_pref_title">Zeige das Passwort.</string>
<string name="show_password_pref_summary">Soll das entschlüsselte Passwort sichtbar sein? Dies deaktiviert nicht das Kopieren.</string>
- <string name="pwd_generate_button">Erstellen</string>
<string name="send_plaintext_password_to">Passwort unverschlüsselt senden an…</string>
<string name="app_icon_hint">App-Icon</string>
<!-- Oreo Autofill -->
@@ -207,7 +203,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">Autofill-Unterstützung mit installierten Browsern:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Der private SSH-Schlüssel konnte nicht geöffnet werden. Bitte überprüfen Sie, ob die Datei existiert.</string>
- <string name="new_password_title">Neues Passwort</string>
<string name="clear_saved_passphrase_ssh">Gespeicherte Passphrase für lokalen SSH-Schlüssel löschen</string>
<string name="clear_saved_passphrase_https">Gespeichertes HTTPS-Passwort löschen</string>
<string name="git_operation_remember_passphrase">Schlüsselpasswort merken</string>
@@ -276,7 +271,6 @@
<string name="invalid_gpg_id">.gpg-id wurde gefunden, enthält jedoch ungültige Schlüssel-ID, Fingerabdruck oder Benutzer-ID.</string>
<string name="short_gpg_id">.gpg-id wurde gefunden, enthält jedoch eine kurze Hex-ID, die nicht unterstützt wird.</string>
<string name="invalid_filename_text">Dateiname darf kein \'/\' enthalten; Verzeichnis oben setzen</string>
- <string name="directory_hint">Ordner</string>
<!-- GitException messages -->
<string name="git_unknown_error">Unbekannter Fehler</string>
<string name="git_pull_rebase_fail_error">Pull fehlgeschlagen. Sie befinden sich in einem abgelösten Head. Speichern Sie die Änderungen in \"Einstellungen &gt; Lokale Git-Konfiguration &amp; Dienstprogramme\" auf das Remote-Repository in einem neuen Branch und lösen Sie den Konflikt auf Ihrem Computer auf.</string>
@@ -319,11 +313,9 @@
<string name="clear_saved_host_key_success">Host-Schlüssel erfolgreich gelöscht!</string>
<string name="otp_import_qr_code">QR-Code scannen</string>
<string name="otp_import_from_file">Wählen Sie ein Bild.</string>
- <string name="otp_import_manual_entry">Manuell eingeben</string>
<string name="otp_import_manual_hint_secret">Schlüssel</string>
<string name="otp_import_manual_hint_account">Benutzer-Konto</string>
<string name="place_shortcut_on_home_screen">Verknüpfung auf dem Home-Screen erstellen</string>
- <string name="password_list_fab_content_description">Neues Passwort oder neuen Ordner erstellen</string>
<string name="pgp_key_import_failed">Fehler beim Import des PGP-Schlüssels</string>
<string name="pgp_key_import_failed_replace_message">Ein bestehender Schlüssel mit dieser ID wurde gefunden. Möchten Sie ihn ersetzen?</string>
<string name="pgp_key_import_succeeded">PGP-Schlüssel erfolgreich importiert</string>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 0cfb345c..d41048f8 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -38,7 +38,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copié dans le presse-papiers</string>
<string name="file_toast_text">Veuillez fournir un nom de fichier</string>
- <string name="path_toast_text">Veuillez fournir un chemin d\'accès au fichier</string>
<string name="empty_toast_text">Vous ne pouvez pas utiliser un mot de passe vide ou des données supplémentaires vide</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Une erreur c\'est produite lors d\'une opération Git</string>
@@ -62,7 +61,6 @@
<string name="crypto_name_hint">Nom</string>
<string name="crypto_pass_label">Mot de passe</string>
<string name="crypto_extra_label">Extra</string>
- <string name="crypto_encrypt_username_label">Chiffrer le nom d\'utilisateur</string>
<string name="crypto_select">Sélectionner</string>
<string name="crypto_save">Sauvegarder</string>
<string name="crypto_save_and_copy">Enregistrer et copier</string>
@@ -113,7 +111,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Générer un mot de passe</string>
<string name="pwgen_generate">Générer</string>
- <string name="pwgen_include">Inclure</string>
<string name="pwgen_length">Longueur</string>
<string name="pwgen_numerals">Chiffres</string>
<string name="pwgen_symbols">Symboles</string>
@@ -161,7 +158,6 @@
<string name="git_log">Afficher l\'historique des commits</string>
<string name="show_password_pref_title">Montrer le mot de passe</string>
<string name="show_password_pref_summary">Contrôle la visibilité des mots de passe une fois déchifrées, ceci n\'empêche pas de copier le mot de passe</string>
- <string name="pwd_generate_button">Générer</string>
<string name="send_plaintext_password_to">Envoyer le mot de passe en clair via…</string>
<string name="app_icon_hint">Icône de l\'application</string>
<!-- Oreo Autofill -->
@@ -195,7 +191,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">Prise en charge du remplissage automatique avec les navigateurs installés:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Impossible d\'ouvrir la clef ssh, merci de vérifier que le ficher existe</string>
- <string name="new_password_title">Nouveau mot de passe</string>
<string name="clear_saved_passphrase_ssh">Effacer le mot de passe enregistrée pour la clé SSH locale</string>
<string name="clear_saved_passphrase_https">Effacer le mot de passe HTTPS enregistré</string>
<string name="git_operation_remember_passphrase">Se rappeler de la phrase secrète dans la configuration de l\'application (peu sûr)</string>
@@ -261,7 +256,6 @@
<string name="otp_import_failure_generic">Impossible d\'importer la configuration TOTP</string>
<string name="exporting_passwords">Exportation des mots de passe…</string>
<string name="invalid_filename_text">Le nom du fichier ne doit pas contenir \'/\', définir le répertoire parent</string>
- <string name="directory_hint">Dossier</string>
<!-- GitException messages -->
<string name="git_unknown_error">Erreur inconnue</string>
<string name="git_pull_rebase_fail_error">Tirer a échoué, vous êtes dans un \'head\' détaché. En utilisant \"settings &gt; git utils\", enregistrez vos modifications sur le dépôt distant dans une nouvelle branche et résolvez le conflit sur votre ordinateur.</string>
@@ -300,10 +294,8 @@
<string name="clear_saved_host_key_success">La clé d\'hôte a été effacée avec succès!</string>
<string name="otp_import_qr_code">Scanner le code QR</string>
<string name="otp_import_from_file">Choisissez une image</string>
- <string name="otp_import_manual_entry">Saisir manuellement</string>
<string name="otp_import_manual_hint_secret">Secret</string>
<string name="otp_import_manual_hint_account">Compte</string>
- <string name="password_list_fab_content_description">Créer un nouveau mot de passe ou dossier</string>
<string name="pgp_key_import_failed">Impossible d\'importer la clé PGP</string>
<string name="pgp_key_import_succeeded">Clé PGP importée avec succès</string>
<string name="pgp_key_import_succeeded_message">La clé d\'identification de la clé importée est donné ci-dessous, veuillez la vérifier pour qu\'elle soit correcte :\n%1$s</string>
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 589208ab..3fb321e7 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -39,7 +39,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copiado ao portapapeis</string>
<string name="file_toast_text">Debes proporcionar un nome de ficheiro</string>
- <string name="path_toast_text">Por favor indica a ruta ao ficheiro</string>
<string name="empty_toast_text">Non podes deixar baleiro o contrasinal ou o contido extra</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Algo fallou na operación de Git</string>
@@ -63,7 +62,6 @@
<string name="crypto_name_hint">Nome</string>
<string name="crypto_pass_label">Contrasinal</string>
<string name="crypto_extra_label">Contido extra</string>
- <string name="crypto_encrypt_username_label">Cifrar identificador</string>
<string name="crypto_select">Seleccionar</string>
<string name="crypto_save">Gardar</string>
<string name="crypto_save_and_copy">Gardar e copiar</string>
@@ -126,7 +124,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Crear contrasinal</string>
<string name="pwgen_generate">Crear</string>
- <string name="pwgen_include">Incluír</string>
<string name="pwgen_length">Lonxitude</string>
<string name="pwgen_numerals">Números</string>
<string name="pwgen_symbols">Símbolos</string>
@@ -174,7 +171,6 @@
<string name="git_log">Mostrar rexistro dos cambios</string>
<string name="show_password_pref_title">Mostrar contrasinal</string>
<string name="show_password_pref_summary">Controlar a visibilidade do contrasinal unha vez descifrado, esto non desactiva o copiado do contrasinal</string>
- <string name="pwd_generate_button">Crear</string>
<string name="send_plaintext_password_to">Enviar contrasinal como texto plano usando…</string>
<string name="app_icon_hint">Icona da app</string>
<!-- Oreo Autofill -->
@@ -209,7 +205,6 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
<string name="oreo_autofill_enable_dialog_installed_browsers">Soporte de autocompletado cos navegadores:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Non se pode abrir a chave privada ssh, comproba que existe tal ficheiro</string>
- <string name="new_password_title">Novo contrasinal</string>
<string name="clear_saved_passphrase_ssh">Baleirar a frase de paso gardada para a chave SSH local</string>
<string name="clear_saved_passphrase_https">Baleirar contrasinal HTTPS gardado</string>
<string name="git_operation_remember_passphrase">Lembrar frase de paso da chave</string>
@@ -278,7 +273,6 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
<string name="invalid_gpg_id">Atopouse .gpg-id, pero contén un ID de chave, impresión dixital ou ID de usuaria non válidos</string>
<string name="short_gpg_id">Atopouse .gpg-id, pero contén un ID hex curto, ao que non damos soporte</string>
<string name="invalid_filename_text">O nome do ficheiro non pode conter \'/\', establece un directorio superior</string>
- <string name="directory_hint">Directorio</string>
<!-- GitException messages -->
<string name="git_unknown_error">Fallo descoñecido</string>
<string name="git_pull_rebase_fail_error">Fallou a acción pull, estás nun head diferente. Utiliza \"axustes &gt; utilidades git\", garda os cambios no remoto nunha nova rama e resolve o conflicto nun ordenador.</string>
@@ -321,11 +315,9 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
<string name="clear_saved_host_key_success">Eliminouse correctamente a chave gardada do host!</string>
<string name="otp_import_qr_code">Escanear código QR</string>
<string name="otp_import_from_file">Elixe unha imaxe</string>
- <string name="otp_import_manual_entry">Escribir manualmente</string>
<string name="otp_import_manual_hint_secret">Segredo</string>
<string name="otp_import_manual_hint_account">Conta</string>
<string name="place_shortcut_on_home_screen">Crear atallo na pantalla de inicio</string>
- <string name="password_list_fab_content_description">Crear novo contrasinal ou cartafol</string>
<string name="pgp_key_import_failed">Fallou a importación da chave PGP</string>
<string name="pgp_key_import_failed_replace_message">Atopouse unha chave existente con este ID, queres substituíla?</string>
<string name="pgp_key_import_succeeded">Chave PGP importada correctamente</string>
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 91cd28aa..c14efa33 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -38,7 +38,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copiato negli appunti</string>
<string name="file_toast_text">Inserisci un nome per il file</string>
- <string name="path_toast_text">Inserisci il percorso del file</string>
<string name="empty_toast_text">Non puoi usare una password vuota o dei contenuti extra vuoti</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Si è verificato un errore durante un\'operazione Git</string>
@@ -62,7 +61,6 @@
<string name="crypto_name_hint">Nome</string>
<string name="crypto_pass_label">Password</string>
<string name="crypto_extra_label">Contenuto extra</string>
- <string name="crypto_encrypt_username_label">Crittografa nome utente</string>
<string name="crypto_select">Seleziona</string>
<string name="crypto_save">Salva</string>
<string name="crypto_save_and_copy">Salva e Copia</string>
@@ -108,7 +106,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Genera Password</string>
<string name="pwgen_generate">Genera</string>
- <string name="pwgen_include">Includi</string>
<string name="pwgen_length">Lunghezza</string>
<string name="pwgen_numerals">Numeri</string>
<string name="pwgen_symbols">Simboli</string>
@@ -156,7 +153,6 @@
<string name="git_log">Mostra registro dei commit</string>
<string name="show_password_pref_title">Mostra la password</string>
<string name="show_password_pref_summary">Controlla la visibilità delle password una volta decrittografate. Questo non disabilita la copia negli appunti.</string>
- <string name="pwd_generate_button">Genera</string>
<string name="send_plaintext_password_to">Invia password come testo semplice usando…</string>
<string name="app_icon_hint">Icona app</string>
<!-- Oreo Autofill -->
@@ -190,7 +186,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">Supporto alla compilazione automatica nei browser installati:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Impossibile aprire la chiave privata SSH, controlla che il file esista</string>
- <string name="new_password_title">Nuova password</string>
<string name="clear_saved_passphrase_ssh">Cancella la frase segreta salvata per la chiave SSH locale</string>
<string name="clear_saved_passphrase_https">Cancella la password HTTPS salvata</string>
<string name="git_operation_remember_passphrase">Ricorda la frase segreta della chiave</string>
@@ -256,7 +251,6 @@
<string name="otp_import_failure_generic">Impossibile importare la configurazione di TOTP</string>
<string name="exporting_passwords">Esportazione delle password…</string>
<string name="invalid_filename_text">Il nome del file non deve contenere \'/\', imposta la directory qui sopra</string>
- <string name="directory_hint">Directory</string>
<!-- GitException messages -->
<string name="git_unknown_error">Errore sconosciuto</string>
<string name="git_pull_rebase_fail_error">Pull non riuscito, sei in detached HEAD. Da \"Impostazioni > Utilità Git\" esegui il push delle modifiche sul remote in un nuovo branch e risolvi il conflitto dal computer.</string>
@@ -293,7 +287,6 @@
<string name="clear_saved_host_key">Cancella la chiave host salvata</string>
<string name="clear_saved_host_key_success">Chiave host cancellata con successo!</string>
<string name="otp_import_from_file">Scegli un\'immagine</string>
- <string name="password_list_fab_content_description">Crea nuova password o cartella</string>
<string name="git_commit_gpg_id">Inizializza gli ID GPG in %1$s.</string>
<string name="crypto_username_hint">Nome utente</string>
<string name="otp_label_format">OTP (scade tra %ds)</string>
@@ -327,7 +320,6 @@
<string name="git_scheme_disallowed_message">Il protocollo git di git-daemon non cifra il trasporto e non è adatto a operazioni sicure.</string>
<string name="activity_proxy_label">Impostazioni proxy</string>
<string name="otp_import_qr_code">Scansiona codice QR</string>
- <string name="otp_import_manual_entry">Inserisci manualmente</string>
<string name="otp_import_manual_hint_secret">Segreto</string>
<string name="otp_import_manual_hint_account">Account</string>
<string name="place_shortcut_on_home_screen">Aggiungi scorciatoia alla schermata Home</string>
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index 7f63ad8b..3efbed68 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -37,7 +37,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">클립보드로 복사됨</string>
<string name="file_toast_text">파일 이름이 필요합니다</string>
- <string name="path_toast_text">파일 경로가 필요합니다</string>
<string name="empty_toast_text">비어있는 비밀번호나 추가 정보를 사용할 수 없습니다</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Git 동작 중 문제가 발생하였습니다</string>
@@ -61,7 +60,6 @@
<string name="crypto_name_hint">이름</string>
<string name="crypto_pass_label">비밀번호</string>
<string name="crypto_extra_label">추가 내용</string>
- <string name="crypto_encrypt_username_label">암호화 계정 이름</string>
<string name="crypto_select">선택</string>
<string name="crypto_save">저장</string>
<string name="crypto_save_and_copy">저장 및 복사</string>
@@ -121,7 +119,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">암호 생성</string>
<string name="pwgen_generate">생성</string>
- <string name="pwgen_include">포함</string>
<string name="pwgen_length">길이</string>
<string name="pwgen_numerals">숫자만</string>
<string name="pwgen_symbols">특수문자</string>
@@ -169,7 +166,6 @@
<string name="git_log">커밋 로그 보기</string>
<string name="show_password_pref_title">비밀번호 표시하기</string>
<string name="show_password_pref_summary">암호가 해독된 후 비밀번호의 공개 여부를 제어합니다. 그렇다고 해서 클립보드 복사가 비활성화되지는 않습니다.</string>
- <string name="pwd_generate_button">생성</string>
<string name="send_plaintext_password_to">비밀번호를 일반 텍스트로 보내는 중…</string>
<string name="app_icon_hint">앱 아이콘</string>
<!-- Oreo Autofill -->
@@ -203,7 +199,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">자동 완성 지원 하는 설치된 브라우저:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">SSH 개인 키를 열 수 없습니다. 파일이 존재하는지 확인하세요</string>
- <string name="new_password_title">새 암호</string>
<string name="clear_saved_passphrase_ssh">로컬 SSH 키의 저장된 비밀번호 지우기</string>
<string name="clear_saved_passphrase_https">저장된 HTTPS 비밀번호 지우기</string>
<string name="git_operation_remember_passphrase">키 암호 기억하기</string>
@@ -274,7 +269,6 @@ username@example.com:…</string>
<string name="invalid_gpg_id">.gpg-id를 찾았지만 잘못된 키 ID, 지문 또는 사용자 ID가 포함되어 있습니다</string>
<string name="short_gpg_id">.gpg-id를 찾았지만, 지원되지 않는 짧은 16진수 ID가 포함되어 있습니다.</string>
<string name="invalid_filename_text">파일 이름에 \'/\'가 포함되어서는 안됩니다. 위의 디렉터리를 설정하세요</string>
- <string name="directory_hint">디렉토리</string>
<!-- GitException messages -->
<string name="git_unknown_error">알 수 없는 오류</string>
<string name="git_pull_rebase_fail_error">풀이 실패하여 head가 분리된 상태입니다. \"설정 &gt; git 기능\"을 사용하여 원격 저장소에 변경 내용을 새 브랜치에 저장하고 컴퓨터에서 충돌을 해결하세요.</string>
@@ -317,11 +311,9 @@ username@example.com:…</string>
<string name="clear_saved_host_key_success">저장된 호스트 키를 성공적으로 지웠습니다!</string>
<string name="otp_import_qr_code">QR코드 스캔</string>
<string name="otp_import_from_file">이미지 선택</string>
- <string name="otp_import_manual_entry">직접 입력</string>
<string name="otp_import_manual_hint_secret">비밀</string>
<string name="otp_import_manual_hint_account">계정</string>
<string name="place_shortcut_on_home_screen">홈 화면에 추가</string>
- <string name="password_list_fab_content_description">새 비밀번호 또는 폴더 만들기</string>
<string name="pgp_key_import_failed">PGP 키를 가져오지 못했습니다</string>
<string name="pgp_key_import_failed_replace_message">이 ID를 가진 기존 키가 발견되었습니다. 교체하시겠습니까?</string>
<string name="pgp_key_import_succeeded">PGP 키를 성공적으로 가져왔습니다</string>
diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml
index a2068e65..65f14ce5 100644
--- a/app/src/main/res/values-pl-rPL/strings.xml
+++ b/app/src/main/res/values-pl-rPL/strings.xml
@@ -37,7 +37,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Skopiowano do schowka</string>
<string name="file_toast_text">Podaj nazwę pliku</string>
- <string name="path_toast_text">Podaj ścieżkę do pliku</string>
<string name="empty_toast_text">Nie możesz użyć pustego hasła lub pustej dodatkowej zawartości</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Wystąpił błąd podczas operacji Git</string>
@@ -61,7 +60,6 @@
<string name="crypto_name_hint">Nazwa</string>
<string name="crypto_pass_label">Hasło</string>
<string name="crypto_extra_label">Treść dodatkowa</string>
- <string name="crypto_encrypt_username_label">Szyfruj nazwę użytkownika</string>
<string name="crypto_select">Wybierz</string>
<string name="crypto_save">Zapisz</string>
<string name="crypto_save_and_copy">Zapisz i skopiuj</string>
@@ -122,7 +120,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Generuj hasło</string>
<string name="pwgen_generate">Wygeneruj</string>
- <string name="pwgen_include">Załącz</string>
<string name="pwgen_length">Długość</string>
<string name="pwgen_numerals">Cyfry</string>
<string name="pwgen_symbols">Symbole</string>
@@ -170,7 +167,6 @@
<string name="git_log">Pokaż dziennik commitów</string>
<string name="show_password_pref_title">Pokaż hasło</string>
<string name="show_password_pref_summary">Kontroluj widoczność haseł po odszyfrowaniu. To nie wyłącza kopiowania do schowka.</string>
- <string name="pwd_generate_button">Generuj</string>
<string name="send_plaintext_password_to">Wyślij niezaszyfrowane hasło, używając…</string>
<string name="app_icon_hint">Ikona aplikacji</string>
<!-- Oreo Autofill -->
@@ -202,7 +198,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">Obsługa autouzupełniania w zainstalowanych przeglądarkach:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Nie można otworzyć klucza prywatnego ssh, sprawdź czy plik istnieje</string>
- <string name="new_password_title">Nowe hasło</string>
<string name="clear_saved_passphrase_ssh">Wyczyść zapisane hasło dla lokalnego klucza SSH</string>
<string name="clear_saved_passphrase_https">Wyczyść zapisane hasło HTTPS</string>
<string name="git_operation_remember_passphrase">Zapamiętaj hasło klucza</string>
@@ -268,7 +263,6 @@
<string name="invalid_gpg_id">Znaleziono .gpg-id, ale zawiera nieprawidłowy identyfikator klucza, odcisk palca lub identyfikator użytkownika</string>
<string name="short_gpg_id">Znaleziono .gpg-id, ale zawarty w nim skrócony identyfikator nie jest obsługiwany</string>
<string name="invalid_filename_text">Nazwa pliku nie może zawierać \'/\', ustaw katalog powyżej</string>
- <string name="directory_hint">Katalog</string>
<!-- GitException messages -->
<string name="git_unknown_error">Nieznany błąd</string>
<string name="git_pull_rebase_fail_error">Zaciąganie zmian nie powiodło się, nie jesteś na żadnej gałęzi (detached head). Używając \"Ustawienia &gt; narzędzia Git\", wyślij lokalne zmiany do zdalnego repozytorium na nowej gałęzi i rozwiąż konflikt na komputerze.</string>
@@ -309,11 +303,9 @@
<string name="clear_saved_host_key_success">Pomyślnie wyczyszczono zapisany klucz hosta!</string>
<string name="otp_import_qr_code">Skanuj kod QR</string>
<string name="otp_import_from_file">Wybierz obraz</string>
- <string name="otp_import_manual_entry">Wprowadź ręcznie</string>
<string name="otp_import_manual_hint_secret">Sekret</string>
<string name="otp_import_manual_hint_account">Konto</string>
<string name="place_shortcut_on_home_screen">Utwórz skrót na pulpicie</string>
- <string name="password_list_fab_content_description">Utwórz nowe hasło lub folder</string>
<string name="pgp_key_import_failed">Nie udało się zaimportować klucza PGP</string>
<string name="pgp_key_import_failed_replace_message">Znaleziono istniejący klucz z tym identyfikatorem, czy chcesz go zastąpić?</string>
<string name="pgp_key_import_succeeded">Pomyślnie zaimportowano klucz PGP</string>
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 909fd33e..86ebfb24 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -39,7 +39,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copiado para a área de transferência</string>
<string name="file_toast_text">Por favor, informe um nome de arquivo</string>
- <string name="path_toast_text">Por favor, forneça o caminho do arquivo</string>
<string name="empty_toast_text">Você não pode usar uma senha vazia ou conteúdo extra vazio</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Ocorreu um erro durante uma operação do Git</string>
@@ -63,7 +62,6 @@
<string name="crypto_name_hint">Nome</string>
<string name="crypto_pass_label">Senha</string>
<string name="crypto_extra_label">Conteúdo extra</string>
- <string name="crypto_encrypt_username_label">Criptografar nome de usuário</string>
<string name="crypto_select">Selecionar</string>
<string name="crypto_save">Salvar</string>
<string name="crypto_save_and_copy">Salvar e Copiar</string>
@@ -125,7 +123,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Gerar Senha</string>
<string name="pwgen_generate">Gerar</string>
- <string name="pwgen_include">Incluir</string>
<string name="pwgen_length">Tamanho</string>
<string name="pwgen_numerals">Numerais</string>
<string name="pwgen_symbols">Símbolos</string>
@@ -173,7 +170,6 @@
<string name="git_log">Mostrar log de commit</string>
<string name="show_password_pref_title">Mostrar a senha</string>
<string name="show_password_pref_summary">Controle a visibilidade das senhas quando descriptografadas. Isso não desativa a cópia para a área de transferência.</string>
- <string name="pwd_generate_button">Gerar</string>
<string name="send_plaintext_password_to">Enviar senha como texto simples usando…</string>
<string name="app_icon_hint">Ícone do aplicativo</string>
<!-- Oreo Autofill -->
@@ -207,7 +203,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">Suporte ao preenchimento automático com navegadores instalados:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Não foi possível abrir a chave privada ssh, por favor verifique se o arquivo existe</string>
- <string name="new_password_title">Nova senha</string>
<string name="clear_saved_passphrase_ssh">Limpar a frase secreta salva para chave SSH local</string>
<string name="clear_saved_passphrase_https">Limpar senha HTTPS salva</string>
<string name="git_operation_remember_passphrase">Lembrar senha da chave</string>
@@ -276,7 +271,6 @@
<string name="invalid_gpg_id">Encontrado .gpg-id, mas contém um ID de chave, fingerprint ou ID de usuário inválidos</string>
<string name="short_gpg_id">Encontrado .gpg-id, mas contém uma ID hexadecimal curta, que não é suportada</string>
<string name="invalid_filename_text">Nome do arquivo não deve conter \'/\', defina o diretório acima</string>
- <string name="directory_hint">Diretório</string>
<!-- GitException messages -->
<string name="git_unknown_error">Erro desconhecido</string>
<string name="git_pull_rebase_fail_error">O pull falhou, você está em uma Head avulsa. Usando \"configurações &gt; utils\" do git, salve suas alterações no remoto em uma nova branch e resolva o conflito no seu computador.</string>
@@ -319,11 +313,9 @@
<string name="clear_saved_host_key_success">Chave de host limpa com sucesso!</string>
<string name="otp_import_qr_code">Escanear QR code</string>
<string name="otp_import_from_file">Selecione uma imagem</string>
- <string name="otp_import_manual_entry">Inserir manualmente</string>
<string name="otp_import_manual_hint_secret">Segredo</string>
<string name="otp_import_manual_hint_account">Conta</string>
<string name="place_shortcut_on_home_screen">Criar atalho na tela inicial</string>
- <string name="password_list_fab_content_description">Criar nova senha ou pasta</string>
<string name="pgp_key_import_failed">Falha ao importar a chave PGP</string>
<string name="pgp_key_import_failed_replace_message">Uma chave existente com esse ID foi encontrada, você deseja substituí-lo?</string>
<string name="pgp_key_import_succeeded">Chave PGP importada com sucesso</string>
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 2ef59d70..8873b34f 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -43,7 +43,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Скопировано в буфер обмена</string>
<string name="file_toast_text">Пожалуйста, укажите имя файла</string>
- <string name="path_toast_text">Пожалуйста, задайте путь к файлу</string>
<string name="empty_toast_text">Вы не можете использовать пустой пароль или пустое поле информации</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Произошла ошибка выполнения операции Git</string>
@@ -67,7 +66,6 @@
<string name="crypto_name_hint">название</string>
<string name="crypto_pass_label">Пароль</string>
<string name="crypto_extra_label">Дополнительно</string>
- <string name="crypto_encrypt_username_label">Зашифровать имя пользователя</string>
<string name="crypto_select">Выбрать</string>
<string name="crypto_save">Сохранить</string>
<string name="crypto_save_and_copy">Сохранить и скопировать</string>
@@ -118,7 +116,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Сгенерировать пароль</string>
<string name="pwgen_generate">Сгенерировать</string>
- <string name="pwgen_include">Включая</string>
<string name="pwgen_length">Длина</string>
<string name="pwgen_numerals">Цифры</string>
<string name="pwgen_symbols">Символы</string>
@@ -166,7 +163,6 @@
<string name="git_log">Показать журнал изменений</string>
<string name="show_password_pref_title">Показывать пароли</string>
<string name="show_password_pref_summary">Видимость расшифрованных паролей, не влияет на копирование в буфер.</string>
- <string name="pwd_generate_button">Сгенерировать</string>
<string name="send_plaintext_password_to">Поделиться паролем в открытом виде с помощью</string>
<string name="app_icon_hint">Иконка приложения</string>
<!-- Oreo Autofill -->
@@ -200,7 +196,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">Поддержка автозаполнения установленными браузерами:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Невозможно открыть приватный ключ ssh, пожалуйста проверьте, что файл существует</string>
- <string name="new_password_title">Новый пароль</string>
<string name="clear_saved_passphrase_ssh">Очистить сохраненную кодовую фразу для локального SSH ключа</string>
<string name="clear_saved_passphrase_https">Удалить сохраненный пароль HTTPS</string>
<string name="git_operation_remember_passphrase">Запомнить кодовую фразу</string>
@@ -268,7 +263,6 @@
<string name="exporting_passwords">Экспорт паролей…</string>
<string name="invalid_gpg_id">Найден .gpg-id, но он содержит неверный ID ключа, fingerprint или ID пользователя</string>
<string name="invalid_filename_text">Имя файла не должно содержать \'/\', укажите директорию выше</string>
- <string name="directory_hint">Директория</string>
<!-- GitException messages -->
<string name="git_unknown_error">Неизвестная ошибка</string>
<string name="git_pull_rebase_fail_error">Не удалось получить изменения, вы находитесь в состоянии \"оторванной головы\". Используйте \"настройки &gt; утилиты git\", сохраните ваши изменения в новую удаленную ветку и разрешите конфликты на своем компьютере.</string>
@@ -311,10 +305,8 @@
<string name="clear_saved_host_key_success">Сохраненный ключ хоста был успешно удален!</string>
<string name="otp_import_qr_code">Отсканировать QR-код</string>
<string name="otp_import_from_file">Выберите изображение</string>
- <string name="otp_import_manual_entry">Ввести вручную</string>
<string name="otp_import_manual_hint_account">Учетная запись</string>
<string name="place_shortcut_on_home_screen">Разместить ярлык на рабочем столе</string>
- <string name="password_list_fab_content_description">Создать новый пароль или папку</string>
<string name="pgp_key_import_failed">Не удалось импортировать PGP-ключ</string>
<string name="pgp_key_import_succeeded">PGP ключ успешно импортирован</string>
</resources>
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 55fbeefa..746b74d2 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -38,7 +38,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">复制到剪切板</string>
<string name="file_toast_text">请提供文件名</string>
- <string name="path_toast_text">请提供文件路径</string>
<string name="empty_toast_text">您不能使用空密码或空额外内容</string>
<!-- Git Async Task -->
<string name="jgit_error_dialog_title">Git操作过程中发生错误</string>
@@ -62,7 +61,6 @@
<string name="crypto_name_hint">名称</string>
<string name="crypto_pass_label">密码</string>
<string name="crypto_extra_label">附加内容</string>
- <string name="crypto_encrypt_username_label">加密用户名</string>
<string name="crypto_select">选择</string>
<string name="crypto_save">保存</string>
<string name="crypto_save_and_copy">保存并复制</string>
@@ -121,7 +119,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">生成密码</string>
<string name="pwgen_generate">生成</string>
- <string name="pwgen_include">包含</string>
<string name="pwgen_length">长度</string>
<string name="pwgen_numerals">数字</string>
<string name="pwgen_symbols">标识</string>
@@ -174,7 +171,6 @@
<string name="git_log">显示提交日志</string>
<string name="show_password_pref_title">显示密码</string>
<string name="show_password_pref_summary">控制密码解密后的可见性,这不会禁用复制到剪贴板</string>
- <string name="pwd_generate_button">生成</string>
<string name="send_plaintext_password_to">使用明文发送密码…</string>
<string name="app_icon_hint">应用图标</string>
<!-- Oreo Autofill -->
@@ -209,7 +205,6 @@
<string name="oreo_autofill_enable_dialog_installed_browsers">已安装支持自动填充的浏览器:</string>
<!-- Autofill -->
<string name="ssh_key_does_not_exist">无法打开SSH私钥,请检查文件是否存在</string>
- <string name="new_password_title">新密码</string>
<string name="clear_saved_passphrase_ssh">清除本地已保存的SSH密钥密码</string>
<string name="clear_saved_passphrase_https">清除保存的HTTPS密码</string>
<string name="git_operation_remember_passphrase">记住密钥密码</string>
@@ -278,7 +273,6 @@ personal.com</string>
<string name="invalid_gpg_id">找到了 .gpg-id,但它包含无效的密钥ID、指纹或用户ID</string>
<string name="short_gpg_id">找到 .gpg-id 但它包含一个不受支持的短十六进制ID。</string>
<string name="invalid_filename_text">文件名不能包含\'/\'</string>
- <string name="directory_hint">目录</string>
<!-- GitException messages -->
<string name="git_unknown_error">未知错误</string>
<string name="git_pull_merge_fail_error">合并失败,你处于冲突状态。</string>
@@ -324,11 +318,9 @@ GPG
<string name="clear_saved_host_key_success">已成功清除已保存的主机密钥!</string>
<string name="otp_import_qr_code">扫描二维码</string>
<string name="otp_import_from_file">选择图像</string>
- <string name="otp_import_manual_entry">手动输入</string>
<string name="otp_import_manual_hint_secret">安全码 (Secret)</string>
<string name="otp_import_manual_hint_account">账户</string>
<string name="place_shortcut_on_home_screen">在主屏幕上放置快捷方式</string>
- <string name="password_list_fab_content_description">创建新密码或文件夹</string>
<string name="pgp_key_import_failed">导入 PGP 密钥失败</string>
<string name="pgp_key_import_failed_replace_message">发现了 ID 相同的现有密钥,您要替换它吗?</string>
<string name="pgp_key_import_succeeded">成功导入 PGP 密钥</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 34b11662..239cb219 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -47,7 +47,6 @@
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copied to clipboard</string>
<string name="file_toast_text">Please provide a file name</string>
- <string name="path_toast_text">Please provide a file path</string>
<string name="empty_toast_text">You cannot use an empty password or empty extra content</string>
<!-- Git Async Task -->
@@ -79,7 +78,6 @@
<string name="crypto_username_hint">Username</string>
<string name="crypto_pass_label">Password</string>
<string name="crypto_extra_label">Extra content</string>
- <string name="crypto_encrypt_username_label">Encrypt username</string>
<string name="crypto_select">Select</string>
<string name="crypto_save">Save</string>
<string name="crypto_save_and_copy">Save and Copy</string>
@@ -148,7 +146,6 @@
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Generate Password</string>
<string name="pwgen_generate">Generate</string>
- <string name="pwgen_include">Include</string>
<string name="pwgen_length">Length</string>
<string name="pwgen_numerals">Numerals</string>
<string name="pwgen_symbols">Symbols</string>
@@ -201,7 +198,6 @@
<string name="git_log">Show commit log</string>
<string name="show_password_pref_title">Show the password</string>
<string name="show_password_pref_summary">Control the visibility of the passwords once decrypted. This does not disable copying to clipboard.</string>
- <string name="pwd_generate_button">Generate</string>
<string name="send_plaintext_password_to">Send password as plaintext using…</string>
<string name="app_icon_hint">App icon</string>
@@ -239,7 +235,6 @@
<!-- Autofill -->
<string name="ssh_key_does_not_exist">Unable to open the ssh private key, please check that the file exists</string>
- <string name="new_password_title">New password</string>
<string name="clear_saved_passphrase_ssh">Clear saved passphrase for local SSH key</string>
<string name="clear_saved_passphrase_https">Clear saved HTTPS password</string>
<string name="git_operation_remember_passphrase">Remember key passphrase</string>
@@ -311,7 +306,6 @@
<string name="invalid_gpg_id">Found .gpg-id, but it contains an invalid key ID, fingerprint or user ID</string>
<string name="short_gpg_id">Found .gpg-id, but it contains a short hex ID, which is not supported</string>
<string name="invalid_filename_text">File name must not contain \'/\', set directory above</string>
- <string name="directory_hint">Directory</string>
<!-- GitException messages -->
<string name="git_unknown_error">Unknown error</string>
@@ -360,11 +354,9 @@
<string name="clear_saved_host_key_success">Successfully cleared saved host key!</string>
<string name="otp_import_qr_code">Scan QR code</string>
<string name="otp_import_from_file">Choose an image</string>
- <string name="otp_import_manual_entry">Enter manually</string>
<string name="otp_import_manual_hint_secret">Secret</string>
<string name="otp_import_manual_hint_account">Account</string>
<string name="place_shortcut_on_home_screen">Place shortcut on home screen</string>
- <string name="password_list_fab_content_description">Create new password or folder</string>
<string name="pgp_key_import_failed">Failed to import PGP key</string>
<string name="pgp_key_import_failed_replace_message">An existing key with this ID was found, do you want to replace it?</string>
<string name="pgp_key_import_succeeded">Successfully imported PGP key</string>