Rework settings to use ModernAndroidPreferences (#1236)
Co-authored-by: Fabian Henneke <fabian@hen.ne.ke>
This commit is contained in:
parent
91e00d897f
commit
8bd156dea6
35 changed files with 1197 additions and 1108 deletions
|
@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file.
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Accessibility autofill has been removed completely due to being buggy, insecure and lacking in features. Upgrade to Android 8 or preferably later to gain access to our advanced Autofill implementation.
|
- Accessibility autofill has been removed completely due to being buggy, insecure and lacking in features. Upgrade to Android 8 or preferably later to gain access to our advanced Autofill implementation.
|
||||||
|
- The settings UI has been completely re-done to dramatically improve discoverability and navigation for users
|
||||||
|
|
||||||
## [1.13.1] - 2020-10-23
|
## [1.13.1] - 2020-10-23
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ dependencies {
|
||||||
|
|
||||||
implementation(Dependencies.FirstParty.zxing_android_embedded)
|
implementation(Dependencies.FirstParty.zxing_android_embedded)
|
||||||
|
|
||||||
|
implementation(Dependencies.ThirdParty.bouncycastle)
|
||||||
implementation(Dependencies.ThirdParty.commons_codec)
|
implementation(Dependencies.ThirdParty.commons_codec)
|
||||||
implementation(Dependencies.ThirdParty.eddsa)
|
implementation(Dependencies.ThirdParty.eddsa)
|
||||||
implementation(Dependencies.ThirdParty.fastscroll)
|
implementation(Dependencies.ThirdParty.fastscroll)
|
||||||
|
@ -80,10 +81,10 @@ dependencies {
|
||||||
exclude(group = "org.apache.httpcomponents", module = "httpclient")
|
exclude(group = "org.apache.httpcomponents", module = "httpclient")
|
||||||
}
|
}
|
||||||
implementation(Dependencies.ThirdParty.kotlin_result)
|
implementation(Dependencies.ThirdParty.kotlin_result)
|
||||||
implementation(Dependencies.ThirdParty.sshj)
|
implementation(Dependencies.ThirdParty.modern_android_prefs)
|
||||||
implementation(Dependencies.ThirdParty.bouncycastle)
|
|
||||||
implementation(Dependencies.ThirdParty.plumber)
|
implementation(Dependencies.ThirdParty.plumber)
|
||||||
implementation(Dependencies.ThirdParty.ssh_auth)
|
implementation(Dependencies.ThirdParty.ssh_auth)
|
||||||
|
implementation(Dependencies.ThirdParty.sshj)
|
||||||
implementation(Dependencies.ThirdParty.timber)
|
implementation(Dependencies.ThirdParty.timber)
|
||||||
implementation(Dependencies.ThirdParty.timberkt)
|
implementation(Dependencies.ThirdParty.timberkt)
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
android:name=".ui.onboarding.activity.OnboardingActivity"
|
android:name=".ui.onboarding.activity.OnboardingActivity"
|
||||||
android:configChanges="orientation|screenSize" />
|
android:configChanges="orientation|screenSize" />
|
||||||
|
|
||||||
<activity android:name=".ui.proxy.ProxySelectorActivity"
|
<activity
|
||||||
|
android:name=".ui.proxy.ProxySelectorActivity"
|
||||||
android:windowSoftInputMode="adjustResize" />
|
android:windowSoftInputMode="adjustResize" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
|
@ -70,8 +71,13 @@
|
||||||
android:label="@string/title_activity_git_log" />
|
android:label="@string/title_activity_git_log" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.settings.UserPreference"
|
android:name=".ui.settings.SettingsActivity"
|
||||||
android:label="@string/action_settings" />
|
android:label="@string/action_settings"
|
||||||
|
android:parentActivityName=".ui.passwords.PasswordStore" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".ui.settings.DirectorySelectionActivity"
|
||||||
|
android:theme="@style/NoBackgroundTheme" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.crypto.PasswordCreationActivity"
|
android:name=".ui.crypto.PasswordCreationActivity"
|
||||||
|
@ -104,6 +110,10 @@
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<activity android:name=".ui.folderselect.SelectFolderActivity" />
|
<activity android:name=".ui.folderselect.SelectFolderActivity" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.sshkeygen.SshKeyImportActivity"
|
||||||
|
android:theme="@style/NoBackgroundTheme"
|
||||||
|
android:windowSoftInputMode="adjustResize" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.sshkeygen.SshKeyGenActivity"
|
android:name=".ui.sshkeygen.SshKeyGenActivity"
|
||||||
android:label="@string/pref_ssh_keygen_title"
|
android:label="@string/pref_ssh_keygen_title"
|
||||||
|
|
|
@ -19,9 +19,9 @@ import com.github.michaelbull.result.onFailure
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.ui.settings.UserPreference
|
|
||||||
import dev.msfjarvis.aps.databinding.FragmentRepoLocationBinding
|
import dev.msfjarvis.aps.databinding.FragmentRepoLocationBinding
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
|
import dev.msfjarvis.aps.ui.settings.DirectorySelectionActivity
|
||||||
import dev.msfjarvis.aps.util.settings.PasswordSortOrder
|
import dev.msfjarvis.aps.util.settings.PasswordSortOrder
|
||||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
import dev.msfjarvis.aps.util.extensions.finish
|
import dev.msfjarvis.aps.util.extensions.finish
|
||||||
|
@ -31,11 +31,13 @@ import dev.msfjarvis.aps.util.extensions.listFilesRecursively
|
||||||
import dev.msfjarvis.aps.util.extensions.performTransactionWithBackStack
|
import dev.msfjarvis.aps.util.extensions.performTransactionWithBackStack
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
import dev.msfjarvis.aps.util.extensions.viewBinding
|
import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||||
|
import android.content.Intent
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||||
|
|
||||||
private val settings by lazy(LazyThreadSafetyMode.NONE) { requireActivity().applicationContext.sharedPrefs }
|
private val settings by lazy(LazyThreadSafetyMode.NONE) { requireActivity().applicationContext.sharedPrefs }
|
||||||
|
private val directorySelectIntent by lazy(LazyThreadSafetyMode.NONE) { Intent(requireContext(), DirectorySelectionActivity::class.java) }
|
||||||
private val binding by viewBinding(FragmentRepoLocationBinding::bind)
|
private val binding by viewBinding(FragmentRepoLocationBinding::bind)
|
||||||
private val sortOrder: PasswordSortOrder
|
private val sortOrder: PasswordSortOrder
|
||||||
get() = PasswordSortOrder.getSortOrder(settings)
|
get() = PasswordSortOrder.getSortOrder(settings)
|
||||||
|
@ -57,7 +59,7 @@ class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val externalDirPermGrantedAction = createPermGrantedAction {
|
private val externalDirPermGrantedAction = createPermGrantedAction {
|
||||||
externalDirectorySelectAction.launch(UserPreference.createDirectorySelectionIntent(requireContext()))
|
externalDirectorySelectAction.launch(directorySelectIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryUsePermGrantedAction = createPermGrantedAction {
|
private val repositoryUsePermGrantedAction = createPermGrantedAction {
|
||||||
|
@ -65,7 +67,7 @@ class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryChangePermGrantedAction = createPermGrantedAction {
|
private val repositoryChangePermGrantedAction = createPermGrantedAction {
|
||||||
repositoryInitAction.launch(UserPreference.createDirectorySelectionIntent(requireContext()))
|
repositoryInitAction.launch(directorySelectIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
@ -102,7 +104,7 @@ class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||||
} else {
|
} else {
|
||||||
// Unlikely we have storage permissions without user ever selecting a directory,
|
// Unlikely we have storage permissions without user ever selecting a directory,
|
||||||
// but let's not assume.
|
// but let's not assume.
|
||||||
externalDirectorySelectAction.launch(UserPreference.createDirectorySelectionIntent(requireContext()))
|
externalDirectorySelectAction.launch(directorySelectIntent)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MaterialAlertDialogBuilder(requireActivity())
|
MaterialAlertDialogBuilder(requireActivity())
|
||||||
|
@ -119,7 +121,7 @@ class RepoLocationFragment : Fragment(R.layout.fragment_repo_location) {
|
||||||
if (!isPermissionGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
if (!isPermissionGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||||
repositoryChangePermGrantedAction.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
repositoryChangePermGrantedAction.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
} else {
|
} else {
|
||||||
repositoryInitAction.launch(UserPreference.createDirectorySelectionIntent(requireContext()))
|
repositoryInitAction.launch(directorySelectIntent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
|
|
|
@ -11,8 +11,8 @@ import android.view.View
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.ui.settings.UserPreference
|
|
||||||
import dev.msfjarvis.aps.databinding.FragmentWelcomeBinding
|
import dev.msfjarvis.aps.databinding.FragmentWelcomeBinding
|
||||||
|
import dev.msfjarvis.aps.ui.settings.SettingsActivity
|
||||||
import dev.msfjarvis.aps.util.extensions.performTransactionWithBackStack
|
import dev.msfjarvis.aps.util.extensions.performTransactionWithBackStack
|
||||||
import dev.msfjarvis.aps.util.extensions.viewBinding
|
import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||||
|
|
||||||
|
@ -25,6 +25,6 @@ class WelcomeFragment : Fragment(R.layout.fragment_welcome) {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.letsGo.setOnClickListener { parentFragmentManager.performTransactionWithBackStack(CloneFragment.newInstance()) }
|
binding.letsGo.setOnClickListener { parentFragmentManager.performTransactionWithBackStack(CloneFragment.newInstance()) }
|
||||||
binding.settingsButton.setOnClickListener { startActivity(Intent(requireContext(), UserPreference::class.java)) }
|
binding.settingsButton.setOnClickListener { startActivity(Intent(requireContext(), SettingsActivity::class.java)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ import dev.msfjarvis.aps.ui.main.LaunchActivity
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.util.viewmodel.SearchableRepositoryViewModel
|
import dev.msfjarvis.aps.util.viewmodel.SearchableRepositoryViewModel
|
||||||
import dev.msfjarvis.aps.ui.folderselect.SelectFolderActivity
|
import dev.msfjarvis.aps.ui.folderselect.SelectFolderActivity
|
||||||
import dev.msfjarvis.aps.ui.settings.UserPreference
|
|
||||||
import dev.msfjarvis.aps.util.autofill.AutofillMatcher
|
import dev.msfjarvis.aps.util.autofill.AutofillMatcher
|
||||||
import dev.msfjarvis.aps.ui.crypto.BasePgpActivity.Companion.getLongName
|
import dev.msfjarvis.aps.ui.crypto.BasePgpActivity.Companion.getLongName
|
||||||
import dev.msfjarvis.aps.ui.crypto.DecryptActivity
|
import dev.msfjarvis.aps.ui.crypto.DecryptActivity
|
||||||
|
@ -55,6 +54,8 @@ import dev.msfjarvis.aps.ui.dialogs.FolderCreationDialogFragment
|
||||||
import dev.msfjarvis.aps.ui.onboarding.activity.OnboardingActivity
|
import dev.msfjarvis.aps.ui.onboarding.activity.OnboardingActivity
|
||||||
import dev.msfjarvis.aps.data.password.PasswordItem
|
import dev.msfjarvis.aps.data.password.PasswordItem
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
|
import dev.msfjarvis.aps.ui.settings.DirectorySelectionActivity
|
||||||
|
import dev.msfjarvis.aps.ui.settings.SettingsActivity
|
||||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
import dev.msfjarvis.aps.util.extensions.base64
|
import dev.msfjarvis.aps.util.extensions.base64
|
||||||
import dev.msfjarvis.aps.util.extensions.commitChange
|
import dev.msfjarvis.aps.util.extensions.commitChange
|
||||||
|
@ -300,7 +301,7 @@ class PasswordStore : BaseGitActivity() {
|
||||||
when (id) {
|
when (id) {
|
||||||
R.id.user_pref -> {
|
R.id.user_pref -> {
|
||||||
runCatching {
|
runCatching {
|
||||||
startActivity(Intent(this, UserPreference::class.java))
|
startActivity(Intent(this, SettingsActivity::class.java))
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
@ -377,7 +378,7 @@ class PasswordStore : BaseGitActivity() {
|
||||||
private fun checkLocalRepository() {
|
private fun checkLocalRepository() {
|
||||||
val repo = PasswordRepository.initialize()
|
val repo = PasswordRepository.initialize()
|
||||||
if (repo == null) {
|
if (repo == null) {
|
||||||
directorySelectAction.launch(UserPreference.createDirectorySelectionIntent(this))
|
directorySelectAction.launch(Intent(this, DirectorySelectionActivity::class.java))
|
||||||
} else {
|
} else {
|
||||||
checkLocalRepository(PasswordRepository.getRepositoryDirectory())
|
checkLocalRepository(PasswordRepository.getRepositoryDirectory())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.editText
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onClick
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.singleChoice
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.switch
|
||||||
|
import de.Maxr1998.modernpreferences.preferences.SwitchPreference
|
||||||
|
import de.Maxr1998.modernpreferences.preferences.choice.SelectionItem
|
||||||
|
import dev.msfjarvis.aps.BuildConfig
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.util.autofill.DirectoryStructure
|
||||||
|
import dev.msfjarvis.aps.util.extensions.autofillManager
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.Settings
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
|
import com.github.androidpasswordstore.autofillparser.BrowserAutofillSupportLevel
|
||||||
|
import com.github.androidpasswordstore.autofillparser.getInstalledBrowsersWithAutofillSupportLevel
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
class AutofillSettings(private val activity: FragmentActivity) : SettingsProvider {
|
||||||
|
|
||||||
|
private val isAutofillServiceEnabled: Boolean
|
||||||
|
get() {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false
|
||||||
|
return activity.autofillManager?.hasEnabledAutofillServices() == true
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
private fun showAutofillDialog(pref: SwitchPreference) {
|
||||||
|
val observer = LifecycleEventObserver { _, event ->
|
||||||
|
when (event) {
|
||||||
|
Lifecycle.Event.ON_RESUME -> {
|
||||||
|
pref.checked = isAutofillServiceEnabled
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaterialAlertDialogBuilder(activity).run {
|
||||||
|
setTitle(R.string.pref_autofill_enable_title)
|
||||||
|
@SuppressLint("InflateParams")
|
||||||
|
val layout =
|
||||||
|
activity.layoutInflater.inflate(R.layout.oreo_autofill_instructions, null)
|
||||||
|
val supportedBrowsersTextView =
|
||||||
|
layout.findViewById<AppCompatTextView>(R.id.supportedBrowsers)
|
||||||
|
supportedBrowsersTextView.text =
|
||||||
|
getInstalledBrowsersWithAutofillSupportLevel(context).joinToString(
|
||||||
|
separator = "\n"
|
||||||
|
) {
|
||||||
|
val appLabel = it.first
|
||||||
|
val supportDescription = when (it.second) {
|
||||||
|
BrowserAutofillSupportLevel.None -> activity.getString(R.string.oreo_autofill_no_support)
|
||||||
|
BrowserAutofillSupportLevel.FlakyFill -> activity.getString(R.string.oreo_autofill_flaky_fill_support)
|
||||||
|
BrowserAutofillSupportLevel.PasswordFill -> activity.getString(R.string.oreo_autofill_password_fill_support)
|
||||||
|
BrowserAutofillSupportLevel.PasswordFillAndSaveIfNoAccessibility -> activity.getString(R.string.oreo_autofill_password_fill_and_conditional_save_support)
|
||||||
|
BrowserAutofillSupportLevel.GeneralFill -> activity.getString(R.string.oreo_autofill_general_fill_support)
|
||||||
|
BrowserAutofillSupportLevel.GeneralFillAndSave -> activity.getString(R.string.oreo_autofill_general_fill_and_save_support)
|
||||||
|
}
|
||||||
|
"$appLabel: $supportDescription"
|
||||||
|
}
|
||||||
|
setView(layout)
|
||||||
|
setPositiveButton(R.string.dialog_ok) { _, _ ->
|
||||||
|
val intent = Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE).apply {
|
||||||
|
data = Uri.parse("package:${BuildConfig.APPLICATION_ID}")
|
||||||
|
}
|
||||||
|
activity.startActivity(intent)
|
||||||
|
}
|
||||||
|
setNegativeButton(R.string.dialog_cancel, null)
|
||||||
|
setOnDismissListener { pref.checked = isAutofillServiceEnabled }
|
||||||
|
activity.lifecycle.addObserver(observer)
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun provideSettings(builder: PreferenceScreen.Builder) {
|
||||||
|
builder.apply {
|
||||||
|
switch(PreferenceKeys.AUTOFILL_ENABLE) {
|
||||||
|
titleRes = R.string.pref_autofill_enable_title
|
||||||
|
visible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||||
|
defaultValue = isAutofillServiceEnabled
|
||||||
|
onClick {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return@onClick true
|
||||||
|
if (isAutofillServiceEnabled) {
|
||||||
|
activity.autofillManager?.disableAutofillServices()
|
||||||
|
} else {
|
||||||
|
showAutofillDialog(this)
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val values = activity.resources.getStringArray(R.array.oreo_autofill_directory_structure_values)
|
||||||
|
val titles = activity.resources.getStringArray(R.array.oreo_autofill_directory_structure_entries)
|
||||||
|
val items = values.zip(titles).map { SelectionItem(it.first, it.second, null) }
|
||||||
|
singleChoice(PreferenceKeys.OREO_AUTOFILL_DIRECTORY_STRUCTURE, items) {
|
||||||
|
initialSelection = DirectoryStructure.DEFAULT.value
|
||||||
|
dependency = PreferenceKeys.AUTOFILL_ENABLE
|
||||||
|
titleRes = R.string.oreo_autofill_preference_directory_structure
|
||||||
|
}
|
||||||
|
editText(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME) {
|
||||||
|
dependency = PreferenceKeys.AUTOFILL_ENABLE
|
||||||
|
titleRes = R.string.preference_default_username_title
|
||||||
|
summaryProvider = { activity.getString(R.string.preference_default_username_summary) }
|
||||||
|
}
|
||||||
|
editText(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES) {
|
||||||
|
dependency = PreferenceKeys.AUTOFILL_ENABLE
|
||||||
|
titleRes = R.string.preference_custom_public_suffixes_title
|
||||||
|
summaryProvider = { activity.getString(R.string.preference_custom_public_suffixes_summary) }
|
||||||
|
textInputHintRes = R.string.preference_custom_public_suffixes_hint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Environment
|
||||||
|
import android.provider.DocumentsContract
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import com.github.ajalt.timberkt.d
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
class DirectorySelectionActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
private val directorySelectAction = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri: Uri? ->
|
||||||
|
if (uri == null) return@registerForActivityResult
|
||||||
|
|
||||||
|
d { "Selected repository URI is $uri" }
|
||||||
|
// TODO: This is fragile. Workaround until PasswordItem is backed by DocumentFile
|
||||||
|
val docId = DocumentsContract.getTreeDocumentId(uri)
|
||||||
|
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||||
|
val path = if (split.size > 1) split[1] else split[0]
|
||||||
|
val repoPath = "${Environment.getExternalStorageDirectory()}/$path"
|
||||||
|
val prefs = sharedPrefs
|
||||||
|
|
||||||
|
d { "Selected repository path is $repoPath" }
|
||||||
|
|
||||||
|
if (Environment.getExternalStorageDirectory().path == repoPath) {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(resources.getString(R.string.sdcard_root_warning_title))
|
||||||
|
.setMessage(resources.getString(R.string.sdcard_root_warning_message))
|
||||||
|
.setPositiveButton(resources.getString(R.string.sdcard_root_warning_remove_everything)) { _, _ ->
|
||||||
|
prefs.edit { putString(PreferenceKeys.GIT_EXTERNAL_REPO, uri.path) }
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.dialog_cancel, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
prefs.edit { putString(PreferenceKeys.GIT_EXTERNAL_REPO, repoPath) }
|
||||||
|
setResult(RESULT_OK)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
directorySelectAction.launch(null)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.checkBox
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onClick
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.singleChoice
|
||||||
|
import de.Maxr1998.modernpreferences.preferences.choice.SelectionItem
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.util.auth.BiometricAuthenticator
|
||||||
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import android.content.pm.ShortcutManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
|
||||||
|
class GeneralSettings(private val activity: FragmentActivity) : SettingsProvider {
|
||||||
|
|
||||||
|
override fun provideSettings(builder: PreferenceScreen.Builder) {
|
||||||
|
builder.apply {
|
||||||
|
val themeValues = activity.resources.getStringArray(R.array.app_theme_values)
|
||||||
|
val themeOptions = activity.resources.getStringArray(R.array.app_theme_options)
|
||||||
|
val themeItems = themeValues.zip(themeOptions).map { SelectionItem(it.first, it.second, null) }
|
||||||
|
singleChoice(PreferenceKeys.APP_THEME, themeItems) {
|
||||||
|
initialSelection = activity.resources.getString(R.string.app_theme_def)
|
||||||
|
titleRes = R.string.pref_app_theme_title
|
||||||
|
}
|
||||||
|
|
||||||
|
val sortValues = activity.resources.getStringArray(R.array.sort_order_values)
|
||||||
|
val sortOptions = activity.resources.getStringArray(R.array.sort_order_entries)
|
||||||
|
val sortItems = sortValues.zip(sortOptions).map { SelectionItem(it.first, it.second, null) }
|
||||||
|
singleChoice(PreferenceKeys.SORT_ORDER, sortItems) {
|
||||||
|
initialSelection = sortValues[0]
|
||||||
|
titleRes = R.string.pref_sort_order_title
|
||||||
|
}
|
||||||
|
|
||||||
|
checkBox(PreferenceKeys.FILTER_RECURSIVELY) {
|
||||||
|
titleRes = R.string.pref_recursive_filter_title
|
||||||
|
summaryRes = R.string.pref_recursive_filter_summary
|
||||||
|
defaultValue = true
|
||||||
|
}
|
||||||
|
|
||||||
|
checkBox(PreferenceKeys.SEARCH_ON_START) {
|
||||||
|
titleRes = R.string.pref_search_on_start_title
|
||||||
|
summaryRes = R.string.pref_search_on_start_summary
|
||||||
|
defaultValue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
checkBox(PreferenceKeys.SHOW_HIDDEN_CONTENTS) {
|
||||||
|
titleRes = R.string.pref_show_hidden_title
|
||||||
|
summaryRes = R.string.pref_show_hidden_summary
|
||||||
|
defaultValue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
checkBox(PreferenceKeys.BIOMETRIC_AUTH) {
|
||||||
|
titleRes = R.string.pref_biometric_auth_title
|
||||||
|
defaultValue = false
|
||||||
|
}.apply {
|
||||||
|
val canAuthenticate = BiometricAuthenticator.canAuthenticate(activity)
|
||||||
|
if (!canAuthenticate) {
|
||||||
|
enabled = false
|
||||||
|
checked = false
|
||||||
|
summaryRes = R.string.pref_biometric_auth_summary_error
|
||||||
|
} else {
|
||||||
|
summaryRes = R.string.pref_biometric_auth_summary
|
||||||
|
onClick {
|
||||||
|
enabled = false
|
||||||
|
val isChecked = checked
|
||||||
|
activity.sharedPrefs.edit {
|
||||||
|
BiometricAuthenticator.authenticate(activity) { result ->
|
||||||
|
when (result) {
|
||||||
|
is BiometricAuthenticator.Result.Success -> {
|
||||||
|
// Apply the changes
|
||||||
|
putBoolean(PreferenceKeys.BIOMETRIC_AUTH, checked)
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// If any error occurs, revert back to the previous state. This
|
||||||
|
// catch-all clause includes the cancellation case.
|
||||||
|
putBoolean(PreferenceKeys.BIOMETRIC_AUTH, !checked)
|
||||||
|
checked = !isChecked
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||||
|
activity.getSystemService<ShortcutManager>()?.apply {
|
||||||
|
removeDynamicShortcuts(dynamicShortcuts.map { it.id }.toMutableList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.checkBox
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onClick
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.pref
|
||||||
|
import dev.msfjarvis.aps.BuildConfig
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.util.services.PasswordExportService
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.documentfile.provider.DocumentFile
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
|
||||||
|
class MiscSettings(activity: FragmentActivity) : SettingsProvider {
|
||||||
|
|
||||||
|
private val storeExportAction = activity.registerForActivityResult(object : ActivityResultContracts.OpenDocumentTree() {
|
||||||
|
override fun createIntent(context: Context, input: Uri?): Intent {
|
||||||
|
return super.createIntent(context, input).apply {
|
||||||
|
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||||
|
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
|
||||||
|
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
|
||||||
|
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) { uri: Uri? ->
|
||||||
|
if (uri == null) return@registerForActivityResult
|
||||||
|
val targetDirectory = DocumentFile.fromTreeUri(activity.applicationContext, uri)
|
||||||
|
|
||||||
|
if (targetDirectory != null) {
|
||||||
|
val service = Intent(activity.applicationContext, PasswordExportService::class.java).apply {
|
||||||
|
action = PasswordExportService.ACTION_EXPORT_PASSWORD
|
||||||
|
putExtra("uri", uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
activity.startForegroundService(service)
|
||||||
|
} else {
|
||||||
|
activity.startService(service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun provideSettings(builder: PreferenceScreen.Builder) {
|
||||||
|
builder.apply {
|
||||||
|
pref(PreferenceKeys.EXPORT_PASSWORDS) {
|
||||||
|
titleRes = R.string.prefs_export_passwords_title
|
||||||
|
summaryRes = R.string.prefs_export_passwords_summary
|
||||||
|
onClick {
|
||||||
|
storeExportAction.launch(null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkBox(PreferenceKeys.CLEAR_CLIPBOARD_20X) {
|
||||||
|
defaultValue = false
|
||||||
|
titleRes = R.string.pref_clear_clipboard_title
|
||||||
|
summaryRes = R.string.pref_clear_clipboard_summary
|
||||||
|
}
|
||||||
|
checkBox(PreferenceKeys.ENABLE_DEBUG_LOGGING) {
|
||||||
|
defaultValue = false
|
||||||
|
titleRes = R.string.pref_debug_logging_title
|
||||||
|
summaryRes = R.string.pref_debug_logging_summary
|
||||||
|
visible = !BuildConfig.DEBUG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.Preference
|
||||||
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.categoryHeader
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.checkBox
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.editText
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onCheckedChange
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onClick
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onSelectionChange
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.singleChoice
|
||||||
|
import de.Maxr1998.modernpreferences.preferences.CheckBoxPreference
|
||||||
|
import de.Maxr1998.modernpreferences.preferences.choice.SelectionItem
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
|
import dev.msfjarvis.aps.util.pwgenxkpwd.XkpwdDictionary
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import android.text.InputType
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class PasswordSettings(private val activity: FragmentActivity) : SettingsProvider {
|
||||||
|
|
||||||
|
private val sharedPrefs by lazy(LazyThreadSafetyMode.NONE) { activity.sharedPrefs }
|
||||||
|
private val storeCustomXkpwdDictionaryAction = activity.registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
|
||||||
|
if (uri == null) return@registerForActivityResult
|
||||||
|
|
||||||
|
Toast.makeText(
|
||||||
|
activity,
|
||||||
|
activity.resources.getString(R.string.xkpwgen_custom_dict_imported, uri.path),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
|
||||||
|
sharedPrefs.edit { putString(PreferenceKeys.PREF_KEY_CUSTOM_DICT, uri.toString()) }
|
||||||
|
|
||||||
|
val inputStream = activity.contentResolver.openInputStream(uri)
|
||||||
|
val customDictFile = File(activity.filesDir.toString(), XkpwdDictionary.XKPWD_CUSTOM_DICT_FILE).outputStream()
|
||||||
|
inputStream?.copyTo(customDictFile, 1024)
|
||||||
|
inputStream?.close()
|
||||||
|
customDictFile.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun provideSettings(builder: PreferenceScreen.Builder) {
|
||||||
|
builder.apply {
|
||||||
|
val customDictPref = CheckBoxPreference(PreferenceKeys.PREF_KEY_IS_CUSTOM_DICT).apply {
|
||||||
|
titleRes = R.string.pref_xkpwgen_custom_wordlist_enabled_title
|
||||||
|
summaryRes = R.string.pref_xkpwgen_custom_dict_summary_off
|
||||||
|
summaryOnRes = R.string.pref_xkpwgen_custom_dict_summary_on
|
||||||
|
visible = sharedPrefs.getString(PreferenceKeys.PREF_KEY_PWGEN_TYPE) == "xkpasswd"
|
||||||
|
onCheckedChange {
|
||||||
|
requestRebind()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val customDictPathPref = Preference(PreferenceKeys.PREF_KEY_CUSTOM_DICT).apply {
|
||||||
|
dependency = PreferenceKeys.PREF_KEY_IS_CUSTOM_DICT
|
||||||
|
titleRes = R.string.pref_xkpwgen_custom_dict_picker_title
|
||||||
|
summary = sharedPrefs.getString(PreferenceKeys.PREF_KEY_CUSTOM_DICT)
|
||||||
|
?: activity.resources.getString(R.string.pref_xkpwgen_custom_dict_picker_summary)
|
||||||
|
visible = sharedPrefs.getString(PreferenceKeys.PREF_KEY_PWGEN_TYPE) == "xkpasswd"
|
||||||
|
onClick {
|
||||||
|
storeCustomXkpwdDictionaryAction.launch(arrayOf("*/*"))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val values = activity.resources.getStringArray(R.array.pwgen_provider_values)
|
||||||
|
val labels = activity.resources.getStringArray(R.array.pwgen_provider_labels)
|
||||||
|
val items = values.zip(labels).map { SelectionItem(it.first, it.second, null) }
|
||||||
|
singleChoice(
|
||||||
|
PreferenceKeys.PREF_KEY_PWGEN_TYPE,
|
||||||
|
items,
|
||||||
|
) {
|
||||||
|
initialSelection = "classic"
|
||||||
|
titleRes = R.string.pref_password_generator_type_title
|
||||||
|
onSelectionChange { selection ->
|
||||||
|
val xkpasswdEnabled = selection == "xkpasswd"
|
||||||
|
customDictPathPref.visible = xkpasswdEnabled
|
||||||
|
customDictPref.visible = xkpasswdEnabled
|
||||||
|
customDictPref.requestRebind()
|
||||||
|
customDictPathPref.requestRebind()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We initialize them early and add them manually to be able to manually force a rebind
|
||||||
|
// when the password generator type is changed.
|
||||||
|
addPreferenceItem(customDictPref)
|
||||||
|
addPreferenceItem(customDictPathPref)
|
||||||
|
editText(PreferenceKeys.GENERAL_SHOW_TIME) {
|
||||||
|
titleRes = R.string.pref_clipboard_timeout_title
|
||||||
|
summaryProvider = { activity.getString(R.string.pref_clipboard_timeout_summary) }
|
||||||
|
textInputType = InputType.TYPE_CLASS_NUMBER
|
||||||
|
}
|
||||||
|
checkBox(PreferenceKeys.SHOW_PASSWORD) {
|
||||||
|
titleRes = R.string.show_password_pref_title
|
||||||
|
summaryRes = R.string.show_password_pref_summary
|
||||||
|
defaultValue = true
|
||||||
|
}
|
||||||
|
checkBox(PreferenceKeys.SHOW_EXTRA_CONTENT) {
|
||||||
|
titleRes = R.string.show_extra_content_pref_title
|
||||||
|
summaryRes = R.string.show_extra_content_pref_summary
|
||||||
|
defaultValue = true
|
||||||
|
}
|
||||||
|
checkBox(PreferenceKeys.COPY_ON_DECRYPT) {
|
||||||
|
titleRes = R.string.pref_copy_title
|
||||||
|
summaryRes = R.string.pref_copy_summary
|
||||||
|
defaultValue = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.Preference
|
||||||
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.checkBox
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onCheckedChange
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.onClick
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.pref
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
|
import dev.msfjarvis.aps.ui.git.config.GitConfigActivity
|
||||||
|
import dev.msfjarvis.aps.ui.git.config.GitServerConfigActivity
|
||||||
|
import dev.msfjarvis.aps.ui.proxy.ProxySelectorActivity
|
||||||
|
import dev.msfjarvis.aps.ui.sshkeygen.ShowSshKeyFragment
|
||||||
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
||||||
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyImportActivity
|
||||||
|
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
|
||||||
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
|
import dev.msfjarvis.aps.util.extensions.snackbar
|
||||||
|
import dev.msfjarvis.aps.util.settings.GitSettings
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ShortcutManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import com.github.michaelbull.result.onFailure
|
||||||
|
import com.github.michaelbull.result.runCatching
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
class RepositorySettings(private val activity: FragmentActivity) : SettingsProvider {
|
||||||
|
|
||||||
|
private val encryptedPreferences by lazy(LazyThreadSafetyMode.NONE) { activity.getEncryptedGitPrefs() }
|
||||||
|
|
||||||
|
private fun <T : FragmentActivity> launchActivity(clazz: Class<T>) {
|
||||||
|
activity.startActivity(Intent(activity, clazz))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectExternalGitRepository() {
|
||||||
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setTitle(activity.resources.getString(R.string.external_repository_dialog_title))
|
||||||
|
.setMessage(activity.resources.getString(R.string.external_repository_dialog_text))
|
||||||
|
.setPositiveButton(R.string.dialog_ok) { _, _ ->
|
||||||
|
launchActivity(DirectorySelectionActivity::class.java)
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.dialog_cancel, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun provideSettings(builder: PreferenceScreen.Builder) {
|
||||||
|
builder.apply {
|
||||||
|
pref(PreferenceKeys.GIT_SERVER_INFO) {
|
||||||
|
titleRes = R.string.pref_edit_git_server_settings
|
||||||
|
visible = PasswordRepository.isGitRepo()
|
||||||
|
onClick {
|
||||||
|
launchActivity(GitServerConfigActivity::class.java)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.PROXY_SETTINGS) {
|
||||||
|
titleRes = R.string.pref_edit_proxy_settings
|
||||||
|
visible = GitSettings.url?.startsWith("https") == true && PasswordRepository.isGitRepo()
|
||||||
|
onClick {
|
||||||
|
launchActivity(ProxySelectorActivity::class.java)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.GIT_CONFIG) {
|
||||||
|
titleRes = R.string.pref_edit_git_config
|
||||||
|
visible = PasswordRepository.isGitRepo()
|
||||||
|
onClick {
|
||||||
|
launchActivity(GitConfigActivity::class.java)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.SSH_KEY) {
|
||||||
|
titleRes = R.string.pref_import_ssh_key_title
|
||||||
|
visible = PasswordRepository.isGitRepo()
|
||||||
|
onClick {
|
||||||
|
launchActivity(SshKeyImportActivity::class.java)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.SSH_KEYGEN) {
|
||||||
|
titleRes = R.string.pref_ssh_keygen_title
|
||||||
|
onClick {
|
||||||
|
launchActivity(SshKeyGenActivity::class.java)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.SSH_SEE_KEY) {
|
||||||
|
titleRes = R.string.pref_ssh_see_key_title
|
||||||
|
visible = PasswordRepository.isGitRepo()
|
||||||
|
onClick {
|
||||||
|
ShowSshKeyFragment().show(activity.supportFragmentManager, "public_key")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.CLEAR_SAVED_PASS) {
|
||||||
|
fun Preference.updatePref() {
|
||||||
|
val sshPass = encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE)
|
||||||
|
val httpsPass = encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD)
|
||||||
|
if (sshPass == null && httpsPass == null) {
|
||||||
|
visible = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
when {
|
||||||
|
httpsPass != null -> titleRes = R.string.clear_saved_passphrase_https
|
||||||
|
sshPass != null -> titleRes = R.string.clear_saved_passphrase_ssh
|
||||||
|
}
|
||||||
|
visible = true
|
||||||
|
requestRebind()
|
||||||
|
}
|
||||||
|
onClick {
|
||||||
|
updatePref()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
updatePref()
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.SSH_OPENKEYSTORE_CLEAR_KEY_ID) {
|
||||||
|
titleRes = R.string.pref_title_openkeystore_clear_keyid
|
||||||
|
visible = activity.sharedPrefs.getString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID)?.isNotEmpty()
|
||||||
|
?: false
|
||||||
|
onClick {
|
||||||
|
activity.sharedPrefs.edit { putString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID, null) }
|
||||||
|
visible = false
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val deleteRepoPref = pref(PreferenceKeys.GIT_DELETE_REPO) {
|
||||||
|
titleRes = R.string.pref_git_delete_repo_title
|
||||||
|
summaryRes = R.string.pref_git_delete_repo_summary
|
||||||
|
visible = !activity.sharedPrefs.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)
|
||||||
|
onClick {
|
||||||
|
val repoDir = PasswordRepository.getRepositoryDirectory()
|
||||||
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.pref_dialog_delete_title)
|
||||||
|
.setMessage(activity.getString(R.string.dialog_delete_msg, repoDir))
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton(R.string.dialog_delete) { dialogInterface, _ ->
|
||||||
|
runCatching {
|
||||||
|
PasswordRepository.getRepositoryDirectory().deleteRecursively()
|
||||||
|
PasswordRepository.closeRepository()
|
||||||
|
}.onFailure {
|
||||||
|
it.message?.let { message ->
|
||||||
|
activity.snackbar(message = message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||||
|
activity.getSystemService<ShortcutManager>()?.apply {
|
||||||
|
removeDynamicShortcuts(dynamicShortcuts.map { it.id }.toMutableList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
activity.sharedPrefs.edit { putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false) }
|
||||||
|
dialogInterface.cancel()
|
||||||
|
activity.finish()
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.dialog_do_not_delete) { dialogInterface, _ -> run { dialogInterface.cancel() } }
|
||||||
|
.show()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkBox(PreferenceKeys.GIT_EXTERNAL) {
|
||||||
|
titleRes = R.string.pref_external_repository_title
|
||||||
|
summaryRes = R.string.pref_external_repository_summary
|
||||||
|
onCheckedChange { checked ->
|
||||||
|
deleteRepoPref.visible = !checked
|
||||||
|
deleteRepoPref.requestRebind()
|
||||||
|
PasswordRepository.closeRepository()
|
||||||
|
activity.sharedPrefs.edit { putBoolean(PreferenceKeys.REPO_CHANGED, true) }
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pref(PreferenceKeys.GIT_EXTERNAL_REPO) {
|
||||||
|
val externalRepo = activity.sharedPrefs.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
|
||||||
|
if (externalRepo != null) {
|
||||||
|
summary = externalRepo
|
||||||
|
} else {
|
||||||
|
summaryRes = R.string.pref_select_external_repository_summary_no_repo_selected
|
||||||
|
}
|
||||||
|
titleRes = R.string.pref_select_external_repository_title
|
||||||
|
dependency = PreferenceKeys.GIT_EXTERNAL
|
||||||
|
onClick {
|
||||||
|
selectExternalGitRepository()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.PreferencesAdapter
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.screen
|
||||||
|
import de.Maxr1998.modernpreferences.helpers.subScreen
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.databinding.ActivityPreferenceRecyclerviewBinding
|
||||||
|
import dev.msfjarvis.aps.util.extensions.viewBinding
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
class SettingsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private val miscSettings = MiscSettings(this)
|
||||||
|
private val autofillSettings = AutofillSettings(this)
|
||||||
|
private val passwordSettings = PasswordSettings(this)
|
||||||
|
private val repositorySettings = RepositorySettings(this)
|
||||||
|
private val generalSettings = GeneralSettings(this)
|
||||||
|
|
||||||
|
private val binding by viewBinding(ActivityPreferenceRecyclerviewBinding::inflate)
|
||||||
|
private val preferencesAdapter: PreferencesAdapter
|
||||||
|
get() = binding.preferenceRecyclerView.adapter as PreferencesAdapter
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(binding.root)
|
||||||
|
val screen = screen(this) {
|
||||||
|
subScreen {
|
||||||
|
titleRes = R.string.pref_category_general_title
|
||||||
|
iconRes = R.drawable.app_settings_alt_24px
|
||||||
|
generalSettings.provideSettings(this)
|
||||||
|
}
|
||||||
|
subScreen {
|
||||||
|
titleRes = R.string.pref_category_autofill_title
|
||||||
|
iconRes = R.drawable.ic_wysiwyg_24px
|
||||||
|
autofillSettings.provideSettings(this)
|
||||||
|
}
|
||||||
|
subScreen {
|
||||||
|
titleRes = R.string.pref_category_passwords_title
|
||||||
|
iconRes = R.drawable.ic_lock_open_24px
|
||||||
|
passwordSettings.provideSettings(this)
|
||||||
|
}
|
||||||
|
subScreen {
|
||||||
|
titleRes = R.string.pref_category_repository_title
|
||||||
|
iconRes = R.drawable.ic_call_merge_24px
|
||||||
|
repositorySettings.provideSettings(this)
|
||||||
|
}
|
||||||
|
subScreen {
|
||||||
|
titleRes = R.string.pref_category_misc_title
|
||||||
|
iconRes = R.drawable.ic_miscellaneous_services_24px
|
||||||
|
miscSettings.provideSettings(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val adapter = PreferencesAdapter(screen)
|
||||||
|
adapter.onScreenChangeListener = PreferencesAdapter.OnScreenChangeListener { subScreen, entering ->
|
||||||
|
supportActionBar?.title = if (!entering) {
|
||||||
|
getString(R.string.action_settings)
|
||||||
|
} else {
|
||||||
|
getString(subScreen.titleRes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
savedInstanceState?.getParcelable<PreferencesAdapter.SavedState>("adapter")
|
||||||
|
?.let(adapter::loadSavedState)
|
||||||
|
binding.preferenceRecyclerView.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
outState.putParcelable("adapter", preferencesAdapter.getSavedState())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
android.R.id.home -> if (!preferencesAdapter.goBack()) {
|
||||||
|
super.onOptionsItemSelected(item)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed() {
|
||||||
|
if (!preferencesAdapter.goBack())
|
||||||
|
super.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.settings
|
||||||
|
|
||||||
|
import de.Maxr1998.modernpreferences.PreferenceScreen
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to generate a uniform API for all settings UI classes.
|
||||||
|
*/
|
||||||
|
interface SettingsProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the settings items for the class into the given [builder].
|
||||||
|
*/
|
||||||
|
fun provideSettings(builder: PreferenceScreen.Builder)
|
||||||
|
}
|
|
@ -1,674 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
*/
|
|
||||||
package dev.msfjarvis.aps.ui.settings
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.content.pm.ShortcutManager
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Environment
|
|
||||||
import android.provider.DocumentsContract
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.text.TextUtils
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.OpenDocument
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.OpenDocumentTree
|
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
|
||||||
import androidx.core.content.edit
|
|
||||||
import androidx.core.content.getSystemService
|
|
||||||
import androidx.documentfile.provider.DocumentFile
|
|
||||||
import androidx.preference.CheckBoxPreference
|
|
||||||
import androidx.preference.EditTextPreference
|
|
||||||
import androidx.preference.ListPreference
|
|
||||||
import androidx.preference.Preference
|
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
|
||||||
import androidx.preference.SwitchPreferenceCompat
|
|
||||||
import com.github.ajalt.timberkt.Timber.tag
|
|
||||||
import com.github.ajalt.timberkt.d
|
|
||||||
import com.github.ajalt.timberkt.w
|
|
||||||
import com.github.androidpasswordstore.autofillparser.BrowserAutofillSupportLevel
|
|
||||||
import com.github.androidpasswordstore.autofillparser.getInstalledBrowsersWithAutofillSupportLevel
|
|
||||||
import com.github.michaelbull.result.getOr
|
|
||||||
import com.github.michaelbull.result.onFailure
|
|
||||||
import com.github.michaelbull.result.runCatching
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import dev.msfjarvis.aps.BuildConfig
|
|
||||||
import dev.msfjarvis.aps.util.services.PasswordExportService
|
|
||||||
import dev.msfjarvis.aps.R
|
|
||||||
import dev.msfjarvis.aps.ui.crypto.BasePgpActivity
|
|
||||||
import dev.msfjarvis.aps.ui.git.config.GitConfigActivity
|
|
||||||
import dev.msfjarvis.aps.ui.git.config.GitServerConfigActivity
|
|
||||||
import dev.msfjarvis.aps.util.git.sshj.SshKey
|
|
||||||
import dev.msfjarvis.aps.util.pwgenxkpwd.XkpwdDictionary
|
|
||||||
import dev.msfjarvis.aps.ui.sshkeygen.ShowSshKeyFragment
|
|
||||||
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
|
||||||
import dev.msfjarvis.aps.ui.proxy.ProxySelectorActivity
|
|
||||||
import dev.msfjarvis.aps.util.auth.BiometricAuthenticator
|
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
|
||||||
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
|
||||||
import dev.msfjarvis.aps.util.extensions.autofillManager
|
|
||||||
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
|
|
||||||
import dev.msfjarvis.aps.util.extensions.getString
|
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
typealias ClickListener = Preference.OnPreferenceClickListener
|
|
||||||
typealias ChangeListener = Preference.OnPreferenceChangeListener
|
|
||||||
|
|
||||||
class UserPreference : AppCompatActivity() {
|
|
||||||
|
|
||||||
private lateinit var prefsFragment: PrefsFragment
|
|
||||||
private var fromIntent = false
|
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private val directorySelectAction = registerForActivityResult(OpenDocumentTree()) { uri: Uri? ->
|
|
||||||
if (uri == null) return@registerForActivityResult
|
|
||||||
|
|
||||||
tag(TAG).d { "Selected repository URI is $uri" }
|
|
||||||
// TODO: This is fragile. Workaround until PasswordItem is backed by DocumentFile
|
|
||||||
val docId = DocumentsContract.getTreeDocumentId(uri)
|
|
||||||
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
||||||
val path = if (split.size > 1) split[1] else split[0]
|
|
||||||
val repoPath = "${Environment.getExternalStorageDirectory()}/$path"
|
|
||||||
val prefs = sharedPrefs
|
|
||||||
|
|
||||||
tag(TAG).d { "Selected repository path is $repoPath" }
|
|
||||||
|
|
||||||
if (Environment.getExternalStorageDirectory().path == repoPath) {
|
|
||||||
MaterialAlertDialogBuilder(this)
|
|
||||||
.setTitle(getString(R.string.sdcard_root_warning_title))
|
|
||||||
.setMessage(getString(R.string.sdcard_root_warning_message))
|
|
||||||
.setPositiveButton("Remove everything") { _, _ ->
|
|
||||||
prefs.edit { putString(PreferenceKeys.GIT_EXTERNAL_REPO, uri.path) }
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.dialog_cancel, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
prefs.edit { putString(PreferenceKeys.GIT_EXTERNAL_REPO, repoPath) }
|
|
||||||
if (fromIntent) {
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private val sshKeyImportAction = registerForActivityResult(OpenDocument()) { uri: Uri? ->
|
|
||||||
if (uri == null) return@registerForActivityResult
|
|
||||||
runCatching {
|
|
||||||
SshKey.import(uri)
|
|
||||||
|
|
||||||
Toast.makeText(this, resources.getString(R.string.ssh_key_success_dialog_title), Toast.LENGTH_LONG).show()
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
finish()
|
|
||||||
}.onFailure { e ->
|
|
||||||
MaterialAlertDialogBuilder(this)
|
|
||||||
.setTitle(resources.getString(R.string.ssh_key_error_dialog_title))
|
|
||||||
.setMessage(e.message)
|
|
||||||
.setPositiveButton(resources.getString(R.string.dialog_ok), null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val storeExportAction = registerForActivityResult(object : OpenDocumentTree() {
|
|
||||||
override fun createIntent(context: Context, input: Uri?): Intent {
|
|
||||||
return super.createIntent(context, input).apply {
|
|
||||||
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
|
||||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
|
|
||||||
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
|
|
||||||
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) { uri: Uri? ->
|
|
||||||
if (uri == null) return@registerForActivityResult
|
|
||||||
val targetDirectory = DocumentFile.fromTreeUri(applicationContext, uri)
|
|
||||||
|
|
||||||
if (targetDirectory != null) {
|
|
||||||
val service = Intent(applicationContext, PasswordExportService::class.java).apply {
|
|
||||||
action = PasswordExportService.ACTION_EXPORT_PASSWORD
|
|
||||||
putExtra("uri", uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
startForegroundService(service)
|
|
||||||
} else {
|
|
||||||
startService(service)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val storeCustomXkpwdDictionaryAction = registerForActivityResult(OpenDocument()) { uri ->
|
|
||||||
if (uri == null) return@registerForActivityResult
|
|
||||||
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
this.resources.getString(R.string.xkpwgen_custom_dict_imported, uri.path),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
|
|
||||||
sharedPrefs.edit { putString(PreferenceKeys.PREF_KEY_CUSTOM_DICT, uri.toString()) }
|
|
||||||
|
|
||||||
val customDictPref = prefsFragment.findPreference<Preference>(PreferenceKeys.PREF_KEY_CUSTOM_DICT)
|
|
||||||
setCustomDictSummary(customDictPref, uri)
|
|
||||||
// copy user selected file to internal storage
|
|
||||||
val inputStream = contentResolver.openInputStream(uri)
|
|
||||||
val customDictFile = File(filesDir.toString(), XkpwdDictionary.XKPWD_CUSTOM_DICT_FILE).outputStream()
|
|
||||||
inputStream?.copyTo(customDictFile, 1024)
|
|
||||||
inputStream?.close()
|
|
||||||
customDictFile.close()
|
|
||||||
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
}
|
|
||||||
|
|
||||||
class PrefsFragment : PreferenceFragmentCompat() {
|
|
||||||
|
|
||||||
private var autoFillEnablePreference: SwitchPreferenceCompat? = null
|
|
||||||
private var clearSavedPassPreference: Preference? = null
|
|
||||||
private var viewSshKeyPreference: Preference? = null
|
|
||||||
private lateinit var oreoAutofillDependencies: List<Preference>
|
|
||||||
private lateinit var prefsActivity: UserPreference
|
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
|
||||||
private lateinit var encryptedPreferences: SharedPreferences
|
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
||||||
prefsActivity = requireActivity() as UserPreference
|
|
||||||
val context = requireContext()
|
|
||||||
sharedPreferences = preferenceManager.sharedPreferences
|
|
||||||
encryptedPreferences = requireActivity().getEncryptedGitPrefs()
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.preference)
|
|
||||||
|
|
||||||
// Git preferences
|
|
||||||
val gitServerPreference = findPreference<Preference>(PreferenceKeys.GIT_SERVER_INFO)
|
|
||||||
val openkeystoreIdPreference = findPreference<Preference>(PreferenceKeys.SSH_OPENKEYSTORE_CLEAR_KEY_ID)
|
|
||||||
val gitConfigPreference = findPreference<Preference>(PreferenceKeys.GIT_CONFIG)
|
|
||||||
val sshKeyPreference = findPreference<Preference>(PreferenceKeys.SSH_KEY)
|
|
||||||
val sshKeygenPreference = findPreference<Preference>(PreferenceKeys.SSH_KEYGEN)
|
|
||||||
viewSshKeyPreference = findPreference(PreferenceKeys.SSH_SEE_KEY)
|
|
||||||
clearSavedPassPreference = findPreference(PreferenceKeys.CLEAR_SAVED_PASS)
|
|
||||||
val deleteRepoPreference = findPreference<Preference>(PreferenceKeys.GIT_DELETE_REPO)
|
|
||||||
val externalGitRepositoryPreference = findPreference<Preference>(PreferenceKeys.GIT_EXTERNAL)
|
|
||||||
val selectExternalGitRepositoryPreference = findPreference<Preference>(PreferenceKeys.PREF_SELECT_EXTERNAL)
|
|
||||||
|
|
||||||
if (!PasswordRepository.isGitRepo()) {
|
|
||||||
listOfNotNull(
|
|
||||||
gitServerPreference,
|
|
||||||
gitConfigPreference,
|
|
||||||
sshKeyPreference,
|
|
||||||
viewSshKeyPreference,
|
|
||||||
clearSavedPassPreference,
|
|
||||||
).forEach {
|
|
||||||
it.parent?.removePreference(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// General preferences
|
|
||||||
val showTimePreference = findPreference<Preference>(PreferenceKeys.GENERAL_SHOW_TIME)
|
|
||||||
val clearClipboard20xPreference = findPreference<CheckBoxPreference>(PreferenceKeys.CLEAR_CLIPBOARD_20X)
|
|
||||||
|
|
||||||
// Autofill preferences
|
|
||||||
autoFillEnablePreference = findPreference(PreferenceKeys.AUTOFILL_ENABLE)
|
|
||||||
val oreoAutofillDirectoryStructurePreference = findPreference<ListPreference>(PreferenceKeys.OREO_AUTOFILL_DIRECTORY_STRUCTURE)
|
|
||||||
val oreoAutofillDefaultUsername = findPreference<EditTextPreference>(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME)
|
|
||||||
val oreoAutofillCustomPublixSuffixes = findPreference<EditTextPreference>(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES)
|
|
||||||
oreoAutofillDependencies = listOfNotNull(
|
|
||||||
oreoAutofillDirectoryStructurePreference,
|
|
||||||
oreoAutofillDefaultUsername,
|
|
||||||
oreoAutofillCustomPublixSuffixes,
|
|
||||||
)
|
|
||||||
oreoAutofillCustomPublixSuffixes?.apply {
|
|
||||||
setOnBindEditTextListener {
|
|
||||||
it.isSingleLine = false
|
|
||||||
it.setHint(R.string.preference_custom_public_suffixes_hint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Misc preferences
|
|
||||||
val appVersionPreference = findPreference<Preference>(PreferenceKeys.APP_VERSION)
|
|
||||||
|
|
||||||
selectExternalGitRepositoryPreference?.summary = sharedPreferences.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
|
|
||||||
?: getString(R.string.no_repo_selected)
|
|
||||||
deleteRepoPreference?.isVisible = !sharedPreferences.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)
|
|
||||||
clearClipboard20xPreference?.isVisible = sharedPreferences.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toInt() != 0
|
|
||||||
openkeystoreIdPreference?.isVisible = sharedPreferences.getString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID)?.isNotEmpty()
|
|
||||||
?: false
|
|
||||||
|
|
||||||
updateAutofillSettings()
|
|
||||||
updateClearSavedPassphrasePrefs()
|
|
||||||
|
|
||||||
appVersionPreference?.summary = "Version: ${BuildConfig.VERSION_NAME}"
|
|
||||||
|
|
||||||
sshKeyPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
prefsActivity.getSshKey()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
sshKeygenPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
prefsActivity.makeSshKey(true)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
viewSshKeyPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
val df = ShowSshKeyFragment()
|
|
||||||
df.show(parentFragmentManager, "public_key")
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSavedPassPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
encryptedPreferences.edit {
|
|
||||||
if (encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD) != null)
|
|
||||||
remove(PreferenceKeys.HTTPS_PASSWORD)
|
|
||||||
else if (encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE) != null)
|
|
||||||
remove(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE)
|
|
||||||
}
|
|
||||||
updateClearSavedPassphrasePrefs()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
openkeystoreIdPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
sharedPreferences.edit { putString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID, null) }
|
|
||||||
it.isVisible = false
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
gitServerPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
startActivity(Intent(prefsActivity, GitServerConfigActivity::class.java))
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
gitConfigPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
startActivity(Intent(prefsActivity, GitConfigActivity::class.java))
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteRepoPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
val repoDir = PasswordRepository.getRepositoryDirectory()
|
|
||||||
MaterialAlertDialogBuilder(prefsActivity)
|
|
||||||
.setTitle(R.string.pref_dialog_delete_title)
|
|
||||||
.setMessage(resources.getString(R.string.dialog_delete_msg, repoDir))
|
|
||||||
.setCancelable(false)
|
|
||||||
.setPositiveButton(R.string.dialog_delete) { dialogInterface, _ ->
|
|
||||||
runCatching {
|
|
||||||
PasswordRepository.getRepositoryDirectory().deleteRecursively()
|
|
||||||
PasswordRepository.closeRepository()
|
|
||||||
}.onFailure {
|
|
||||||
// TODO Handle the different cases of exceptions
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
|
||||||
requireContext().getSystemService<ShortcutManager>()?.apply {
|
|
||||||
removeDynamicShortcuts(dynamicShortcuts.map { it.id }.toMutableList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sharedPreferences.edit { putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false) }
|
|
||||||
dialogInterface.cancel()
|
|
||||||
prefsActivity.finish()
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.dialog_do_not_delete) { dialogInterface, _ -> run { dialogInterface.cancel() } }
|
|
||||||
.show()
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
selectExternalGitRepositoryPreference?.summary =
|
|
||||||
sharedPreferences.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
|
|
||||||
?: context.getString(R.string.no_repo_selected)
|
|
||||||
selectExternalGitRepositoryPreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
prefsActivity.selectExternalGitRepository()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
val resetRepo = Preference.OnPreferenceChangeListener { _, o ->
|
|
||||||
deleteRepoPreference?.isVisible = !(o as Boolean)
|
|
||||||
PasswordRepository.closeRepository()
|
|
||||||
sharedPreferences.edit { putBoolean(PreferenceKeys.REPO_CHANGED, true) }
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
selectExternalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
|
|
||||||
externalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
autoFillEnablePreference?.onPreferenceClickListener = ClickListener {
|
|
||||||
onEnableAutofillClick()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>(PreferenceKeys.EXPORT_PASSWORDS)?.apply {
|
|
||||||
isVisible = sharedPreferences.getBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false)
|
|
||||||
onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
|
||||||
prefsActivity.exportPasswords()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showTimePreference?.onPreferenceChangeListener = ChangeListener { _, newValue: Any? ->
|
|
||||||
runCatching {
|
|
||||||
val isEnabled = newValue.toString().toInt() != 0
|
|
||||||
clearClipboard20xPreference?.isVisible = isEnabled
|
|
||||||
true
|
|
||||||
}.getOr(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
showTimePreference?.summaryProvider = Preference.SummaryProvider<Preference> {
|
|
||||||
getString(R.string.pref_clipboard_timeout_summary, sharedPreferences.getString
|
|
||||||
(PreferenceKeys.GENERAL_SHOW_TIME, "45"))
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<CheckBoxPreference>(PreferenceKeys.ENABLE_DEBUG_LOGGING)?.isVisible = !BuildConfig.ENABLE_DEBUG_FEATURES
|
|
||||||
|
|
||||||
findPreference<CheckBoxPreference>(PreferenceKeys.BIOMETRIC_AUTH)?.apply {
|
|
||||||
val canAuthenticate = BiometricAuthenticator.canAuthenticate(prefsActivity)
|
|
||||||
|
|
||||||
if (!canAuthenticate) {
|
|
||||||
isEnabled = false
|
|
||||||
isChecked = false
|
|
||||||
summary = getString(R.string.biometric_auth_summary_error)
|
|
||||||
} else {
|
|
||||||
setOnPreferenceClickListener {
|
|
||||||
isEnabled = false
|
|
||||||
sharedPreferences.edit {
|
|
||||||
val checked = isChecked
|
|
||||||
BiometricAuthenticator.authenticate(requireActivity()) { result ->
|
|
||||||
when (result) {
|
|
||||||
is BiometricAuthenticator.Result.Success -> {
|
|
||||||
// Apply the changes
|
|
||||||
putBoolean(PreferenceKeys.BIOMETRIC_AUTH, checked)
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// If any error occurs, revert back to the previous state. This
|
|
||||||
// catch-all clause includes the cancellation case.
|
|
||||||
putBoolean(PreferenceKeys.BIOMETRIC_AUTH, !checked)
|
|
||||||
isChecked = !checked
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
|
||||||
requireContext().getSystemService<ShortcutManager>()?.apply {
|
|
||||||
removeDynamicShortcuts(dynamicShortcuts.map { it.id }.toMutableList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>(PreferenceKeys.PROXY_SETTINGS)?.onPreferenceClickListener = ClickListener {
|
|
||||||
startActivity(Intent(requireContext(), ProxySelectorActivity::class.java))
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
val prefCustomXkpwdDictionary = findPreference<Preference>(PreferenceKeys.PREF_KEY_CUSTOM_DICT)
|
|
||||||
prefCustomXkpwdDictionary?.onPreferenceClickListener = ClickListener {
|
|
||||||
prefsActivity.storeCustomDictionaryPath()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
val dictUri = sharedPreferences.getString(PreferenceKeys.PREF_KEY_CUSTOM_DICT) ?: ""
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(dictUri)) {
|
|
||||||
setCustomDictSummary(prefCustomXkpwdDictionary, Uri.parse(dictUri))
|
|
||||||
}
|
|
||||||
|
|
||||||
val prefIsCustomDict = findPreference<CheckBoxPreference>(PreferenceKeys.PREF_KEY_IS_CUSTOM_DICT)
|
|
||||||
val prefCustomDictPicker = findPreference<Preference>(PreferenceKeys.PREF_KEY_CUSTOM_DICT)
|
|
||||||
val prefPwgenType = findPreference<ListPreference>(PreferenceKeys.PREF_KEY_PWGEN_TYPE)
|
|
||||||
updateXkPasswdPrefsVisibility(prefPwgenType?.value, prefIsCustomDict, prefCustomDictPicker)
|
|
||||||
|
|
||||||
prefPwgenType?.onPreferenceChangeListener = ChangeListener { _, newValue ->
|
|
||||||
updateXkPasswdPrefsVisibility(newValue, prefIsCustomDict, prefCustomDictPicker)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
prefIsCustomDict?.onPreferenceChangeListener = ChangeListener { _, newValue ->
|
|
||||||
if (!(newValue as Boolean)) {
|
|
||||||
val customDictFile = File(context.filesDir, XkpwdDictionary.XKPWD_CUSTOM_DICT_FILE)
|
|
||||||
if (customDictFile.exists() && !customDictFile.delete()) {
|
|
||||||
w { "Failed to delete custom XkPassword dictionary: $customDictFile" }
|
|
||||||
}
|
|
||||||
prefCustomDictPicker?.setSummary(R.string.xkpwgen_pref_custom_dict_picker_summary)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateXkPasswdPrefsVisibility(newValue: Any?, prefIsCustomDict: CheckBoxPreference?, prefCustomDictPicker: Preference?) {
|
|
||||||
when (newValue as String) {
|
|
||||||
BasePgpActivity.KEY_PWGEN_TYPE_CLASSIC -> {
|
|
||||||
prefIsCustomDict?.isVisible = false
|
|
||||||
prefCustomDictPicker?.isVisible = false
|
|
||||||
}
|
|
||||||
BasePgpActivity.KEY_PWGEN_TYPE_XKPASSWD -> {
|
|
||||||
prefIsCustomDict?.isVisible = true
|
|
||||||
prefCustomDictPicker?.isVisible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateAutofillSettings() {
|
|
||||||
val isAutofillServiceEnabled = prefsActivity.isAutofillServiceEnabled
|
|
||||||
val isAutofillSupported = prefsActivity.isAutofillServiceSupported
|
|
||||||
if (!isAutofillSupported) {
|
|
||||||
autoFillEnablePreference?.isVisible = false
|
|
||||||
} else {
|
|
||||||
autoFillEnablePreference?.isChecked = isAutofillServiceEnabled
|
|
||||||
}
|
|
||||||
oreoAutofillDependencies.forEach {
|
|
||||||
it.isVisible = isAutofillServiceEnabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateClearSavedPassphrasePrefs() {
|
|
||||||
clearSavedPassPreference?.apply {
|
|
||||||
val sshPass = encryptedPreferences.getString(PreferenceKeys.SSH_KEY_LOCAL_PASSPHRASE)
|
|
||||||
val httpsPass = encryptedPreferences.getString(PreferenceKeys.HTTPS_PASSWORD)
|
|
||||||
if (sshPass == null && httpsPass == null) {
|
|
||||||
isVisible = false
|
|
||||||
return@apply
|
|
||||||
}
|
|
||||||
title = when {
|
|
||||||
httpsPass != null -> getString(R.string.clear_saved_passphrase_https)
|
|
||||||
sshPass != null -> getString(R.string.clear_saved_passphrase_ssh)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
isVisible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateViewSshPubkeyPref() {
|
|
||||||
viewSshKeyPreference?.isVisible = SshKey.canShowSshPublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
private fun onEnableAutofillClick() {
|
|
||||||
if (prefsActivity.isAutofillServiceEnabled) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
|
||||||
prefsActivity.autofillManager!!.disableAutofillServices()
|
|
||||||
else
|
|
||||||
throw IllegalStateException("isAutofillServiceEnabled == true, but Build.VERSION.SDK_INT < Build.VERSION_CODES.O")
|
|
||||||
} else {
|
|
||||||
MaterialAlertDialogBuilder(prefsActivity).run {
|
|
||||||
setTitle(R.string.pref_autofill_enable_title)
|
|
||||||
@SuppressLint("InflateParams")
|
|
||||||
val layout =
|
|
||||||
layoutInflater.inflate(R.layout.oreo_autofill_instructions, null)
|
|
||||||
val supportedBrowsersTextView =
|
|
||||||
layout.findViewById<AppCompatTextView>(R.id.supportedBrowsers)
|
|
||||||
supportedBrowsersTextView.text =
|
|
||||||
getInstalledBrowsersWithAutofillSupportLevel(context).joinToString(
|
|
||||||
separator = "\n"
|
|
||||||
) {
|
|
||||||
val appLabel = it.first
|
|
||||||
val supportDescription = when (it.second) {
|
|
||||||
BrowserAutofillSupportLevel.None -> getString(R.string.oreo_autofill_no_support)
|
|
||||||
BrowserAutofillSupportLevel.FlakyFill -> getString(R.string.oreo_autofill_flaky_fill_support)
|
|
||||||
BrowserAutofillSupportLevel.PasswordFill -> getString(R.string.oreo_autofill_password_fill_support)
|
|
||||||
BrowserAutofillSupportLevel.PasswordFillAndSaveIfNoAccessibility -> getString(R.string.oreo_autofill_password_fill_and_conditional_save_support)
|
|
||||||
BrowserAutofillSupportLevel.GeneralFill -> getString(R.string.oreo_autofill_general_fill_support)
|
|
||||||
BrowserAutofillSupportLevel.GeneralFillAndSave -> getString(R.string.oreo_autofill_general_fill_and_save_support)
|
|
||||||
}
|
|
||||||
"$appLabel: $supportDescription"
|
|
||||||
}
|
|
||||||
setView(layout)
|
|
||||||
setPositiveButton(R.string.dialog_ok) { _, _ ->
|
|
||||||
val intent = Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE).apply {
|
|
||||||
data = Uri.parse("package:${BuildConfig.APPLICATION_ID}")
|
|
||||||
}
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
setNegativeButton(R.string.dialog_cancel, null)
|
|
||||||
setOnDismissListener { updateAutofillSettings() }
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
updateAutofillSettings()
|
|
||||||
updateClearSavedPassphrasePrefs()
|
|
||||||
updateViewSshPubkeyPref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
super.onBackPressed()
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
when (intent?.getStringExtra("operation")) {
|
|
||||||
"get_ssh_key" -> getSshKey()
|
|
||||||
"make_ssh_key" -> makeSshKey(false)
|
|
||||||
"git_external" -> {
|
|
||||||
fromIntent = true
|
|
||||||
selectExternalGitRepository()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prefsFragment = PrefsFragment()
|
|
||||||
|
|
||||||
supportFragmentManager
|
|
||||||
.beginTransaction()
|
|
||||||
.replace(android.R.id.content, prefsFragment)
|
|
||||||
.commit()
|
|
||||||
|
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("Deprecation") // for Environment.getExternalStorageDirectory()
|
|
||||||
fun selectExternalGitRepository() {
|
|
||||||
MaterialAlertDialogBuilder(this)
|
|
||||||
.setTitle(this.resources.getString(R.string.external_repository_dialog_title))
|
|
||||||
.setMessage(this.resources.getString(R.string.external_repository_dialog_text))
|
|
||||||
.setPositiveButton(R.string.dialog_ok) { _, _ ->
|
|
||||||
directorySelectAction.launch(null)
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.dialog_cancel, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
return when (item.itemId) {
|
|
||||||
android.R.id.home -> {
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
onBackPressed()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else -> super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun importSshKey() {
|
|
||||||
sshKeyImportAction.launch(arrayOf("*/*"))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens a file explorer to import the private key
|
|
||||||
*/
|
|
||||||
private fun getSshKey() {
|
|
||||||
if (SshKey.exists) {
|
|
||||||
MaterialAlertDialogBuilder(this).run {
|
|
||||||
setTitle(R.string.ssh_keygen_existing_title)
|
|
||||||
setMessage(R.string.ssh_keygen_existing_message)
|
|
||||||
setPositiveButton(R.string.ssh_keygen_existing_replace) { _, _ ->
|
|
||||||
importSshKey()
|
|
||||||
}
|
|
||||||
setNegativeButton(R.string.ssh_keygen_existing_keep) { _, _ -> }
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
importSshKey()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exports the passwords
|
|
||||||
*/
|
|
||||||
private fun exportPasswords() {
|
|
||||||
storeExportAction.launch(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens a key generator to generate a public/private key pair
|
|
||||||
*/
|
|
||||||
fun makeSshKey(fromPreferences: Boolean) {
|
|
||||||
val intent = Intent(applicationContext, SshKeyGenActivity::class.java)
|
|
||||||
startActivity(intent)
|
|
||||||
if (!fromPreferences) {
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pick custom xkpwd dictionary from sdcard
|
|
||||||
*/
|
|
||||||
private fun storeCustomDictionaryPath() {
|
|
||||||
storeCustomXkpwdDictionaryAction.launch(arrayOf("*/*"))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val isAutofillServiceSupported: Boolean
|
|
||||||
get() {
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false
|
|
||||||
return autofillManager?.isAutofillSupported != null
|
|
||||||
}
|
|
||||||
|
|
||||||
private val isAutofillServiceEnabled: Boolean
|
|
||||||
get() {
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false
|
|
||||||
return autofillManager?.hasEnabledAutofillServices() == true
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
private const val TAG = "UserPreference"
|
|
||||||
|
|
||||||
fun createDirectorySelectionIntent(context: Context): Intent {
|
|
||||||
return Intent(context, UserPreference::class.java).run {
|
|
||||||
putExtra("operation", "git_external")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set custom dictionary summary
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
private fun setCustomDictSummary(customDictPref: Preference?, uri: Uri) {
|
|
||||||
val fileName = uri.path?.substring(uri.path?.lastIndexOf(":")!! + 1)
|
|
||||||
customDictPref?.summary = "Selected dictionary: $fileName"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -144,6 +144,7 @@ class SshKeyGenActivity : AppCompatActivity() {
|
||||||
.setTitle(getString(R.string.error_generate_ssh_key))
|
.setTitle(getString(R.string.error_generate_ssh_key))
|
||||||
.setMessage(getString(R.string.ssh_key_error_dialog_text) + e.message)
|
.setMessage(getString(R.string.ssh_key_error_dialog_text) + e.message)
|
||||||
.setPositiveButton(getString(R.string.dialog_ok)) { _, _ ->
|
.setPositiveButton(getString(R.string.dialog_ok)) { _, _ ->
|
||||||
|
setResult(RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.msfjarvis.aps.ui.sshkeygen
|
||||||
|
|
||||||
|
import dev.msfjarvis.aps.R
|
||||||
|
import dev.msfjarvis.aps.util.git.sshj.SshKey
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.github.michaelbull.result.onFailure
|
||||||
|
import com.github.michaelbull.result.runCatching
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
class SshKeyImportActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private val sshKeyImportAction = registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri: Uri? ->
|
||||||
|
if (uri == null) {
|
||||||
|
finish()
|
||||||
|
return@registerForActivityResult
|
||||||
|
}
|
||||||
|
runCatching {
|
||||||
|
SshKey.import(uri)
|
||||||
|
Toast.makeText(this, resources.getString(R.string.ssh_key_success_dialog_title), Toast.LENGTH_LONG).show()
|
||||||
|
setResult(RESULT_OK)
|
||||||
|
finish()
|
||||||
|
}.onFailure { e ->
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(resources.getString(R.string.ssh_key_error_dialog_title))
|
||||||
|
.setMessage(e.message)
|
||||||
|
.setPositiveButton(resources.getString(R.string.dialog_ok)) { _, _ -> finish() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
if (SshKey.exists) {
|
||||||
|
MaterialAlertDialogBuilder(this).run {
|
||||||
|
setTitle(R.string.ssh_keygen_existing_title)
|
||||||
|
setMessage(R.string.ssh_keygen_existing_message)
|
||||||
|
setPositiveButton(R.string.ssh_keygen_existing_replace) { _, _ ->
|
||||||
|
importSshKey()
|
||||||
|
}
|
||||||
|
setNegativeButton(R.string.ssh_keygen_existing_keep) { _, _ -> finish() }
|
||||||
|
setOnCancelListener { finish() }
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
importSshKey()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun importSshKey() {
|
||||||
|
sshKeyImportAction.launch(arrayOf("*/*"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,8 +9,10 @@ import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import com.github.androidpasswordstore.autofillparser.Credentials
|
import com.github.androidpasswordstore.autofillparser.Credentials
|
||||||
import dev.msfjarvis.aps.data.password.PasswordEntry
|
import dev.msfjarvis.aps.data.password.PasswordEntry
|
||||||
|
import dev.msfjarvis.aps.util.extensions.getString
|
||||||
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
import dev.msfjarvis.aps.util.extensions.sharedPrefs
|
||||||
import dev.msfjarvis.aps.util.services.getDefaultUsername
|
import dev.msfjarvis.aps.util.services.getDefaultUsername
|
||||||
|
import dev.msfjarvis.aps.util.settings.PreferenceKeys
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
|
@ -110,8 +112,7 @@ enum class DirectoryStructure(val value: String) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val PREFERENCE = "oreo_autofill_directory_structure"
|
val DEFAULT = FileBased
|
||||||
private val DEFAULT = FileBased
|
|
||||||
|
|
||||||
private val reverseMap = values().associateBy { it.value }
|
private val reverseMap = values().associateBy { it.value }
|
||||||
fun fromValue(value: String?) = if (value != null) reverseMap[value] ?: DEFAULT else DEFAULT
|
fun fromValue(value: String?) = if (value != null) reverseMap[value] ?: DEFAULT else DEFAULT
|
||||||
|
@ -121,7 +122,7 @@ enum class DirectoryStructure(val value: String) {
|
||||||
object AutofillPreferences {
|
object AutofillPreferences {
|
||||||
|
|
||||||
fun directoryStructure(context: Context): DirectoryStructure {
|
fun directoryStructure(context: Context): DirectoryStructure {
|
||||||
val value = context.sharedPrefs.getString(DirectoryStructure.PREFERENCE, null)
|
val value = context.sharedPrefs.getString(PreferenceKeys.OREO_AUTOFILL_DIRECTORY_STRUCTURE)
|
||||||
return DirectoryStructure.fromValue(value)
|
return DirectoryStructure.fromValue(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import com.github.michaelbull.result.onFailure
|
||||||
import com.github.michaelbull.result.runCatching
|
import com.github.michaelbull.result.runCatching
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import dev.msfjarvis.aps.R
|
import dev.msfjarvis.aps.R
|
||||||
import dev.msfjarvis.aps.ui.settings.UserPreference
|
|
||||||
import dev.msfjarvis.aps.util.git.GitCommandExecutor
|
import dev.msfjarvis.aps.util.git.GitCommandExecutor
|
||||||
import dev.msfjarvis.aps.util.settings.AuthMode
|
import dev.msfjarvis.aps.util.settings.AuthMode
|
||||||
import dev.msfjarvis.aps.util.settings.GitSettings
|
import dev.msfjarvis.aps.util.settings.GitSettings
|
||||||
|
@ -25,6 +24,8 @@ import dev.msfjarvis.aps.util.git.sshj.SshKey
|
||||||
import dev.msfjarvis.aps.util.git.sshj.SshjSessionFactory
|
import dev.msfjarvis.aps.util.git.sshj.SshjSessionFactory
|
||||||
import dev.msfjarvis.aps.util.auth.BiometricAuthenticator
|
import dev.msfjarvis.aps.util.auth.BiometricAuthenticator
|
||||||
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
import dev.msfjarvis.aps.data.repo.PasswordRepository
|
||||||
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
|
||||||
|
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyImportActivity
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -92,9 +93,11 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
|
||||||
|
|
||||||
private fun getSshKey(make: Boolean) {
|
private fun getSshKey(make: Boolean) {
|
||||||
runCatching {
|
runCatching {
|
||||||
// Ask the UserPreference to provide us with the ssh-key
|
val intent = if (make) {
|
||||||
val intent = Intent(callingActivity.applicationContext, UserPreference::class.java)
|
Intent(callingActivity.applicationContext, SshKeyGenActivity::class.java)
|
||||||
intent.putExtra("operation", if (make) "make_ssh_key" else "get_ssh_key")
|
} else {
|
||||||
|
Intent(callingActivity.applicationContext, SshKeyImportActivity::class.java)
|
||||||
|
}
|
||||||
callingActivity.startActivity(intent)
|
callingActivity.startActivity(intent)
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
e(e)
|
e(e)
|
||||||
|
|
14
app/src/main/res/drawable/app_settings_alt_24px.xml
Normal file
14
app/src/main/res/drawable/app_settings_alt_24px.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright © 2014-2021 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:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M21.81,12.74l-0.82,-0.63v-0.22l0.8,-0.63c0.16,-0.12 0.2,-0.34 0.1,-0.51l-0.85,-1.48c-0.07,-0.13 -0.21,-0.2 -0.35,-0.2 -0.05,0 -0.1,0.01 -0.15,0.03l-0.95,0.38c-0.08,-0.05 -0.11,-0.07 -0.19,-0.11l-0.15,-1.01c-0.03,-0.21 -0.2,-0.36 -0.4,-0.36h-1.71c-0.2,0 -0.37,0.15 -0.4,0.34l-0.14,1.01c-0.03,0.02 -0.07,0.03 -0.1,0.05l-0.09,0.06 -0.95,-0.38c-0.05,-0.02 -0.1,-0.03 -0.15,-0.03 -0.14,0 -0.27,0.07 -0.35,0.2l-0.85,1.48c-0.1,0.17 -0.06,0.39 0.1,0.51l0.8,0.63v0.23l-0.8,0.63c-0.16,0.12 -0.2,0.34 -0.1,0.51l0.85,1.48c0.07,0.13 0.21,0.2 0.35,0.2 0.05,0 0.1,-0.01 0.15,-0.03l0.95,-0.37c0.08,0.05 0.12,0.07 0.2,0.11l0.15,1.01c0.03,0.2 0.2,0.34 0.4,0.34h1.71c0.2,0 0.37,-0.15 0.4,-0.34l0.15,-1.01c0.03,-0.02 0.07,-0.03 0.1,-0.05l0.09,-0.06 0.95,0.38c0.05,0.02 0.1,0.03 0.15,0.03 0.14,0 0.27,-0.07 0.35,-0.2l0.85,-1.48c0.1,-0.17 0.06,-0.39 -0.1,-0.51zM18,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM17,17h2v4c0,1.1 -0.9,2 -2,2H7c-1.1,0 -2,-0.9 -2,-2V3c0,-1.1 0.9,-2 2,-2h10c1.1,0 2,0.9 2,2v4h-2V6H7v12h10v-1z"/>
|
||||||
|
</vector>
|
14
app/src/main/res/drawable/ic_call_merge_24px.xml
Normal file
14
app/src/main/res/drawable/ic_call_merge_24px.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright © 2014-2020 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:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M17,20.41L18.41,19 15,15.59 13.59,17 17,20.41zM7.5,8H11v5.59L5.59,19 7,20.41l6,-6V8h3.5L12,3.5 7.5,8z"/>
|
||||||
|
</vector>
|
17
app/src/main/res/drawable/ic_miscellaneous_services_24px.xml
Normal file
17
app/src/main/res/drawable/ic_miscellaneous_services_24px.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright © 2014-2020 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:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M14.17,13.71l1.4,-2.42c0.09,-0.15 0.05,-0.34 -0.08,-0.45l-1.48,-1.16c0.03,-0.22 0.05,-0.45 0.05,-0.68s-0.02,-0.46 -0.05,-0.69l1.48,-1.16c0.13,-0.11 0.17,-0.3 0.08,-0.45l-1.4,-2.42c-0.09,-0.15 -0.27,-0.21 -0.43,-0.15L12,4.83c-0.36,-0.28 -0.75,-0.51 -1.18,-0.69l-0.26,-1.85C10.53,2.13 10.38,2 10.21,2h-2.8C7.24,2 7.09,2.13 7.06,2.3L6.8,4.15C6.38,4.33 5.98,4.56 5.62,4.84l-1.74,-0.7c-0.16,-0.06 -0.34,0 -0.43,0.15l-1.4,2.42C1.96,6.86 2,7.05 2.13,7.16l1.48,1.16C3.58,8.54 3.56,8.77 3.56,9s0.02,0.46 0.05,0.69l-1.48,1.16C2,10.96 1.96,11.15 2.05,11.3l1.4,2.42c0.09,0.15 0.27,0.21 0.43,0.15l1.74,-0.7c0.36,0.28 0.75,0.51 1.18,0.69l0.26,1.85C7.09,15.87 7.24,16 7.41,16h2.8c0.17,0 0.32,-0.13 0.35,-0.3l0.26,-1.85c0.42,-0.18 0.82,-0.41 1.18,-0.69l1.74,0.7C13.9,13.92 14.08,13.86 14.17,13.71zM8.81,11c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C10.81,10.1 9.91,11 8.81,11z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M21.92,18.67l-0.96,-0.74c0.02,-0.14 0.04,-0.29 0.04,-0.44c0,-0.15 -0.01,-0.3 -0.04,-0.44l0.95,-0.74c0.08,-0.07 0.11,-0.19 0.05,-0.29l-0.9,-1.55c-0.05,-0.1 -0.17,-0.13 -0.28,-0.1l-1.11,0.45c-0.23,-0.18 -0.48,-0.33 -0.76,-0.44l-0.17,-1.18C18.73,13.08 18.63,13 18.53,13h-1.79c-0.11,0 -0.21,0.08 -0.22,0.19l-0.17,1.18c-0.27,0.12 -0.53,0.26 -0.76,0.44l-1.11,-0.45c-0.1,-0.04 -0.22,0 -0.28,0.1l-0.9,1.55c-0.05,0.1 -0.04,0.22 0.05,0.29l0.95,0.74c-0.02,0.14 -0.03,0.29 -0.03,0.44c0,0.15 0.01,0.3 0.03,0.44l-0.95,0.74c-0.08,0.07 -0.11,0.19 -0.05,0.29l0.9,1.55c0.05,0.1 0.17,0.13 0.28,0.1l1.11,-0.45c0.23,0.18 0.48,0.33 0.76,0.44l0.17,1.18c0.02,0.11 0.11,0.19 0.22,0.19h1.79c0.11,0 0.21,-0.08 0.22,-0.19l0.17,-1.18c0.27,-0.12 0.53,-0.26 0.75,-0.44l1.12,0.45c0.1,0.04 0.22,0 0.28,-0.1l0.9,-1.55C22.03,18.86 22,18.74 21.92,18.67zM17.63,18.83c-0.74,0 -1.35,-0.6 -1.35,-1.35s0.6,-1.35 1.35,-1.35s1.35,0.6 1.35,1.35S18.37,18.83 17.63,18.83z"/>
|
||||||
|
</vector>
|
14
app/src/main/res/drawable/ic_wysiwyg_24px.xml
Normal file
14
app/src/main/res/drawable/ic_wysiwyg_24px.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright © 2014-2020 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:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M19,3H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.11,3 19,3zM19,19H5V7h14V19zM17,12H7v-2h10V12zM13,16H7v-2h6V16z"/>
|
||||||
|
</vector>
|
18
app/src/main/res/layout/activity_preference_recyclerview.xml
Normal file
18
app/src/main/res/layout/activity_preference_recyclerview.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Copyright © 2014-2020 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"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/preference_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -89,43 +89,42 @@
|
||||||
<string name="share_as_plaintext">Als Klartext teilen</string>
|
<string name="share_as_plaintext">Als Klartext teilen</string>
|
||||||
<string name="last_changed">Zuletzt geändert %s</string>
|
<string name="last_changed">Zuletzt geändert %s</string>
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Repository</string>
|
<string name="pref_category_repository_title">Repository</string>
|
||||||
<string name="pref_edit_server_info">Git-Server Einstellungen</string>
|
<string name="pref_edit_git_server_settings">Git-Server Einstellungen</string>
|
||||||
<string name="pref_edit_git_config">Lokale Git Konfiguration & Dienstprogramme</string>
|
<string name="pref_edit_git_config">Lokale Git Konfiguration & Dienstprogramme</string>
|
||||||
<string name="pref_ssh_title">Importiere SSH-Key</string>
|
<string name="pref_import_ssh_key_title">Importiere SSH-Key</string>
|
||||||
<string name="pref_ssh_keygen_title">Erstelle SSH-Schlüsselpaar</string>
|
<string name="pref_ssh_keygen_title">Erstelle SSH-Schlüsselpaar</string>
|
||||||
<string name="pref_ssh_see_key_title">Zeige erstellten öffentlichen SSH-Key</string>
|
<string name="pref_ssh_see_key_title">Zeige erstellten öffentlichen SSH-Key</string>
|
||||||
<string name="pref_git_delete_repo">Repository löschen</string>
|
<string name="pref_git_delete_repo_title">Repository löschen</string>
|
||||||
<string name="pref_dialog_delete_title">Repository löschen</string>
|
<string name="pref_dialog_delete_title">Repository löschen</string>
|
||||||
<string name="pref_category_general_title">Allgemein</string>
|
<string name="pref_category_general_title">Allgemein</string>
|
||||||
<string name="pref_category_title_passwords">Passwörter</string>
|
<string name="pref_category_passwords_title">Passwörter</string>
|
||||||
<string name="pref_clipboard_timeout_title">Timeout für das Kopieren des Passwortes</string>
|
<string name="pref_clipboard_timeout_title">Timeout für das Kopieren des Passwortes</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Legen Sie die Zeit (in Sekunden) fest, die das Passwort in der Zwischenablage liegen soll. 0 bedeutet für immer. Aktueller Wert: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Legen Sie die Zeit (in Sekunden) fest, die das Passwort in der Zwischenablage liegen soll. 0 bedeutet für immer. Aktueller Wert: %1$s</string>
|
||||||
<string name="pref_copy_title">Kopiere Passwort automatisch</string>
|
<string name="pref_copy_title">Kopiere Passwort automatisch</string>
|
||||||
<string name="pref_copy_dialog_title">Kopiert das Passwort in die Zwischenablage, wenn der Eintrag entschlüsselt wurde.</string>
|
<string name="pref_copy_summary">Kopiert das Passwort in die Zwischenablage, wenn der Eintrag entschlüsselt wurde.</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">Die ausgewählte Datei scheint kein privater SSH-Schlüssel zu sein.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">Die ausgewählte Datei scheint kein privater SSH-Schlüssel zu sein.</string>
|
||||||
<string name="ssh_key_success_dialog_title">SSH-Key importiert</string>
|
<string name="ssh_key_success_dialog_title">SSH-Key importiert</string>
|
||||||
<string name="ssh_key_error_dialog_title">Schlüssel-Importfehler</string>
|
<string name="ssh_key_error_dialog_title">Schlüssel-Importfehler</string>
|
||||||
<string name="ssh_key_error_dialog_text">Nachricht : \n</string>
|
<string name="ssh_key_error_dialog_text">Nachricht : \n</string>
|
||||||
<string name="pref_recursive_filter">Suche in Unterordnern</string>
|
<string name="pref_recursive_filter_title">Suche in Unterordnern</string>
|
||||||
<string name="pref_recursive_filter_hint">Findet Passwörter auch in Unterordnern.</string>
|
<string name="pref_recursive_filter_summary">Findet Passwörter auch in Unterordnern.</string>
|
||||||
<string name="pref_sort_order_title">Passwortsortierung</string>
|
<string name="pref_sort_order_title">Passwortsortierung</string>
|
||||||
<string name="pref_folder_first_sort_order">Ordner zuerst</string>
|
<string name="pref_folder_first_sort_order">Ordner zuerst</string>
|
||||||
<string name="pref_file_first_sort_order">Dateien zuerst</string>
|
<string name="pref_file_first_sort_order">Dateien zuerst</string>
|
||||||
<string name="pref_type_independent_sort_order">Typ unabhängig</string>
|
<string name="pref_type_independent_sort_order">Typ unabhängig</string>
|
||||||
<string name="pref_recently_used_sort_order">Zuletzt verwendet</string>
|
<string name="pref_recently_used_sort_order">Zuletzt verwendet</string>
|
||||||
<string name="pref_autofill_title">Automatisch ausfüllen</string>
|
<string name="pref_category_autofill_title">Automatisch ausfüllen</string>
|
||||||
<string name="pref_autofill_enable_title">Autofill aktivieren</string>
|
<string name="pref_autofill_enable_title">Autofill aktivieren</string>
|
||||||
<string name="pref_misc_title">Verschiedenes</string>
|
<string name="pref_category_misc_title">Verschiedenes</string>
|
||||||
<string name="pref_clear_clipboard_title">Lösche die Zwischenablage 20-mal</string>
|
<string name="pref_clear_clipboard_title">Lösche die Zwischenablage 20-mal</string>
|
||||||
<string name="pref_clear_clipboard_hint">Speichert Nonsense 20-mal anstatt 1-mal in der Zwischenablage. Nützlich bspw. auf Samsung-Geräten, die den Verlauf der Zwischenablage speichern.</string>
|
<string name="pref_clear_clipboard_summary">Speichert Nonsense 20-mal anstatt 1-mal in der Zwischenablage. Nützlich bspw. auf Samsung-Geräten, die den Verlauf der Zwischenablage speichern.</string>
|
||||||
<string name="pref_git_delete_repo_summary">Lösche das lokale (versteckte) Repository</string>
|
<string name="pref_git_delete_repo_summary">Lösche das lokale (versteckte) Repository</string>
|
||||||
<string name="pref_external_repository">Externes Repository</string>
|
<string name="pref_external_repository_title">Externes Repository</string>
|
||||||
<string name="pref_external_repository_summary">Nutze ein externes Repository</string>
|
<string name="pref_external_repository_summary">Nutze ein externes Repository</string>
|
||||||
<string name="pref_select_external_repository">Wähle ein externes Repository</string>
|
<string name="pref_select_external_repository_title">Wähle ein externes Repository</string>
|
||||||
<string name="prefs_export_passwords_title">Passwörter exportieren</string>
|
<string name="prefs_export_passwords_title">Passwörter exportieren</string>
|
||||||
<string name="prefs_export_passwords_summary">Exportiert die verschlüsselten Passwörter in ein externes Verzeichnis</string>
|
<string name="prefs_export_passwords_summary">Exportiert die verschlüsselten Passwörter in ein externes Verzeichnis</string>
|
||||||
<string name="prefs_version">Version</string>
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Passwort generieren</string>
|
<string name="pwgen_title">Passwort generieren</string>
|
||||||
<string name="pwgen_generate">Generieren</string>
|
<string name="pwgen_generate">Generieren</string>
|
||||||
|
@ -147,12 +146,12 @@
|
||||||
<string name="xkpwgen_custom_dict_imported">Eigene Wortliste: %1$s</string>
|
<string name="xkpwgen_custom_dict_imported">Eigene Wortliste: %1$s</string>
|
||||||
<string name="xkpwgen_builder_error">Das ausgewählte Wörterbuch enthält nicht genügend Wörter der angegebenen Länge %1$d..%2$d</string>
|
<string name="xkpwgen_builder_error">Das ausgewählte Wörterbuch enthält nicht genügend Wörter der angegebenen Länge %1$d..%2$d</string>
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Passwortgenerator</string>
|
<string name="pref_password_generator_type_title">Passwortgenerator</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Eigene Wortliste</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Eigene Wortliste</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Eigene Wordlist-Datei verwenden</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Eigene Wordlist-Datei verwenden</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Integrierte Wortliste verwenden</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Integrierte Wortliste verwenden</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">Eigene Wortliste</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">Eigene Wortliste</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Tippen Sie, um eine benutzerdefinierte Wordlist-Datei mit einem Wort pro Zeile auszuwählen</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Tippen Sie, um eine benutzerdefinierte Wordlist-Datei mit einem Wort pro Zeile auszuwählen</string>
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Passwort</string>
|
<string name="ssh_keygen_passphrase">Passwort</string>
|
||||||
<string name="ssh_keygen_generate">Generieren</string>
|
<string name="ssh_keygen_generate">Generieren</string>
|
||||||
|
@ -192,7 +191,7 @@
|
||||||
<string name="show_extra_content_pref_summary">Soll weiterer Inhalt sichtbar sein?</string>
|
<string name="show_extra_content_pref_summary">Soll weiterer Inhalt sichtbar sein?</string>
|
||||||
<string name="pwd_generate_button">Generieren</string>
|
<string name="pwd_generate_button">Generieren</string>
|
||||||
<string name="refresh_list">Aktualisieren</string>
|
<string name="refresh_list">Aktualisieren</string>
|
||||||
<string name="no_repo_selected">Kein externes Repository ausgewählt</string>
|
<string name="pref_select_external_repository_summary_no_repo_selected">Kein externes Repository ausgewählt</string>
|
||||||
<string name="send_plaintext_password_to">Passwort unverschlüsselt senden an…</string>
|
<string name="send_plaintext_password_to">Passwort unverschlüsselt senden an…</string>
|
||||||
<string name="app_icon_hint">App Icon</string>
|
<string name="app_icon_hint">App Icon</string>
|
||||||
<!-- Oreo Autofill -->
|
<!-- Oreo Autofill -->
|
||||||
|
@ -238,10 +237,10 @@
|
||||||
<string name="biometric_prompt_title">Biometrische Abfrage</string>
|
<string name="biometric_prompt_title">Biometrische Abfrage</string>
|
||||||
<string name="biometric_auth_error">Authentifizierungsfehler</string>
|
<string name="biometric_auth_error">Authentifizierungsfehler</string>
|
||||||
<string name="biometric_auth_error_reason">Authentifizierungsfehler: %s</string>
|
<string name="biometric_auth_error_reason">Authentifizierungsfehler: %s</string>
|
||||||
<string name="biometric_auth_title">Biometrische Authentifizierung aktivieren</string>
|
<string name="pref_biometric_auth_title">Biometrische Authentifizierung aktivieren</string>
|
||||||
<string name="biometric_auth_summary">Wenn aktiviert, werden Sie beim Starten der App nach Ihrem Fingerabdruck gefragt</string>
|
<string name="pref_biometric_auth_summary">Wenn aktiviert, werden Sie beim Starten der App nach Ihrem Fingerabdruck gefragt</string>
|
||||||
<string name="biometric_auth_summary_error">Fingerabdrucksensor fehlt oder ist nicht ansprechbar</string>
|
<string name="pref_biometric_auth_summary_error">Fingerabdrucksensor fehlt oder ist nicht ansprechbar</string>
|
||||||
<string name="ssh_openkeystore_clear_keyid">Lösche gespeicherte OpenKeystore SSH-Schlüssel-ID</string>
|
<string name="pref_title_openkeystore_clear_keyid">Lösche gespeicherte OpenKeystore SSH-Schlüssel-ID</string>
|
||||||
<string name="access_sdcard_text">Der Speicherort befindet sich in Ihrer SD-Karte oder im internen Speicher, aber die App hat nicht die Berechtigung, darauf zuzugreifen.</string>
|
<string name="access_sdcard_text">Der Speicherort befindet sich in Ihrer SD-Karte oder im internen Speicher, aber die App hat nicht die Berechtigung, darauf zuzugreifen.</string>
|
||||||
<string name="your_public_key">Ihr öffentlicher Schlüssel</string>
|
<string name="your_public_key">Ihr öffentlicher Schlüssel</string>
|
||||||
<string name="error_generate_ssh_key">Fehler beim Generieren des SSH-Schlüssels</string>
|
<string name="error_generate_ssh_key">Fehler beim Generieren des SSH-Schlüssels</string>
|
||||||
|
@ -254,16 +253,15 @@
|
||||||
<string name="message_error_destination_outside_repo">Ziel muss innerhalb des repository sein</string>
|
<string name="message_error_destination_outside_repo">Ziel muss innerhalb des repository sein</string>
|
||||||
<string name="message_rename_folder">Ziel für %1$s angeben</string>
|
<string name="message_rename_folder">Ziel für %1$s angeben</string>
|
||||||
<string name="button_create">Erstellen</string>
|
<string name="button_create">Erstellen</string>
|
||||||
<string name="pref_search_on_start">Suchfeld beim Start öffnen</string>
|
<string name="pref_search_on_start_title">Suchfeld beim Start öffnen</string>
|
||||||
<string name="pref_search_on_start_hint">Suchleiste beim Start der App anzeigen</string>
|
<string name="pref_search_on_start_summary">Suchleiste beim Start der App anzeigen</string>
|
||||||
<string name="password_generator_category_title">Passwort Generator</string>
|
|
||||||
<string name="tap_clear_clipboard">Hier tippen, um die Zwischenablage zu löschen</string>
|
<string name="tap_clear_clipboard">Hier tippen, um die Zwischenablage zu löschen</string>
|
||||||
<string name="clone_git_repo">Das Repository muss geklont werden, bevor Änderungen synchronisert werden können.</string>
|
<string name="clone_git_repo">Das Repository muss geklont werden, bevor Änderungen synchronisert werden können.</string>
|
||||||
<string name="theme_title">App Farbthema</string>
|
<string name="pref_app_theme_title">App Farbthema</string>
|
||||||
<string name="theme_light">Hell</string>
|
<string name="pref_app_theme_value_light">Hell</string>
|
||||||
<string name="theme_dark">Dunkel</string>
|
<string name="pref_app_theme_value_dark">Dunkel</string>
|
||||||
<string name="theme_battery_saver">Durch Energiesparmodus gesetzt</string>
|
<string name="pref_app_theme_value_battery_saver">Durch Energiesparmodus gesetzt</string>
|
||||||
<string name="theme_follow_system">Systemstandard</string>
|
<string name="pref_app_theme_value_follow_system">Systemstandard</string>
|
||||||
<string name="connection_mode_ssh_key">SSH-Schlüssel</string>
|
<string name="connection_mode_ssh_key">SSH-Schlüssel</string>
|
||||||
<string name="connection_mode_basic_authentication">Passwort</string>
|
<string name="connection_mode_basic_authentication">Passwort</string>
|
||||||
<string name="git_server_config_save_success">Konfiguration erfolgreich gespeichert</string>
|
<string name="git_server_config_save_success">Konfiguration erfolgreich gespeichert</string>
|
||||||
|
|
|
@ -91,43 +91,42 @@
|
||||||
<string name="share_as_plaintext">Partager en clair</string>
|
<string name="share_as_plaintext">Partager en clair</string>
|
||||||
<string name="last_changed">Dernière modification le %s</string>
|
<string name="last_changed">Dernière modification le %s</string>
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Dépôt</string>
|
<string name="pref_category_repository_title">Dépôt</string>
|
||||||
<string name="pref_edit_server_info">Modifier les paramètres du serveur Git</string>
|
<string name="pref_edit_git_server_settings">Modifier les paramètres du serveur Git</string>
|
||||||
<string name="pref_edit_git_config">Configuration locale de Git & utilitaires</string>
|
<string name="pref_edit_git_config">Configuration locale de Git & utilitaires</string>
|
||||||
<string name="pref_ssh_title">Importer une clef SSH</string>
|
<string name="pref_import_ssh_key_title">Importer une clef SSH</string>
|
||||||
<string name="pref_ssh_keygen_title">Générer une paire de clefs SSH</string>
|
<string name="pref_ssh_keygen_title">Générer une paire de clefs SSH</string>
|
||||||
<string name="pref_ssh_see_key_title">Voir la clef publique SSH générée</string>
|
<string name="pref_ssh_see_key_title">Voir la clef publique SSH générée</string>
|
||||||
<string name="pref_git_delete_repo">Supprimer le dépôt</string>
|
<string name="pref_git_delete_repo_title">Supprimer le dépôt</string>
|
||||||
<string name="pref_dialog_delete_title">Effacer le dépôt</string>
|
<string name="pref_dialog_delete_title">Effacer le dépôt</string>
|
||||||
<string name="pref_category_general_title">Général</string>
|
<string name="pref_category_general_title">Général</string>
|
||||||
<string name="pref_category_title_passwords">Mot de passe</string>
|
<string name="pref_category_passwords_title">Mot de passe</string>
|
||||||
<string name="pref_clipboard_timeout_title">Délai imparti pour la copie</string>
|
<string name="pref_clipboard_timeout_title">Délai imparti pour la copie</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Définissez le temps (en secondes) durant lequel le mot de passe restera dans le presse-papiers. 0 pour une rétention illimitée. Valeur actuelle: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Définissez le temps (en secondes) durant lequel le mot de passe restera dans le presse-papiers. 0 pour une rétention illimitée. Valeur actuelle: %1$s</string>
|
||||||
<string name="pref_copy_title">Copie automatique du mot de passe</string>
|
<string name="pref_copy_title">Copie automatique du mot de passe</string>
|
||||||
<string name="pref_copy_dialog_title">Copie automatiquement le mot de passe vers le presse-papier si le déchiffrement a réussi.</string>
|
<string name="pref_copy_summary">Copie automatiquement le mot de passe vers le presse-papier si le déchiffrement a réussi.</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">Le fichier sélectionné ne semble pas être une clé privée SSH.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">Le fichier sélectionné ne semble pas être une clé privée SSH.</string>
|
||||||
<string name="ssh_key_success_dialog_title">Clef SSH importée</string>
|
<string name="ssh_key_success_dialog_title">Clef SSH importée</string>
|
||||||
<string name="ssh_key_error_dialog_title">Erreur d\'importation de la clé</string>
|
<string name="ssh_key_error_dialog_title">Erreur d\'importation de la clé</string>
|
||||||
<string name="ssh_key_error_dialog_text">Message : \n</string>
|
<string name="ssh_key_error_dialog_text">Message : \n</string>
|
||||||
<string name="pref_recursive_filter">Filtre récursif</string>
|
<string name="pref_recursive_filter_title">Filtre récursif</string>
|
||||||
<string name="pref_recursive_filter_hint">Cherche le mot de passe dans tous les sous-répertoires du répertoire actuel.</string>
|
<string name="pref_recursive_filter_summary">Cherche le mot de passe dans tous les sous-répertoires du répertoire actuel.</string>
|
||||||
<string name="pref_sort_order_title">Ordre de tri des mots de passe</string>
|
<string name="pref_sort_order_title">Ordre de tri des mots de passe</string>
|
||||||
<string name="pref_folder_first_sort_order">Dossiers en premier</string>
|
<string name="pref_folder_first_sort_order">Dossiers en premier</string>
|
||||||
<string name="pref_file_first_sort_order">Fichiers en premier</string>
|
<string name="pref_file_first_sort_order">Fichiers en premier</string>
|
||||||
<string name="pref_type_independent_sort_order">Indifférent au type d\'entrée</string>
|
<string name="pref_type_independent_sort_order">Indifférent au type d\'entrée</string>
|
||||||
<string name="pref_recently_used_sort_order">Récemment utilisé</string>
|
<string name="pref_recently_used_sort_order">Récemment utilisé</string>
|
||||||
<string name="pref_autofill_title">Saisie automatique</string>
|
<string name="pref_category_autofill_title">Saisie automatique</string>
|
||||||
<string name="pref_autofill_enable_title">Saisie automatique</string>
|
<string name="pref_autofill_enable_title">Saisie automatique</string>
|
||||||
<string name="pref_misc_title">Divers</string>
|
<string name="pref_category_misc_title">Divers</string>
|
||||||
<string name="pref_clear_clipboard_title">Effacer le presse-papier 20 fois</string>
|
<string name="pref_clear_clipboard_title">Effacer le presse-papier 20 fois</string>
|
||||||
<string name="pref_clear_clipboard_hint">Enregistre des informations absurdes dans le presse-papier 20 fois à la place d\'une seule. Utile sur les téléphones Samsung qui disposent d\'un historique du presse-papier.</string>
|
<string name="pref_clear_clipboard_summary">Enregistre des informations absurdes dans le presse-papier 20 fois à la place d\'une seule. Utile sur les téléphones Samsung qui disposent d\'un historique du presse-papier.</string>
|
||||||
<string name="pref_git_delete_repo_summary">Supprime le dépot local (caché)</string>
|
<string name="pref_git_delete_repo_summary">Supprime le dépot local (caché)</string>
|
||||||
<string name="pref_external_repository">Dépôt externe</string>
|
<string name="pref_external_repository_title">Dépôt externe</string>
|
||||||
<string name="pref_external_repository_summary">Utilise un dépôt externe pour les mots de passe</string>
|
<string name="pref_external_repository_summary">Utilise un dépôt externe pour les mots de passe</string>
|
||||||
<string name="pref_select_external_repository">Choisissez un dépôt externe</string>
|
<string name="pref_select_external_repository_title">Choisissez un dépôt externe</string>
|
||||||
<string name="prefs_export_passwords_title">Exporter les mots de passe</string>
|
<string name="prefs_export_passwords_title">Exporter les mots de passe</string>
|
||||||
<string name="prefs_export_passwords_summary">Exporter les mots de passe (chiffrés) vers un répertoire externe</string>
|
<string name="prefs_export_passwords_summary">Exporter les mots de passe (chiffrés) vers un répertoire externe</string>
|
||||||
<string name="prefs_version">Version</string>
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Générer un mot de passe</string>
|
<string name="pwgen_title">Générer un mot de passe</string>
|
||||||
<string name="pwgen_generate">Générer</string>
|
<string name="pwgen_generate">Générer</string>
|
||||||
|
@ -149,12 +148,12 @@
|
||||||
<string name="xkpwgen_custom_dict_imported">Liste de mots personnalisée : %1$s</string>
|
<string name="xkpwgen_custom_dict_imported">Liste de mots personnalisée : %1$s</string>
|
||||||
<string name="xkpwgen_builder_error">Le dictionnaire sélectionné ne contient pas assez de mots de la longueur %1$d..%2$d</string>
|
<string name="xkpwgen_builder_error">Le dictionnaire sélectionné ne contient pas assez de mots de la longueur %1$d..%2$d</string>
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Type de générateur de mot de passe</string>
|
<string name="pref_password_generator_type_title">Type de générateur de mot de passe</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Liste de mots personnalisée</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Liste de mots personnalisée</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Utiliser une liste de mots personnalisée</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Utiliser une liste de mots personnalisée</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Utilisation de la liste de mots intégrée</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Utilisation de la liste de mots intégrée</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">Fichier personnalisé de liste de mots</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">Fichier personnalisé de liste de mots</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Touchez pour choisir un fichier de liste de mots personnalisés contenant un mot par ligne</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Touchez pour choisir un fichier de liste de mots personnalisés contenant un mot par ligne</string>
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Mot de passe</string>
|
<string name="ssh_keygen_passphrase">Mot de passe</string>
|
||||||
<string name="ssh_keygen_generate">Générer</string>
|
<string name="ssh_keygen_generate">Générer</string>
|
||||||
|
@ -191,7 +190,7 @@
|
||||||
<string name="show_extra_content_pref_summary">Controller la visibilité du contenu supplémentaire une fois déchiffré</string>
|
<string name="show_extra_content_pref_summary">Controller la visibilité du contenu supplémentaire une fois déchiffré</string>
|
||||||
<string name="pwd_generate_button">Générer</string>
|
<string name="pwd_generate_button">Générer</string>
|
||||||
<string name="refresh_list">Rafraichir la liste</string>
|
<string name="refresh_list">Rafraichir la liste</string>
|
||||||
<string name="no_repo_selected">Pas de dépôt externe séléctionné</string>
|
<string name="pref_select_external_repository_summary_no_repo_selected">Pas de dépôt externe séléctionné</string>
|
||||||
<string name="send_plaintext_password_to">Envoyer le mot de passe en clair via…</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>
|
<string name="app_icon_hint">Icône de l\'application</string>
|
||||||
<!-- Oreo Autofill -->
|
<!-- Oreo Autofill -->
|
||||||
|
@ -224,9 +223,9 @@
|
||||||
<string name="git_operation_remember_passphrase">Se rappeler de la phrase secrète dans la configuration de l\'application (peu sûr)</string>
|
<string name="git_operation_remember_passphrase">Se rappeler de la phrase secrète dans la configuration de l\'application (peu sûr)</string>
|
||||||
<string name="reset_to_remote">Réinitialisation dure de la branche distante</string>
|
<string name="reset_to_remote">Réinitialisation dure de la branche distante</string>
|
||||||
<string name="biometric_prompt_title">Identification biométrique</string>
|
<string name="biometric_prompt_title">Identification biométrique</string>
|
||||||
<string name="biometric_auth_title">Authentification biométrique</string>
|
<string name="pref_biometric_auth_title">Authentification biométrique</string>
|
||||||
<string name="biometric_auth_summary">Lorsque cette option est activée, Password Store vous demandera votre empreinte digitale au lancement</string>
|
<string name="pref_biometric_auth_summary">Lorsque cette option est activée, Password Store vous demandera votre empreinte digitale au lancement</string>
|
||||||
<string name="biometric_auth_summary_error">Lecteur d\'empreinte digitale non accessible ou manquant</string>
|
<string name="pref_biometric_auth_summary_error">Lecteur d\'empreinte digitale non accessible ou manquant</string>
|
||||||
<string name="your_public_key">Votre clé publique</string>
|
<string name="your_public_key">Votre clé publique</string>
|
||||||
<string name="error_generate_ssh_key">Une erreur est survenue pendant la génération de la clé ssh</string>
|
<string name="error_generate_ssh_key">Une erreur est survenue pendant la génération de la clé ssh</string>
|
||||||
<string name="pref_show_hidden_title">Afficher tous les fichiers et dossiers</string>
|
<string name="pref_show_hidden_title">Afficher tous les fichiers et dossiers</string>
|
||||||
|
@ -235,14 +234,13 @@
|
||||||
<string name="title_rename_folder">Renommer le dossier</string>
|
<string name="title_rename_folder">Renommer le dossier</string>
|
||||||
<string name="message_rename_folder">Entrez le chemin pour %1$s</string>
|
<string name="message_rename_folder">Entrez le chemin pour %1$s</string>
|
||||||
<string name="button_create">Créer</string>
|
<string name="button_create">Créer</string>
|
||||||
<string name="pref_search_on_start">Ouvrir la recherche au démarrage</string>
|
<string name="pref_search_on_start_title">Ouvrir la recherche au démarrage</string>
|
||||||
<string name="pref_search_on_start_hint">Ouvrir la barre de recherche au démarrage de l\'application</string>
|
<string name="pref_search_on_start_summary">Ouvrir la barre de recherche au démarrage de l\'application</string>
|
||||||
<string name="password_generator_category_title">Générateur de mot de passe</string>
|
|
||||||
<string name="tap_clear_clipboard">Appuyez ici pour effacer le presse-papiers</string>
|
<string name="tap_clear_clipboard">Appuyez ici pour effacer le presse-papiers</string>
|
||||||
<string name="theme_title">Thème de l\'application</string>
|
<string name="pref_app_theme_title">Thème de l\'application</string>
|
||||||
<string name="theme_light">Clair</string>
|
<string name="pref_app_theme_value_light">Clair</string>
|
||||||
<string name="theme_dark">Sombre</string>
|
<string name="pref_app_theme_value_dark">Sombre</string>
|
||||||
<string name="theme_follow_system">Thème système</string>
|
<string name="pref_app_theme_value_follow_system">Thème système</string>
|
||||||
<string name="connection_mode_ssh_key">Clé SSH</string>
|
<string name="connection_mode_ssh_key">Clé SSH</string>
|
||||||
<string name="connection_mode_basic_authentication">Mot de passe</string>
|
<string name="connection_mode_basic_authentication">Mot de passe</string>
|
||||||
<string name="git_server_config_save_error">L\'URL du dépôt fournie n\'est pas valide</string>
|
<string name="git_server_config_save_error">L\'URL du dépôt fournie n\'est pas valide</string>
|
||||||
|
|
|
@ -93,43 +93,42 @@
|
||||||
<string name="share_as_plaintext">Compartir como texto plano</string>
|
<string name="share_as_plaintext">Compartir como texto plano</string>
|
||||||
<string name="last_changed">Último cambio %s</string>
|
<string name="last_changed">Último cambio %s</string>
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Repositorio</string>
|
<string name="pref_category_repository_title">Repositorio</string>
|
||||||
<string name="pref_edit_server_info">Editar axustes do servidor git</string>
|
<string name="pref_edit_git_server_settings">Editar axustes do servidor git</string>
|
||||||
<string name="pref_edit_git_config">Utilidades Git</string>
|
<string name="pref_edit_git_config">Utilidades Git</string>
|
||||||
<string name="pref_ssh_title">Importar chave SSH</string>
|
<string name="pref_import_ssh_key_title">Importar chave SSH</string>
|
||||||
<string name="pref_ssh_keygen_title">Crear par de chaves SSH</string>
|
<string name="pref_ssh_keygen_title">Crear par de chaves SSH</string>
|
||||||
<string name="pref_ssh_see_key_title">Ver a chave pública SSH creada</string>
|
<string name="pref_ssh_see_key_title">Ver a chave pública SSH creada</string>
|
||||||
<string name="pref_git_delete_repo">Eliminar repositorio</string>
|
<string name="pref_git_delete_repo_title">Eliminar repositorio</string>
|
||||||
<string name="pref_dialog_delete_title">Baleirar repositorio</string>
|
<string name="pref_dialog_delete_title">Baleirar repositorio</string>
|
||||||
<string name="pref_category_general_title">Xeral</string>
|
<string name="pref_category_general_title">Xeral</string>
|
||||||
<string name="pref_category_title_passwords">Contrasinais</string>
|
<string name="pref_category_passwords_title">Contrasinais</string>
|
||||||
<string name="pref_clipboard_timeout_title">Caducidade do copiado do contrasinal</string>
|
<string name="pref_clipboard_timeout_title">Caducidade do copiado do contrasinal</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Establece os segundos que queres que o contrasinal permaneza copiado no portapapeis. 0 significa para sempre. Valor actual: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Establece os segundos que queres que o contrasinal permaneza copiado no portapapeis. 0 significa para sempre. Valor actual: %1$s</string>
|
||||||
<string name="pref_copy_title">Copiar contrasinal automáticamente</string>
|
<string name="pref_copy_title">Copiar contrasinal automáticamente</string>
|
||||||
<string name="pref_copy_dialog_title">Copia automáticamente o contrasinal ao portapapeis se o descifra correctamente</string>
|
<string name="pref_copy_summary">Copia automáticamente o contrasinal ao portapapeis se o descifra correctamente</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">O ficheiro escollido non semella ser unha chave privada SSH.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">O ficheiro escollido non semella ser unha chave privada SSH.</string>
|
||||||
<string name="ssh_key_success_dialog_title">Chave-SSH importada</string>
|
<string name="ssh_key_success_dialog_title">Chave-SSH importada</string>
|
||||||
<string name="ssh_key_error_dialog_title">Houbo un fallo ao importar a chave ssh</string>
|
<string name="ssh_key_error_dialog_title">Houbo un fallo ao importar a chave ssh</string>
|
||||||
<string name="ssh_key_error_dialog_text">Mensaxe : \n</string>
|
<string name="ssh_key_error_dialog_text">Mensaxe : \n</string>
|
||||||
<string name="pref_recursive_filter">Filtro recursivo</string>
|
<string name="pref_recursive_filter_title">Filtro recursivo</string>
|
||||||
<string name="pref_recursive_filter_hint">Atopa as chaves de xeito recursivo no directorio actual.</string>
|
<string name="pref_recursive_filter_summary">Atopa as chaves de xeito recursivo no directorio actual.</string>
|
||||||
<string name="pref_sort_order_title">Orde para mostrar contrasinais</string>
|
<string name="pref_sort_order_title">Orde para mostrar contrasinais</string>
|
||||||
<string name="pref_folder_first_sort_order">Primeiro cartafoles</string>
|
<string name="pref_folder_first_sort_order">Primeiro cartafoles</string>
|
||||||
<string name="pref_file_first_sort_order">Primeiro ficheiros</string>
|
<string name="pref_file_first_sort_order">Primeiro ficheiros</string>
|
||||||
<string name="pref_type_independent_sort_order">Independentemente do tipo</string>
|
<string name="pref_type_independent_sort_order">Independentemente do tipo</string>
|
||||||
<string name="pref_recently_used_sort_order">Usadas recentemente</string>
|
<string name="pref_recently_used_sort_order">Usadas recentemente</string>
|
||||||
<string name="pref_autofill_title">Completado automático</string>
|
<string name="pref_category_autofill_title">Completado automático</string>
|
||||||
<string name="pref_autofill_enable_title">Activar completado automático</string>
|
<string name="pref_autofill_enable_title">Activar completado automático</string>
|
||||||
<string name="pref_misc_title">Varios</string>
|
<string name="pref_category_misc_title">Varios</string>
|
||||||
<string name="pref_clear_clipboard_title">Baleirar portapapeis 20 veces</string>
|
<string name="pref_clear_clipboard_title">Baleirar portapapeis 20 veces</string>
|
||||||
<string name="pref_clear_clipboard_hint">Gardar números consecutivos no portapapeis 20 veces. Resulta útil nos móbiles Samsung que gardan historial no portapapeis.</string>
|
<string name="pref_clear_clipboard_summary">Gardar números consecutivos no portapapeis 20 veces. Resulta útil nos móbiles Samsung que gardan historial no portapapeis.</string>
|
||||||
<string name="pref_git_delete_repo_summary">Elimina repositorio local (oculto).</string>
|
<string name="pref_git_delete_repo_summary">Elimina repositorio local (oculto).</string>
|
||||||
<string name="pref_external_repository">Repositorio externo</string>
|
<string name="pref_external_repository_title">Repositorio externo</string>
|
||||||
<string name="pref_external_repository_summary">Usar un repositorio externo de contrasinais</string>
|
<string name="pref_external_repository_summary">Usar un repositorio externo de contrasinais</string>
|
||||||
<string name="pref_select_external_repository">Selecciona repositorio externo</string>
|
<string name="pref_select_external_repository_title">Selecciona repositorio externo</string>
|
||||||
<string name="prefs_export_passwords_title">Exportar contrasinais</string>
|
<string name="prefs_export_passwords_title">Exportar contrasinais</string>
|
||||||
<string name="prefs_export_passwords_summary">Exporta os contrasinais cifrados a un directorio externo</string>
|
<string name="prefs_export_passwords_summary">Exporta os contrasinais cifrados a un directorio externo</string>
|
||||||
<string name="prefs_version">Versión</string>
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Crear contrasinal</string>
|
<string name="pwgen_title">Crear contrasinal</string>
|
||||||
<string name="pwgen_generate">Crear</string>
|
<string name="pwgen_generate">Crear</string>
|
||||||
|
@ -151,12 +150,12 @@
|
||||||
<string name="xkpwgen_custom_dict_imported">Lista persoal de palabras: %1$s</string>
|
<string name="xkpwgen_custom_dict_imported">Lista persoal de palabras: %1$s</string>
|
||||||
<string name="xkpwgen_builder_error">O dicionario non contén palabras suficientes da lonxitude dada %1$d .. %2$d</string>
|
<string name="xkpwgen_builder_error">O dicionario non contén palabras suficientes da lonxitude dada %1$d .. %2$d</string>
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Tipo de creador de contrasinais</string>
|
<string name="pref_password_generator_type_title">Tipo de creador de contrasinais</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Lista persoal de palabras</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Lista persoal de palabras</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Usar ficheiro con palabras personalizadas</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Usar ficheiro con palabras personalizadas</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Usar lista de palabras incluída</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Usar lista de palabras incluída</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">Ficheiro persoal de palabras</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">Ficheiro persoal de palabras</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Toca para escoller un ficheiro persoal con palabras que conteña unha palabra por liña</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Toca para escoller un ficheiro persoal con palabras que conteña unha palabra por liña</string>
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Frase de paso</string>
|
<string name="ssh_keygen_passphrase">Frase de paso</string>
|
||||||
<string name="ssh_keygen_generate">Crear</string>
|
<string name="ssh_keygen_generate">Crear</string>
|
||||||
|
@ -196,7 +195,7 @@
|
||||||
<string name="show_extra_content_pref_summary">Controla a visibilidade do contido extra unha vez descifrado</string>
|
<string name="show_extra_content_pref_summary">Controla a visibilidade do contido extra unha vez descifrado</string>
|
||||||
<string name="pwd_generate_button">Crear</string>
|
<string name="pwd_generate_button">Crear</string>
|
||||||
<string name="refresh_list">Actualizar lista</string>
|
<string name="refresh_list">Actualizar lista</string>
|
||||||
<string name="no_repo_selected">Non hai seleccionado ningún repositorio externo</string>
|
<string name="pref_select_external_repository_summary_no_repo_selected">Non hai seleccionado ningún repositorio externo</string>
|
||||||
<string name="send_plaintext_password_to">Enviar contrasinal como texto plano usando...</string>
|
<string name="send_plaintext_password_to">Enviar contrasinal como texto plano usando...</string>
|
||||||
<string name="app_icon_hint">Icona da app</string>
|
<string name="app_icon_hint">Icona da app</string>
|
||||||
<!-- Oreo Autofill -->
|
<!-- Oreo Autofill -->
|
||||||
|
@ -249,10 +248,10 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
|
||||||
<string name="biometric_prompt_title">Petición biométrica</string>
|
<string name="biometric_prompt_title">Petición biométrica</string>
|
||||||
<string name="biometric_auth_error">Fallo de autenticación</string>
|
<string name="biometric_auth_error">Fallo de autenticación</string>
|
||||||
<string name="biometric_auth_error_reason">Fallou a autenticación: %s</string>
|
<string name="biometric_auth_error_reason">Fallou a autenticación: %s</string>
|
||||||
<string name="biometric_auth_title">Activar autenticación biométrica</string>
|
<string name="pref_biometric_auth_title">Activar autenticación biométrica</string>
|
||||||
<string name="biometric_auth_summary">Ao activala, Password Store vaiche pedir a túa pegada dactilar ao iniciar a app</string>
|
<string name="pref_biometric_auth_summary">Ao activala, Password Store vaiche pedir a túa pegada dactilar ao iniciar a app</string>
|
||||||
<string name="biometric_auth_summary_error">O hardware de pegada dixital non é accesible ou existente</string>
|
<string name="pref_biometric_auth_summary_error">O hardware de pegada dixital non é accesible ou existente</string>
|
||||||
<string name="ssh_openkeystore_clear_keyid">Eliminar o ID lembrado da chave SSH en OpenKeystore</string>
|
<string name="pref_title_openkeystore_clear_keyid">Eliminar o ID lembrado da chave SSH en OpenKeystore</string>
|
||||||
<string name="access_sdcard_text">O almacenaxe está na tarxeta SD pero a app non ten permiso para acceder a el. Por favor concédelle permiso.</string>
|
<string name="access_sdcard_text">O almacenaxe está na tarxeta SD pero a app non ten permiso para acceder a el. Por favor concédelle permiso.</string>
|
||||||
<string name="your_public_key">A túa chave pública</string>
|
<string name="your_public_key">A túa chave pública</string>
|
||||||
<string name="error_generate_ssh_key">Algo fallou ao intentar crear a chave-ssh</string>
|
<string name="error_generate_ssh_key">Algo fallou ao intentar crear a chave-ssh</string>
|
||||||
|
@ -265,16 +264,15 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
|
||||||
<string name="message_error_destination_outside_repo">O destino debe estar dentro do repositorio</string>
|
<string name="message_error_destination_outside_repo">O destino debe estar dentro do repositorio</string>
|
||||||
<string name="message_rename_folder">Escribe o destino para %1$s</string>
|
<string name="message_rename_folder">Escribe o destino para %1$s</string>
|
||||||
<string name="button_create">Crear</string>
|
<string name="button_create">Crear</string>
|
||||||
<string name="pref_search_on_start">Abrir busca ao inicio</string>
|
<string name="pref_search_on_start_title">Abrir busca ao inicio</string>
|
||||||
<string name="pref_search_on_start_hint">Abrir a barra de busca cando se inicia a app</string>
|
<string name="pref_search_on_start_summary">Abrir a barra de busca cando se inicia a app</string>
|
||||||
<string name="password_generator_category_title">Creador de contrasinais</string>
|
|
||||||
<string name="tap_clear_clipboard">Toca aquí para baleirar o portapapeis</string>
|
<string name="tap_clear_clipboard">Toca aquí para baleirar o portapapeis</string>
|
||||||
<string name="clone_git_repo">Clonar un repositorio git para sincronizar os cambios</string>
|
<string name="clone_git_repo">Clonar un repositorio git para sincronizar os cambios</string>
|
||||||
<string name="theme_title">Decorado da App</string>
|
<string name="pref_app_theme_title">Decorado da App</string>
|
||||||
<string name="theme_light">Claro</string>
|
<string name="pref_app_theme_value_light">Claro</string>
|
||||||
<string name="theme_dark">Escuro</string>
|
<string name="pref_app_theme_value_dark">Escuro</string>
|
||||||
<string name="theme_battery_saver">Establecido polo Aforrador de enerxía</string>
|
<string name="pref_app_theme_value_battery_saver">Establecido polo Aforrador de enerxía</string>
|
||||||
<string name="theme_follow_system">Por omisión do sistema</string>
|
<string name="pref_app_theme_value_follow_system">Por omisión do sistema</string>
|
||||||
<string name="connection_mode_ssh_key">Chave SSH</string>
|
<string name="connection_mode_ssh_key">Chave SSH</string>
|
||||||
<string name="connection_mode_basic_authentication">Contrasinal</string>
|
<string name="connection_mode_basic_authentication">Contrasinal</string>
|
||||||
<string name="git_server_config_save_success">Configuración gardada</string>
|
<string name="git_server_config_save_success">Configuración gardada</string>
|
||||||
|
@ -354,7 +352,7 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
|
||||||
<!-- Proxy configuration activity -->
|
<!-- Proxy configuration activity -->
|
||||||
<string name="proxy_hostname">Servidor proxy</string>
|
<string name="proxy_hostname">Servidor proxy</string>
|
||||||
<string name="port">Porto</string>
|
<string name="port">Porto</string>
|
||||||
<string name="pref_proxy_settings">Axustes do proxy HTTP(S)</string>
|
<string name="pref_edit_proxy_settings">Axustes do proxy HTTP(S)</string>
|
||||||
<string name="invalid_proxy_url">URL non válido</string>
|
<string name="invalid_proxy_url">URL non válido</string>
|
||||||
<string name="oreo_autofill_password_fill_and_conditional_save_support">Completa e garda contrasinais (gardar require que os servizos de accesibilidade non estén activados)</string>
|
<string name="oreo_autofill_password_fill_and_conditional_save_support">Completa e garda contrasinais (gardar require que os servizos de accesibilidade non estén activados)</string>
|
||||||
<string name="clear_saved_host_key">Eliminar chave do host gardada</string>
|
<string name="clear_saved_host_key">Eliminar chave do host gardada</string>
|
||||||
|
|
|
@ -93,43 +93,42 @@
|
||||||
<string name="share_as_plaintext">Condividi come testo semplice</string>
|
<string name="share_as_plaintext">Condividi come testo semplice</string>
|
||||||
<string name="last_changed">Ultima modifica %s</string>
|
<string name="last_changed">Ultima modifica %s</string>
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Repository</string>
|
<string name="pref_category_repository_title">Repository</string>
|
||||||
<string name="pref_edit_server_info">Modifica impostazioni del server di Git</string>
|
<string name="pref_edit_git_server_settings">Modifica impostazioni del server di Git</string>
|
||||||
<string name="pref_edit_git_config">Configurazione & utilità della configurazione di Git</string>
|
<string name="pref_edit_git_config">Configurazione & utilità della configurazione di Git</string>
|
||||||
<string name="pref_ssh_title">Importa chiave SSH</string>
|
<string name="pref_import_ssh_key_title">Importa chiave SSH</string>
|
||||||
<string name="pref_ssh_keygen_title">Genera coppia di chiavi SSH</string>
|
<string name="pref_ssh_keygen_title">Genera coppia di chiavi SSH</string>
|
||||||
<string name="pref_ssh_see_key_title">Visualizza la chiave SSH pubblica generata</string>
|
<string name="pref_ssh_see_key_title">Visualizza la chiave SSH pubblica generata</string>
|
||||||
<string name="pref_git_delete_repo">Elimina repository</string>
|
<string name="pref_git_delete_repo_title">Elimina repository</string>
|
||||||
<string name="pref_dialog_delete_title">Cancella repository</string>
|
<string name="pref_dialog_delete_title">Cancella repository</string>
|
||||||
<string name="pref_category_general_title">Generale</string>
|
<string name="pref_category_general_title">Generale</string>
|
||||||
<string name="pref_category_title_passwords">Password</string>
|
<string name="pref_category_passwords_title">Password</string>
|
||||||
<string name="pref_clipboard_timeout_title">Timeout copia della password</string>
|
<string name="pref_clipboard_timeout_title">Timeout copia della password</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Imposta per quanto tempo (in secondi) vuoi che la password rimanga negli appunti. 0 significa per sempre. Valore corrente: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Imposta per quanto tempo (in secondi) vuoi che la password rimanga negli appunti. 0 significa per sempre. Valore corrente: %1$s</string>
|
||||||
<string name="pref_copy_title">Copia automaticamente la password</string>
|
<string name="pref_copy_title">Copia automaticamente la password</string>
|
||||||
<string name="pref_copy_dialog_title">Copia automaticamente la password negli appunti dopo il successo della decifratura.</string>
|
<string name="pref_copy_summary">Copia automaticamente la password negli appunti dopo il successo della decifratura.</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">Il file selezionato non sembra essere una chiave privata SSH.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">Il file selezionato non sembra essere una chiave privata SSH.</string>
|
||||||
<string name="ssh_key_success_dialog_title">Chiave SSH importata</string>
|
<string name="ssh_key_success_dialog_title">Chiave SSH importata</string>
|
||||||
<string name="ssh_key_error_dialog_title">Errore di importazione della chiave</string>
|
<string name="ssh_key_error_dialog_title">Errore di importazione della chiave</string>
|
||||||
<string name="ssh_key_error_dialog_text">Messaggio : \n</string>
|
<string name="ssh_key_error_dialog_text">Messaggio : \n</string>
|
||||||
<string name="pref_recursive_filter">Filtro ricorsivo</string>
|
<string name="pref_recursive_filter_title">Filtro ricorsivo</string>
|
||||||
<string name="pref_recursive_filter_hint">Trova ricorsivamente le password della directory corrente.</string>
|
<string name="pref_recursive_filter_summary">Trova ricorsivamente le password della directory corrente.</string>
|
||||||
<string name="pref_sort_order_title">Ordine password</string>
|
<string name="pref_sort_order_title">Ordine password</string>
|
||||||
<string name="pref_folder_first_sort_order">Prima le cartelle</string>
|
<string name="pref_folder_first_sort_order">Prima le cartelle</string>
|
||||||
<string name="pref_file_first_sort_order">Prima i file</string>
|
<string name="pref_file_first_sort_order">Prima i file</string>
|
||||||
<string name="pref_type_independent_sort_order">Tipo indipendente</string>
|
<string name="pref_type_independent_sort_order">Tipo indipendente</string>
|
||||||
<string name="pref_recently_used_sort_order">Usato di recente</string>
|
<string name="pref_recently_used_sort_order">Usato di recente</string>
|
||||||
<string name="pref_autofill_title">Auto-compilazione</string>
|
<string name="pref_category_autofill_title">Auto-compilazione</string>
|
||||||
<string name="pref_autofill_enable_title">Abilita Auto-Compilazione</string>
|
<string name="pref_autofill_enable_title">Abilita Auto-Compilazione</string>
|
||||||
<string name="pref_misc_title">Varie</string>
|
<string name="pref_category_misc_title">Varie</string>
|
||||||
<string name="pref_clear_clipboard_title">Cancella 20 volte gli appunti</string>
|
<string name="pref_clear_clipboard_title">Cancella 20 volte gli appunti</string>
|
||||||
<string name="pref_clear_clipboard_hint">Archivia i numeri consecutivi negli appunti per 20 volte. Utile sui telefoni Samsung che presentano la cronologia degli appunti.</string>
|
<string name="pref_clear_clipboard_summary">Archivia i numeri consecutivi negli appunti per 20 volte. Utile sui telefoni Samsung che presentano la cronologia degli appunti.</string>
|
||||||
<string name="pref_git_delete_repo_summary">Elimina repository locale (nascosta)</string>
|
<string name="pref_git_delete_repo_summary">Elimina repository locale (nascosta)</string>
|
||||||
<string name="pref_external_repository">Repository Esterna</string>
|
<string name="pref_external_repository_title">Repository Esterna</string>
|
||||||
<string name="pref_external_repository_summary">Usa una repository di password esterna</string>
|
<string name="pref_external_repository_summary">Usa una repository di password esterna</string>
|
||||||
<string name="pref_select_external_repository">Seleziona repository esterna</string>
|
<string name="pref_select_external_repository_title">Seleziona repository esterna</string>
|
||||||
<string name="prefs_export_passwords_title">Esporta password</string>
|
<string name="prefs_export_passwords_title">Esporta password</string>
|
||||||
<string name="prefs_export_passwords_summary">Esporta le password crittografate ad una directory esterna</string>
|
<string name="prefs_export_passwords_summary">Esporta le password crittografate ad una directory esterna</string>
|
||||||
<string name="prefs_version">Versione</string>
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Genera Password</string>
|
<string name="pwgen_title">Genera Password</string>
|
||||||
<string name="pwgen_generate">Genera</string>
|
<string name="pwgen_generate">Genera</string>
|
||||||
|
@ -151,12 +150,12 @@
|
||||||
<string name="xkpwgen_custom_dict_imported">Lista di parole personalizzata: %1$s</string>
|
<string name="xkpwgen_custom_dict_imported">Lista di parole personalizzata: %1$s</string>
|
||||||
<string name="xkpwgen_builder_error">Il dizionario selezionato non contiene abbastanza parole della data lunghezza %1$d..%2$d</string>
|
<string name="xkpwgen_builder_error">Il dizionario selezionato non contiene abbastanza parole della data lunghezza %1$d..%2$d</string>
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Tipo di generatore di password</string>
|
<string name="pref_password_generator_type_title">Tipo di generatore di password</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Lista di parole personalizzata</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Lista di parole personalizzata</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Usando file di elenco di parole personalizzati</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Usando file di elenco di parole personalizzati</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Usando liste di parole integrate</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Usando liste di parole integrate</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">File di elenco di parole personalizzato</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">File di elenco di parole personalizzato</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Tocca per selezionare un file di lista di parole personalizzato contenente una parola per riga</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Tocca per selezionare un file di lista di parole personalizzato contenente una parola per riga</string>
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Frase Segreta</string>
|
<string name="ssh_keygen_passphrase">Frase Segreta</string>
|
||||||
<string name="ssh_keygen_generate">Genera</string>
|
<string name="ssh_keygen_generate">Genera</string>
|
||||||
|
@ -196,7 +195,7 @@
|
||||||
<string name="show_extra_content_pref_summary">Controlla la visibilità del contenuto extra una volta decrittografato.</string>
|
<string name="show_extra_content_pref_summary">Controlla la visibilità del contenuto extra una volta decrittografato.</string>
|
||||||
<string name="pwd_generate_button">Genera</string>
|
<string name="pwd_generate_button">Genera</string>
|
||||||
<string name="refresh_list">Aggiorna elenco</string>
|
<string name="refresh_list">Aggiorna elenco</string>
|
||||||
<string name="no_repo_selected">Nessuna repository esterna selezionata</string>
|
<string name="pref_select_external_repository_summary_no_repo_selected">Nessuna repository esterna selezionata</string>
|
||||||
<string name="send_plaintext_password_to">Invia password come testo semplice usando…</string>
|
<string name="send_plaintext_password_to">Invia password come testo semplice usando…</string>
|
||||||
<string name="app_icon_hint">Icona app</string>
|
<string name="app_icon_hint">Icona app</string>
|
||||||
<!-- Oreo Autofill -->
|
<!-- Oreo Autofill -->
|
||||||
|
@ -248,10 +247,10 @@
|
||||||
<string name="biometric_prompt_title">Richiesta Biometrica</string>
|
<string name="biometric_prompt_title">Richiesta Biometrica</string>
|
||||||
<string name="biometric_auth_error">Autenticazione non riuscita</string>
|
<string name="biometric_auth_error">Autenticazione non riuscita</string>
|
||||||
<string name="biometric_auth_error_reason">Autenticazione non riuscita: %s</string>
|
<string name="biometric_auth_error_reason">Autenticazione non riuscita: %s</string>
|
||||||
<string name="biometric_auth_title">Abilita autenticazione biometrica</string>
|
<string name="pref_biometric_auth_title">Abilita autenticazione biometrica</string>
|
||||||
<string name="biometric_auth_summary">Quando abilitata, il Password Store ti chiederà la tua impronta digitale al lancio dell\'app</string>
|
<string name="pref_biometric_auth_summary">Quando abilitata, il Password Store ti chiederà la tua impronta digitale al lancio dell\'app</string>
|
||||||
<string name="biometric_auth_summary_error">L\'hardware delle impronte digitali non è accessibile o mancante</string>
|
<string name="pref_biometric_auth_summary_error">L\'hardware delle impronte digitali non è accessibile o mancante</string>
|
||||||
<string name="ssh_openkeystore_clear_keyid">Elimina l\'ID della Chiave SSH di OpenKeystore memorizzato</string>
|
<string name="pref_title_openkeystore_clear_keyid">Elimina l\'ID della Chiave SSH di OpenKeystore memorizzato</string>
|
||||||
<string name="access_sdcard_text">La posizione dell\'archiviazione nella tua Scheda SD o Archiviazione Interna, ma l\'app non ha i permessi per accedervi.</string>
|
<string name="access_sdcard_text">La posizione dell\'archiviazione nella tua Scheda SD o Archiviazione Interna, ma l\'app non ha i permessi per accedervi.</string>
|
||||||
<string name="your_public_key">La tua chiave pubblica</string>
|
<string name="your_public_key">La tua chiave pubblica</string>
|
||||||
<string name="error_generate_ssh_key">Errore provando a generare la chiave-ssh</string>
|
<string name="error_generate_ssh_key">Errore provando a generare la chiave-ssh</string>
|
||||||
|
@ -264,16 +263,15 @@
|
||||||
<string name="message_error_destination_outside_repo">La destinazione deve essere nella repository</string>
|
<string name="message_error_destination_outside_repo">La destinazione deve essere nella repository</string>
|
||||||
<string name="message_rename_folder">Inserire destinazione per %1$s</string>
|
<string name="message_rename_folder">Inserire destinazione per %1$s</string>
|
||||||
<string name="button_create">Crea</string>
|
<string name="button_create">Crea</string>
|
||||||
<string name="pref_search_on_start">Apri ricerca all\'avvio</string>
|
<string name="pref_search_on_start_title">Apri ricerca all\'avvio</string>
|
||||||
<string name="pref_search_on_start_hint">Apri la barra di ricerca al lancio dell\'app</string>
|
<string name="pref_search_on_start_summary">Apri la barra di ricerca al lancio dell\'app</string>
|
||||||
<string name="password_generator_category_title">Generatore di Password</string>
|
|
||||||
<string name="tap_clear_clipboard">Tocca qui per cancellare gli appunti</string>
|
<string name="tap_clear_clipboard">Tocca qui per cancellare gli appunti</string>
|
||||||
<string name="clone_git_repo">La repository deve essere clonata prima di sincronizzare le modifiche.</string>
|
<string name="clone_git_repo">La repository deve essere clonata prima di sincronizzare le modifiche.</string>
|
||||||
<string name="theme_title">Tema dell\'App</string>
|
<string name="pref_app_theme_title">Tema dell\'App</string>
|
||||||
<string name="theme_light">Chiaro</string>
|
<string name="pref_app_theme_value_light">Chiaro</string>
|
||||||
<string name="theme_dark">Scuro</string>
|
<string name="pref_app_theme_value_dark">Scuro</string>
|
||||||
<string name="theme_battery_saver">Impostato dal Risparmio Energetico</string>
|
<string name="pref_app_theme_value_battery_saver">Impostato dal Risparmio Energetico</string>
|
||||||
<string name="theme_follow_system">Predefinito del sistema</string>
|
<string name="pref_app_theme_value_follow_system">Predefinito del sistema</string>
|
||||||
<string name="connection_mode_ssh_key">Chiave SSH</string>
|
<string name="connection_mode_ssh_key">Chiave SSH</string>
|
||||||
<string name="connection_mode_basic_authentication">Password</string>
|
<string name="connection_mode_basic_authentication">Password</string>
|
||||||
<string name="git_server_config_save_success">Configurazione correttamente salvata</string>
|
<string name="git_server_config_save_success">Configurazione correttamente salvata</string>
|
||||||
|
@ -353,7 +351,7 @@
|
||||||
<!-- Proxy configuration activity -->
|
<!-- Proxy configuration activity -->
|
||||||
<string name="proxy_hostname">Nome host del proxy</string>
|
<string name="proxy_hostname">Nome host del proxy</string>
|
||||||
<string name="port">Porta</string>
|
<string name="port">Porta</string>
|
||||||
<string name="pref_proxy_settings">Impostazioni proxy HTTP(S)</string>
|
<string name="pref_edit_proxy_settings">Impostazioni proxy HTTP(S)</string>
|
||||||
<string name="invalid_proxy_url">URL non valido</string>
|
<string name="invalid_proxy_url">URL non valido</string>
|
||||||
<string name="oreo_autofill_password_fill_and_conditional_save_support">Compila e salva le password (il salvataggio necessita che nessun servizio di accessibilità sia abilitato)</string>
|
<string name="oreo_autofill_password_fill_and_conditional_save_support">Compila e salva le password (il salvataggio necessita che nessun servizio di accessibilità sia abilitato)</string>
|
||||||
<string name="clear_saved_host_key">Cancella la chiave host salvata</string>
|
<string name="clear_saved_host_key">Cancella la chiave host salvata</string>
|
||||||
|
|
|
@ -93,43 +93,42 @@
|
||||||
<string name="share_as_plaintext">Compartilhar como texto</string>
|
<string name="share_as_plaintext">Compartilhar como texto</string>
|
||||||
<string name="last_changed">Última alteração %s</string>
|
<string name="last_changed">Última alteração %s</string>
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Repositório</string>
|
<string name="pref_category_repository_title">Repositório</string>
|
||||||
<string name="pref_edit_server_info">Editar configurações do servidor Git</string>
|
<string name="pref_edit_git_server_settings">Editar configurações do servidor Git</string>
|
||||||
<string name="pref_edit_git_config">Configuração local do Git & utilitários</string>
|
<string name="pref_edit_git_config">Configuração local do Git & utilitários</string>
|
||||||
<string name="pref_ssh_title">Importar chave SSH</string>
|
<string name="pref_import_ssh_key_title">Importar chave SSH</string>
|
||||||
<string name="pref_ssh_keygen_title">Gerar um par de chave SSH</string>
|
<string name="pref_ssh_keygen_title">Gerar um par de chave SSH</string>
|
||||||
<string name="pref_ssh_see_key_title">Ver a chave SSH pública gerada</string>
|
<string name="pref_ssh_see_key_title">Ver a chave SSH pública gerada</string>
|
||||||
<string name="pref_git_delete_repo">Excluir repositório</string>
|
<string name="pref_git_delete_repo_title">Excluir repositório</string>
|
||||||
<string name="pref_dialog_delete_title">Limpar repositório</string>
|
<string name="pref_dialog_delete_title">Limpar repositório</string>
|
||||||
<string name="pref_category_general_title">Geral</string>
|
<string name="pref_category_general_title">Geral</string>
|
||||||
<string name="pref_category_title_passwords">Senhas</string>
|
<string name="pref_category_passwords_title">Senhas</string>
|
||||||
<string name="pref_clipboard_timeout_title">Tempo limite de cópia da senha</string>
|
<string name="pref_clipboard_timeout_title">Tempo limite de cópia da senha</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Definir o tempo (em segundos) que a senha está na área de transferência. 0 significa para sempre. Valor atual: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Definir o tempo (em segundos) que a senha está na área de transferência. 0 significa para sempre. Valor atual: %1$s</string>
|
||||||
<string name="pref_copy_title">Copiar senha automaticamente</string>
|
<string name="pref_copy_title">Copiar senha automaticamente</string>
|
||||||
<string name="pref_copy_dialog_title">Automaticamente copie a senha para a área de transferência após a descriptografia ser bem sucedida.</string>
|
<string name="pref_copy_summary">Automaticamente copie a senha para a área de transferência após a descriptografia ser bem sucedida.</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">O arquivo selecionado não parece ser uma chave SSH privada.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">O arquivo selecionado não parece ser uma chave SSH privada.</string>
|
||||||
<string name="ssh_key_success_dialog_title">Chave SSH importada</string>
|
<string name="ssh_key_success_dialog_title">Chave SSH importada</string>
|
||||||
<string name="ssh_key_error_dialog_title">Erro ao importar chave</string>
|
<string name="ssh_key_error_dialog_title">Erro ao importar chave</string>
|
||||||
<string name="ssh_key_error_dialog_text">Mensagem : \n</string>
|
<string name="ssh_key_error_dialog_text">Mensagem : \n</string>
|
||||||
<string name="pref_recursive_filter">Filtragem recursiva</string>
|
<string name="pref_recursive_filter_title">Filtragem recursiva</string>
|
||||||
<string name="pref_recursive_filter_hint">Encontrar senhas do diretório corrente recursivamente.</string>
|
<string name="pref_recursive_filter_summary">Encontrar senhas do diretório corrente recursivamente.</string>
|
||||||
<string name="pref_sort_order_title">Ordenação da Senha</string>
|
<string name="pref_sort_order_title">Ordenação da Senha</string>
|
||||||
<string name="pref_folder_first_sort_order">Pastas primeiro</string>
|
<string name="pref_folder_first_sort_order">Pastas primeiro</string>
|
||||||
<string name="pref_file_first_sort_order">Arquivos primeiro</string>
|
<string name="pref_file_first_sort_order">Arquivos primeiro</string>
|
||||||
<string name="pref_type_independent_sort_order">Tipo independente</string>
|
<string name="pref_type_independent_sort_order">Tipo independente</string>
|
||||||
<string name="pref_recently_used_sort_order">Usado recentemente</string>
|
<string name="pref_recently_used_sort_order">Usado recentemente</string>
|
||||||
<string name="pref_autofill_title">Preenchimento Automático</string>
|
<string name="pref_category_autofill_title">Preenchimento Automático</string>
|
||||||
<string name="pref_autofill_enable_title">Ativar preenchimento automático</string>
|
<string name="pref_autofill_enable_title">Ativar preenchimento automático</string>
|
||||||
<string name="pref_misc_title">Outros</string>
|
<string name="pref_category_misc_title">Outros</string>
|
||||||
<string name="pref_clear_clipboard_title">Limpar área de transferência 20 vezes</string>
|
<string name="pref_clear_clipboard_title">Limpar área de transferência 20 vezes</string>
|
||||||
<string name="pref_clear_clipboard_hint">Armazene números consecutivos na área de transferência 20 vezes. Útil em telefones Samsung que apresentam o histórico da área de transferência.</string>
|
<string name="pref_clear_clipboard_summary">Armazene números consecutivos na área de transferência 20 vezes. Útil em telefones Samsung que apresentam o histórico da área de transferência.</string>
|
||||||
<string name="pref_git_delete_repo_summary">Exclui o repositório local (oculto)</string>
|
<string name="pref_git_delete_repo_summary">Exclui o repositório local (oculto)</string>
|
||||||
<string name="pref_external_repository">Repositório externo</string>
|
<string name="pref_external_repository_title">Repositório externo</string>
|
||||||
<string name="pref_external_repository_summary">Use um repositório de senha externo</string>
|
<string name="pref_external_repository_summary">Use um repositório de senha externo</string>
|
||||||
<string name="pref_select_external_repository">Selecionar repositório externo</string>
|
<string name="pref_select_external_repository_title">Selecionar repositório externo</string>
|
||||||
<string name="prefs_export_passwords_title">Exportar senhas</string>
|
<string name="prefs_export_passwords_title">Exportar senhas</string>
|
||||||
<string name="prefs_export_passwords_summary">Exporta as senhas criptografadas para um diretório externo</string>
|
<string name="prefs_export_passwords_summary">Exporta as senhas criptografadas para um diretório externo</string>
|
||||||
<string name="prefs_version">Versão</string>
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Gerar Senha</string>
|
<string name="pwgen_title">Gerar Senha</string>
|
||||||
<string name="pwgen_generate">Gerar</string>
|
<string name="pwgen_generate">Gerar</string>
|
||||||
|
@ -151,12 +150,12 @@
|
||||||
<string name="xkpwgen_custom_dict_imported">Lista de palavras personalizada: %1$s</string>
|
<string name="xkpwgen_custom_dict_imported">Lista de palavras personalizada: %1$s</string>
|
||||||
<string name="xkpwgen_builder_error">O dicionário selecionado não contém palavras suficientes de tamanho %1$d..%2$d</string>
|
<string name="xkpwgen_builder_error">O dicionário selecionado não contém palavras suficientes de tamanho %1$d..%2$d</string>
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Tipo de gerador de senha</string>
|
<string name="pref_password_generator_type_title">Tipo de gerador de senha</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Lista de palavras personalizadas</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Lista de palavras personalizadas</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Usando um arquivo de Lista de Palavras</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Usando um arquivo de Lista de Palavras</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Usando o arquivo de palavras embutido</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Usando o arquivo de palavras embutido</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">Lista de palavras personalizadas</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">Lista de palavras personalizadas</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Toque para escolher um arquivo personalizado de lista de palavras contendo uma palavra por linha</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Toque para escolher um arquivo personalizado de lista de palavras contendo uma palavra por linha</string>
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Frase Secreta</string>
|
<string name="ssh_keygen_passphrase">Frase Secreta</string>
|
||||||
<string name="ssh_keygen_generate">Gerar</string>
|
<string name="ssh_keygen_generate">Gerar</string>
|
||||||
|
@ -196,7 +195,7 @@
|
||||||
<string name="show_extra_content_pref_summary">Controlar a visibilidade do conteúdo extra uma vez descriptografado.</string>
|
<string name="show_extra_content_pref_summary">Controlar a visibilidade do conteúdo extra uma vez descriptografado.</string>
|
||||||
<string name="pwd_generate_button">Gerar</string>
|
<string name="pwd_generate_button">Gerar</string>
|
||||||
<string name="refresh_list">Atualizar lista</string>
|
<string name="refresh_list">Atualizar lista</string>
|
||||||
<string name="no_repo_selected">Nenhum repositório externo selecionado</string>
|
<string name="pref_select_external_repository_summary_no_repo_selected">Nenhum repositório externo selecionado</string>
|
||||||
<string name="send_plaintext_password_to">Enviar senha como texto simples usando…</string>
|
<string name="send_plaintext_password_to">Enviar senha como texto simples usando…</string>
|
||||||
<string name="app_icon_hint">Ícone do aplicativo</string>
|
<string name="app_icon_hint">Ícone do aplicativo</string>
|
||||||
<!-- Oreo Autofill -->
|
<!-- Oreo Autofill -->
|
||||||
|
@ -247,10 +246,10 @@
|
||||||
<string name="biometric_prompt_title">Confirmação Biométrica</string>
|
<string name="biometric_prompt_title">Confirmação Biométrica</string>
|
||||||
<string name="biometric_auth_error">Falha de autenticação</string>
|
<string name="biometric_auth_error">Falha de autenticação</string>
|
||||||
<string name="biometric_auth_error_reason">Falha de autenticação: %s</string>
|
<string name="biometric_auth_error_reason">Falha de autenticação: %s</string>
|
||||||
<string name="biometric_auth_title">Ativar autenticação biométrica</string>
|
<string name="pref_biometric_auth_title">Ativar autenticação biométrica</string>
|
||||||
<string name="biometric_auth_summary">Quando ativado, o Password Store irá pedir a sua impressão digital ao iniciar o aplicativo</string>
|
<string name="pref_biometric_auth_summary">Quando ativado, o Password Store irá pedir a sua impressão digital ao iniciar o aplicativo</string>
|
||||||
<string name="biometric_auth_summary_error">Hardware de impressão digital não acessível ou ausente</string>
|
<string name="pref_biometric_auth_summary_error">Hardware de impressão digital não acessível ou ausente</string>
|
||||||
<string name="ssh_openkeystore_clear_keyid">Limpar ID de chave SSH lembrada do OpenKeystore</string>
|
<string name="pref_title_openkeystore_clear_keyid">Limpar ID de chave SSH lembrada do OpenKeystore</string>
|
||||||
<string name="access_sdcard_text">O local do armazenamento está em seu cartão SD ou armazenamento interno, mas o aplicativo não tem permissão para acessá-lo.</string>
|
<string name="access_sdcard_text">O local do armazenamento está em seu cartão SD ou armazenamento interno, mas o aplicativo não tem permissão para acessá-lo.</string>
|
||||||
<string name="your_public_key">Sua chave pública</string>
|
<string name="your_public_key">Sua chave pública</string>
|
||||||
<string name="error_generate_ssh_key">Erro ao tentar gerar a chave SSH</string>
|
<string name="error_generate_ssh_key">Erro ao tentar gerar a chave SSH</string>
|
||||||
|
@ -263,16 +262,15 @@
|
||||||
<string name="message_error_destination_outside_repo">O destino deve estar dentro do repositório</string>
|
<string name="message_error_destination_outside_repo">O destino deve estar dentro do repositório</string>
|
||||||
<string name="message_rename_folder">Insira o destino para %1$s</string>
|
<string name="message_rename_folder">Insira o destino para %1$s</string>
|
||||||
<string name="button_create">Criar</string>
|
<string name="button_create">Criar</string>
|
||||||
<string name="pref_search_on_start">Abrir pesquisa ao inicializar</string>
|
<string name="pref_search_on_start_title">Abrir pesquisa ao inicializar</string>
|
||||||
<string name="pref_search_on_start_hint">Abrir barra de pesquisa quando o aplicativo for iniciado</string>
|
<string name="pref_search_on_start_summary">Abrir barra de pesquisa quando o aplicativo for iniciado</string>
|
||||||
<string name="password_generator_category_title">Gerador de Senha</string>
|
|
||||||
<string name="tap_clear_clipboard">Toque aqui para limpar a área de transferência</string>
|
<string name="tap_clear_clipboard">Toque aqui para limpar a área de transferência</string>
|
||||||
<string name="clone_git_repo">O repositório deve ser clonado antes de sincronizar as alterações.</string>
|
<string name="clone_git_repo">O repositório deve ser clonado antes de sincronizar as alterações.</string>
|
||||||
<string name="theme_title">Tema do aplicativo</string>
|
<string name="pref_app_theme_title">Tema do aplicativo</string>
|
||||||
<string name="theme_light">Claro</string>
|
<string name="pref_app_theme_value_light">Claro</string>
|
||||||
<string name="theme_dark">Escuro</string>
|
<string name="pref_app_theme_value_dark">Escuro</string>
|
||||||
<string name="theme_battery_saver">Configurado pela Economia de bateria</string>
|
<string name="pref_app_theme_value_battery_saver">Configurado pela Economia de bateria</string>
|
||||||
<string name="theme_follow_system">Padrão do sistema</string>
|
<string name="pref_app_theme_value_follow_system">Padrão do sistema</string>
|
||||||
<string name="connection_mode_ssh_key">Chave SSH</string>
|
<string name="connection_mode_ssh_key">Chave SSH</string>
|
||||||
<string name="connection_mode_basic_authentication">Senha</string>
|
<string name="connection_mode_basic_authentication">Senha</string>
|
||||||
<string name="git_server_config_save_success">Configuração salva com sucesso</string>
|
<string name="git_server_config_save_success">Configuração salva com sucesso</string>
|
||||||
|
|
|
@ -97,43 +97,42 @@
|
||||||
<string name="share_as_plaintext">Поделиться в открытом виде</string>
|
<string name="share_as_plaintext">Поделиться в открытом виде</string>
|
||||||
<string name="last_changed">Последние изменение %s</string>
|
<string name="last_changed">Последние изменение %s</string>
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Репозиторий</string>
|
<string name="pref_category_repository_title">Репозиторий</string>
|
||||||
<string name="pref_edit_server_info">Изменить настройки сервера Git</string>
|
<string name="pref_edit_git_server_settings">Изменить настройки сервера Git</string>
|
||||||
<string name="pref_edit_git_config">Конфигурация локального Git</string>
|
<string name="pref_edit_git_config">Конфигурация локального Git</string>
|
||||||
<string name="pref_ssh_title">Импортировать SSH ключ</string>
|
<string name="pref_import_ssh_key_title">Импортировать SSH ключ</string>
|
||||||
<string name="pref_ssh_keygen_title">Сгенерировать пару SSH ключей</string>
|
<string name="pref_ssh_keygen_title">Сгенерировать пару SSH ключей</string>
|
||||||
<string name="pref_ssh_see_key_title">Просмотреть публичный SSH ключ</string>
|
<string name="pref_ssh_see_key_title">Просмотреть публичный SSH ключ</string>
|
||||||
<string name="pref_git_delete_repo">Удалить репозиторий</string>
|
<string name="pref_git_delete_repo_title">Удалить репозиторий</string>
|
||||||
<string name="pref_dialog_delete_title">Очистить репозиторий</string>
|
<string name="pref_dialog_delete_title">Очистить репозиторий</string>
|
||||||
<string name="pref_category_general_title">Общие</string>
|
<string name="pref_category_general_title">Общие</string>
|
||||||
<string name="pref_category_title_passwords">Пароли</string>
|
<string name="pref_category_passwords_title">Пароли</string>
|
||||||
<string name="pref_clipboard_timeout_title">Срок хранения пароля в буфере обмена</string>
|
<string name="pref_clipboard_timeout_title">Срок хранения пароля в буфере обмена</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Установите время (в секундах), которое вы хотите, чтобы пароль был в буфере обмена. 0 означает навсегда. Текущее значение: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Установите время (в секундах), которое вы хотите, чтобы пароль был в буфере обмена. 0 означает навсегда. Текущее значение: %1$s</string>
|
||||||
<string name="pref_copy_title">Автоматически копировать пароль</string>
|
<string name="pref_copy_title">Автоматически копировать пароль</string>
|
||||||
<string name="pref_copy_dialog_title">Автоматически копировать пароль в буфер обмена после успешного расшифрования</string>
|
<string name="pref_copy_summary">Автоматически копировать пароль в буфер обмена после успешного расшифрования</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">Выбранный файл не похож на приватный SSH-ключ.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">Выбранный файл не похож на приватный SSH-ключ.</string>
|
||||||
<string name="ssh_key_success_dialog_title">SSH ключ импортирован</string>
|
<string name="ssh_key_success_dialog_title">SSH ключ импортирован</string>
|
||||||
<string name="ssh_key_error_dialog_title">Ошибка импорта ключа</string>
|
<string name="ssh_key_error_dialog_title">Ошибка импорта ключа</string>
|
||||||
<string name="ssh_key_error_dialog_text">Сообщение: \n</string>
|
<string name="ssh_key_error_dialog_text">Сообщение: \n</string>
|
||||||
<string name="pref_recursive_filter">Рекурсивная фильтрация</string>
|
<string name="pref_recursive_filter_title">Рекурсивная фильтрация</string>
|
||||||
<string name="pref_recursive_filter_hint">Рекурсивный поиск паролей в текущей директории</string>
|
<string name="pref_recursive_filter_summary">Рекурсивный поиск паролей в текущей директории</string>
|
||||||
<string name="pref_sort_order_title">Порядок сортировки паролей</string>
|
<string name="pref_sort_order_title">Порядок сортировки паролей</string>
|
||||||
<string name="pref_folder_first_sort_order">Сначала папки</string>
|
<string name="pref_folder_first_sort_order">Сначала папки</string>
|
||||||
<string name="pref_file_first_sort_order">Сначала файлы</string>
|
<string name="pref_file_first_sort_order">Сначала файлы</string>
|
||||||
<string name="pref_type_independent_sort_order">Типонезависимый</string>
|
<string name="pref_type_independent_sort_order">Типонезависимый</string>
|
||||||
<string name="pref_recently_used_sort_order">Недавно использованные</string>
|
<string name="pref_recently_used_sort_order">Недавно использованные</string>
|
||||||
<string name="pref_autofill_title">Автозаполнение</string>
|
<string name="pref_category_autofill_title">Автозаполнение</string>
|
||||||
<string name="pref_autofill_enable_title">Включить автозаполнение</string>
|
<string name="pref_autofill_enable_title">Включить автозаполнение</string>
|
||||||
<string name="pref_misc_title">Другое</string>
|
<string name="pref_category_misc_title">Другое</string>
|
||||||
<string name="pref_clear_clipboard_title">Очистить буфер 20 раз</string>
|
<string name="pref_clear_clipboard_title">Очистить буфер 20 раз</string>
|
||||||
<string name="pref_clear_clipboard_hint">Вставлять чепуху в буфер обмена 20 раз вместо одного. Полезно на некоторых моделях телефонов с запоминанием истории буфера обмена</string>
|
<string name="pref_clear_clipboard_summary">Вставлять чепуху в буфер обмена 20 раз вместо одного. Полезно на некоторых моделях телефонов с запоминанием истории буфера обмена</string>
|
||||||
<string name="pref_git_delete_repo_summary">Удалить локальный (скрытый) репозиторий</string>
|
<string name="pref_git_delete_repo_summary">Удалить локальный (скрытый) репозиторий</string>
|
||||||
<string name="pref_external_repository">Внешний репозиторий</string>
|
<string name="pref_external_repository_title">Внешний репозиторий</string>
|
||||||
<string name="pref_external_repository_summary">Использовать внешний репозиторий</string>
|
<string name="pref_external_repository_summary">Использовать внешний репозиторий</string>
|
||||||
<string name="pref_select_external_repository">Выбрать внешний репозиторий</string>
|
<string name="pref_select_external_repository_title">Выбрать внешний репозиторий</string>
|
||||||
<string name="prefs_export_passwords_title">Экспортировать пароли</string>
|
<string name="prefs_export_passwords_title">Экспортировать пароли</string>
|
||||||
<string name="prefs_export_passwords_summary">Экспортировать пароли в открытом виде во внешнее хранилище</string>
|
<string name="prefs_export_passwords_summary">Экспортировать пароли в открытом виде во внешнее хранилище</string>
|
||||||
<string name="prefs_version">Версия</string>
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Сгенерировать пароль</string>
|
<string name="pwgen_title">Сгенерировать пароль</string>
|
||||||
<string name="pwgen_generate">Сгенерировать</string>
|
<string name="pwgen_generate">Сгенерировать</string>
|
||||||
|
@ -155,12 +154,12 @@
|
||||||
<string name="xkpwgen_custom_dict_imported">Пользовательский список слов: %1$s</string>
|
<string name="xkpwgen_custom_dict_imported">Пользовательский список слов: %1$s</string>
|
||||||
<string name="xkpwgen_builder_error">Выбранный словарь не содержит достаточного количества слова заданной длинны %1$d..%2$d</string>
|
<string name="xkpwgen_builder_error">Выбранный словарь не содержит достаточного количества слова заданной длинны %1$d..%2$d</string>
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Тип генератора паролей</string>
|
<string name="pref_password_generator_type_title">Тип генератора паролей</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Пользовательский список слов</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Пользовательский список слов</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Использовать файл списка слов созданный пользователем</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Использовать файл списка слов созданный пользователем</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Использовать встроенный список слов</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Использовать встроенный список слов</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">Файл пользовательского списка слов</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">Файл пользовательского списка слов</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Нажмите чтобы выбрать файл пользовательского списка слов содержащий одно слово на строку</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Нажмите чтобы выбрать файл пользовательского списка слов содержащий одно слово на строку</string>
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Пароль</string>
|
<string name="ssh_keygen_passphrase">Пароль</string>
|
||||||
<string name="ssh_keygen_generate">Сгенерировать</string>
|
<string name="ssh_keygen_generate">Сгенерировать</string>
|
||||||
|
@ -200,7 +199,7 @@
|
||||||
<string name="show_extra_content_pref_summary">Видимость поля дополнительной информации после расшифрования</string>
|
<string name="show_extra_content_pref_summary">Видимость поля дополнительной информации после расшифрования</string>
|
||||||
<string name="pwd_generate_button">Сгенерировать</string>
|
<string name="pwd_generate_button">Сгенерировать</string>
|
||||||
<string name="refresh_list">Обновить список</string>
|
<string name="refresh_list">Обновить список</string>
|
||||||
<string name="no_repo_selected">Внешний репозиторий не выбран</string>
|
<string name="pref_select_external_repository_summary_no_repo_selected">Внешний репозиторий не выбран</string>
|
||||||
<string name="send_plaintext_password_to">Поделиться паролем в открытом виде с помощью</string>
|
<string name="send_plaintext_password_to">Поделиться паролем в открытом виде с помощью</string>
|
||||||
<string name="app_icon_hint">Иконка приложения</string>
|
<string name="app_icon_hint">Иконка приложения</string>
|
||||||
<!-- Oreo Autofill -->
|
<!-- Oreo Autofill -->
|
||||||
|
@ -251,10 +250,10 @@
|
||||||
<string name="biometric_prompt_title">Запрос биометрии</string>
|
<string name="biometric_prompt_title">Запрос биометрии</string>
|
||||||
<string name="biometric_auth_error">Ошибка авторизации</string>
|
<string name="biometric_auth_error">Ошибка авторизации</string>
|
||||||
<string name="biometric_auth_error_reason">Ошибка аутентификации: %s</string>
|
<string name="biometric_auth_error_reason">Ошибка аутентификации: %s</string>
|
||||||
<string name="biometric_auth_title">Включить биометрическую аутентификацию</string>
|
<string name="pref_biometric_auth_title">Включить биометрическую аутентификацию</string>
|
||||||
<string name="biometric_auth_summary">Когда ключено, Password Store будет запрашивать ваш опечаток пальца при каждом запуске приложения</string>
|
<string name="pref_biometric_auth_summary">Когда ключено, Password Store будет запрашивать ваш опечаток пальца при каждом запуске приложения</string>
|
||||||
<string name="biometric_auth_summary_error">Сенсор отпечатка пальца не доступен или отсутствует</string>
|
<string name="pref_biometric_auth_summary_error">Сенсор отпечатка пальца не доступен или отсутствует</string>
|
||||||
<string name="ssh_openkeystore_clear_keyid">Очистить сохраненный SSH Key идентификатор OpenKystortore</string>
|
<string name="pref_title_openkeystore_clear_keyid">Очистить сохраненный SSH Key идентификатор OpenKystortore</string>
|
||||||
<string name="access_sdcard_text">Хранилище расположено на вашей SD-карте или во внутреннем хранилище, но у приложения нет разрешения на доступ к нему.</string>
|
<string name="access_sdcard_text">Хранилище расположено на вашей SD-карте или во внутреннем хранилище, но у приложения нет разрешения на доступ к нему.</string>
|
||||||
<string name="your_public_key">Ваш публичный ключ</string>
|
<string name="your_public_key">Ваш публичный ключ</string>
|
||||||
<string name="error_generate_ssh_key">Возникла ошибка при попытке генерации ssh ключа</string>
|
<string name="error_generate_ssh_key">Возникла ошибка при попытке генерации ssh ключа</string>
|
||||||
|
@ -267,16 +266,15 @@
|
||||||
<string name="message_error_destination_outside_repo">Путь должен указывать на область внутри репозитория</string>
|
<string name="message_error_destination_outside_repo">Путь должен указывать на область внутри репозитория</string>
|
||||||
<string name="message_rename_folder">Введите адрес назначения для %1$s</string>
|
<string name="message_rename_folder">Введите адрес назначения для %1$s</string>
|
||||||
<string name="button_create">Создать</string>
|
<string name="button_create">Создать</string>
|
||||||
<string name="pref_search_on_start">Открыть поиск на старте</string>
|
<string name="pref_search_on_start_title">Открыть поиск на старте</string>
|
||||||
<string name="pref_search_on_start_hint">Открыть панель поиска при запуске приложения</string>
|
<string name="pref_search_on_start_summary">Открыть панель поиска при запуске приложения</string>
|
||||||
<string name="password_generator_category_title">Генератор паролей</string>
|
|
||||||
<string name="tap_clear_clipboard">Нажмите здесь чтобы очистить буфер обмена</string>
|
<string name="tap_clear_clipboard">Нажмите здесь чтобы очистить буфер обмена</string>
|
||||||
<string name="clone_git_repo">Для синхронизации изменений клонируйте git репозиторий</string>
|
<string name="clone_git_repo">Для синхронизации изменений клонируйте git репозиторий</string>
|
||||||
<string name="theme_title">Тема приложения</string>
|
<string name="pref_app_theme_title">Тема приложения</string>
|
||||||
<string name="theme_light">Светлая</string>
|
<string name="pref_app_theme_value_light">Светлая</string>
|
||||||
<string name="theme_dark">Темная</string>
|
<string name="pref_app_theme_value_dark">Темная</string>
|
||||||
<string name="theme_battery_saver">Задается экономией батареи</string>
|
<string name="pref_app_theme_value_battery_saver">Задается экономией батареи</string>
|
||||||
<string name="theme_follow_system">Системная</string>
|
<string name="pref_app_theme_value_follow_system">Системная</string>
|
||||||
<string name="connection_mode_ssh_key">SSH ключ</string>
|
<string name="connection_mode_ssh_key">SSH ключ</string>
|
||||||
<string name="connection_mode_basic_authentication">Пароль</string>
|
<string name="connection_mode_basic_authentication">Пароль</string>
|
||||||
<string name="git_server_config_save_success">Конфигурация успешно сохранена</string>
|
<string name="git_server_config_save_success">Конфигурация успешно сохранена</string>
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="app_theme_options">
|
<string-array name="app_theme_options">
|
||||||
<item>@string/theme_light</item>
|
<item>@string/pref_app_theme_value_light</item>
|
||||||
<item>@string/theme_dark</item>
|
<item>@string/pref_app_theme_value_dark</item>
|
||||||
<item>@string/theme_follow_system</item>
|
<item>@string/pref_app_theme_value_follow_system</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="app_theme_values">
|
<string-array name="app_theme_values">
|
||||||
<item>light</item>
|
<item>light</item>
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
<item>directory</item>
|
<item>directory</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="app_theme_options">
|
<string-array name="app_theme_options">
|
||||||
<item>@string/theme_light</item>
|
<item>@string/pref_app_theme_value_light</item>
|
||||||
<item>@string/theme_dark</item>
|
<item>@string/pref_app_theme_value_dark</item>
|
||||||
<item>@string/theme_battery_saver</item>
|
<item>@string/pref_app_theme_value_battery_saver</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="app_theme_values">
|
<string-array name="app_theme_values">
|
||||||
<item>light</item>
|
<item>light</item>
|
||||||
|
|
|
@ -110,43 +110,43 @@
|
||||||
<string name="last_changed">Last changed %s</string>
|
<string name="last_changed">Last changed %s</string>
|
||||||
|
|
||||||
<!-- Preferences -->
|
<!-- Preferences -->
|
||||||
<string name="pref_repository_title">Repository</string>
|
<string name="pref_category_repository_title">Repository</string>
|
||||||
<string name="pref_edit_server_info">Edit Git server settings</string>
|
<string name="pref_edit_git_server_settings">Edit Git server settings</string>
|
||||||
<string name="pref_edit_git_config">Local Git config & utilities</string>
|
<string name="pref_edit_git_config">Local Git config & utilities</string>
|
||||||
<string name="pref_ssh_title">Import SSH key</string>
|
<string name="pref_import_ssh_key_title">Import SSH key</string>
|
||||||
<string name="pref_ssh_keygen_title">Generate SSH key pair</string>
|
<string name="pref_ssh_keygen_title">Generate SSH key pair</string>
|
||||||
<string name="pref_ssh_see_key_title">View generated public SSH key</string>
|
<string name="pref_ssh_see_key_title">View generated public SSH key</string>
|
||||||
<string name="pref_git_delete_repo">Delete repository</string>
|
<string name="pref_git_delete_repo_title">Delete repository</string>
|
||||||
<string name="pref_dialog_delete_title">Clear repository</string>
|
<string name="pref_dialog_delete_title">Clear repository</string>
|
||||||
<string name="pref_category_general_title">General</string>
|
<string name="pref_category_general_title">General</string>
|
||||||
<string name="pref_category_title_passwords">Passwords</string>
|
<string name="pref_category_passwords_title">Passwords</string>
|
||||||
<string name="pref_clipboard_timeout_title">Password copy timeout</string>
|
<string name="pref_clipboard_timeout_title">Password copy timeout</string>
|
||||||
<string name="pref_clipboard_timeout_summary">Set the time (in seconds) you want the password to be in clipboard. 0 means forever. Current value: %1$s</string>
|
<string name="pref_clipboard_timeout_summary">Set the time (in seconds) you want the password to be in clipboard. 0 means forever. Current value: %1$s</string>
|
||||||
<string name="pref_copy_title">Automatically copy password</string>
|
<string name="pref_copy_title">Automatically copy password</string>
|
||||||
<string name="pref_copy_dialog_title">Automatically copy the password to the clipboard after decryption was successful.</string>
|
<string name="pref_copy_summary">Automatically copy the password to the clipboard after decryption was successful.</string>
|
||||||
<string name="ssh_key_import_error_not_an_ssh_key_message">Selected file does not appear to be an SSH private key.</string>
|
<string name="ssh_key_import_error_not_an_ssh_key_message">Selected file does not appear to be an SSH private key.</string>
|
||||||
<string name="ssh_key_success_dialog_title">SSH-key imported</string>
|
<string name="ssh_key_success_dialog_title">SSH-key imported</string>
|
||||||
<string name="ssh_key_error_dialog_title">Key import error</string>
|
<string name="ssh_key_error_dialog_title">Key import error</string>
|
||||||
<string name="ssh_key_error_dialog_text">Message : \n</string>
|
<string name="ssh_key_error_dialog_text">Message : \n</string>
|
||||||
<string name="pref_recursive_filter">Recursive filtering</string>
|
<string name="pref_recursive_filter_title">Recursive filtering</string>
|
||||||
<string name="pref_recursive_filter_hint">Recursively find passwords of the current directory.</string>
|
<string name="pref_recursive_filter_summary">Recursively find passwords of the current directory.</string>
|
||||||
<string name="pref_sort_order_title">Password sort order</string>
|
<string name="pref_sort_order_title">Password sort order</string>
|
||||||
<string name="pref_folder_first_sort_order">Folders first</string>
|
<string name="pref_folder_first_sort_order">Folders first</string>
|
||||||
<string name="pref_file_first_sort_order">Files first</string>
|
<string name="pref_file_first_sort_order">Files first</string>
|
||||||
<string name="pref_type_independent_sort_order">Type independent</string>
|
<string name="pref_type_independent_sort_order">Type independent</string>
|
||||||
<string name="pref_recently_used_sort_order">Recently used</string>
|
<string name="pref_recently_used_sort_order">Recently used</string>
|
||||||
<string name="pref_autofill_title">Autofill</string>
|
<string name="pref_category_autofill_title">Autofill</string>
|
||||||
<string name="pref_autofill_enable_title">Enable Autofill</string>
|
<string name="pref_autofill_enable_title">Enable Autofill</string>
|
||||||
<string name="pref_misc_title">Misc</string>
|
<string name="pref_category_misc_title">Misc</string>
|
||||||
<string name="pref_clear_clipboard_title">Clear clipboard 20 times</string>
|
<string name="pref_clear_clipboard_title">Clear clipboard 20 times</string>
|
||||||
<string name="pref_clear_clipboard_hint">Store consecutive numbers in the clipboard 20 times. Useful on Samsung phones that feature clipboard history.</string>
|
<string name="pref_clear_clipboard_summary">Store consecutive numbers in the clipboard 20 times. Useful on Samsung phones that feature clipboard history.</string>
|
||||||
<string name="pref_git_delete_repo_summary">Deletes local (hidden) repository</string>
|
<string name="pref_git_delete_repo_summary">Deletes local (hidden) repository</string>
|
||||||
<string name="pref_external_repository">External repository</string>
|
<string name="pref_external_repository_title">External repository</string>
|
||||||
<string name="pref_external_repository_summary">Use an external password repository</string>
|
<string name="pref_external_repository_summary">Use an external password repository</string>
|
||||||
<string name="pref_select_external_repository">Select external repository</string>
|
<string name="pref_select_external_repository_title">Select external repository</string>
|
||||||
|
<string name="pref_select_external_repository_summary_no_repo_selected">No external repository selected</string>
|
||||||
<string name="prefs_export_passwords_title">Export passwords</string>
|
<string name="prefs_export_passwords_title">Export passwords</string>
|
||||||
<string name="prefs_export_passwords_summary">Exports the encrypted passwords to an external directory</string>
|
<string name="prefs_export_passwords_summary">Exports the encrypted passwords to an external directory</string>
|
||||||
<string name="prefs_version">Version</string>
|
|
||||||
|
|
||||||
<!-- PasswordGenerator fragment -->
|
<!-- PasswordGenerator fragment -->
|
||||||
<string name="pwgen_title">Generate Password</string>
|
<string name="pwgen_title">Generate Password</string>
|
||||||
|
@ -171,12 +171,12 @@
|
||||||
<string name="xkpwgen_builder_error">Selected dictionary does not contain enough words of given length %1$d..%2$d</string>
|
<string name="xkpwgen_builder_error">Selected dictionary does not contain enough words of given length %1$d..%2$d</string>
|
||||||
|
|
||||||
<!-- XKPWD prefs -->
|
<!-- XKPWD prefs -->
|
||||||
<string name="xkpwgen_pref_gentype_title">Password generator type</string>
|
<string name="pref_password_generator_type_title">Password generator type</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_title">Custom wordlist</string>
|
<string name="pref_xkpwgen_custom_wordlist_enabled_title">Custom wordlist</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_on">Using custom wordlist file</string>
|
<string name="pref_xkpwgen_custom_dict_summary_on">Using custom wordlist file</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_summary_off">Using built-in wordlist</string>
|
<string name="pref_xkpwgen_custom_dict_summary_off">Using built-in wordlist</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_title">Custom worldlist file</string>
|
<string name="pref_xkpwgen_custom_dict_picker_title">Custom worldlist file</string>
|
||||||
<string name="xkpwgen_pref_custom_dict_picker_summary">Tap to pick a custom wordlist file containing one word per line</string>
|
<string name="pref_xkpwgen_custom_dict_picker_summary">Tap to pick a custom wordlist file containing one word per line</string>
|
||||||
|
|
||||||
<!-- ssh keygen fragment -->
|
<!-- ssh keygen fragment -->
|
||||||
<string name="ssh_keygen_passphrase">Passphrase</string>
|
<string name="ssh_keygen_passphrase">Passphrase</string>
|
||||||
|
@ -220,7 +220,6 @@
|
||||||
<string name="show_extra_content_pref_summary">Control the visibility of the extra content once decrypted.</string>
|
<string name="show_extra_content_pref_summary">Control the visibility of the extra content once decrypted.</string>
|
||||||
<string name="pwd_generate_button">Generate</string>
|
<string name="pwd_generate_button">Generate</string>
|
||||||
<string name="refresh_list">Refresh list</string>
|
<string name="refresh_list">Refresh list</string>
|
||||||
<string name="no_repo_selected">No external repository selected</string>
|
|
||||||
<string name="send_plaintext_password_to">Send password as plaintext using…</string>
|
<string name="send_plaintext_password_to">Send password as plaintext using…</string>
|
||||||
<string name="app_icon_hint">App icon</string>
|
<string name="app_icon_hint">App icon</string>
|
||||||
|
|
||||||
|
@ -271,14 +270,15 @@
|
||||||
<string name="git_head_missing">Unable to locate HEAD</string>
|
<string name="git_head_missing">Unable to locate HEAD</string>
|
||||||
<string name="sdcard_root_warning_title">SD-Card root selected</string>
|
<string name="sdcard_root_warning_title">SD-Card root selected</string>
|
||||||
<string name="sdcard_root_warning_message">You have selected the root of your sdcard for the store. This is extremely dangerous and you will lose your data as its content will, eventually, be deleted</string>
|
<string name="sdcard_root_warning_message">You have selected the root of your sdcard for the store. This is extremely dangerous and you will lose your data as its content will, eventually, be deleted</string>
|
||||||
|
<string name="sdcard_root_warning_remove_everything">Remove everything</string>
|
||||||
<string name="git_abort_and_push_title">Abort and Push</string>
|
<string name="git_abort_and_push_title">Abort and Push</string>
|
||||||
<string name="biometric_prompt_title">Biometric Prompt</string>
|
<string name="biometric_prompt_title">Biometric Prompt</string>
|
||||||
<string name="biometric_auth_error">Authentication failure</string>
|
<string name="biometric_auth_error">Authentication failure</string>
|
||||||
<string name="biometric_auth_error_reason">Authentication failure: %s</string>
|
<string name="biometric_auth_error_reason">Authentication failure: %s</string>
|
||||||
<string name="biometric_auth_title">Enable biometric authentication</string>
|
<string name="pref_biometric_auth_title">Enable biometric authentication</string>
|
||||||
<string name="biometric_auth_summary">When enabled, Password Store will prompt you for your fingerprint when launching the app</string>
|
<string name="pref_biometric_auth_summary">When enabled, Password Store will prompt you for your fingerprint when launching the app</string>
|
||||||
<string name="biometric_auth_summary_error">Fingerprint hardware not accessible or missing</string>
|
<string name="pref_biometric_auth_summary_error">Fingerprint hardware not accessible or missing</string>
|
||||||
<string name="ssh_openkeystore_clear_keyid">Clear remembered OpenKeystore SSH Key ID</string>
|
<string name="pref_title_openkeystore_clear_keyid">Clear remembered OpenKeystore SSH Key ID</string>
|
||||||
<string name="access_sdcard_text">The store location is in your SD Card or Internal storage, but the app does not have permission to access it.</string>
|
<string name="access_sdcard_text">The store location is in your SD Card or Internal storage, but the app does not have permission to access it.</string>
|
||||||
<string name="your_public_key">Your public key</string>
|
<string name="your_public_key">Your public key</string>
|
||||||
<string name="error_generate_ssh_key">Error while trying to generate the ssh-key</string>
|
<string name="error_generate_ssh_key">Error while trying to generate the ssh-key</string>
|
||||||
|
@ -291,16 +291,15 @@
|
||||||
<string name="message_error_destination_outside_repo">Destination must be within the repository</string>
|
<string name="message_error_destination_outside_repo">Destination must be within the repository</string>
|
||||||
<string name="message_rename_folder">Enter destination for %1$s</string>
|
<string name="message_rename_folder">Enter destination for %1$s</string>
|
||||||
<string name="button_create">Create</string>
|
<string name="button_create">Create</string>
|
||||||
<string name="pref_search_on_start">Open search on start</string>
|
<string name="pref_search_on_start_title">Open search on start</string>
|
||||||
<string name="pref_search_on_start_hint">Open search bar when app is launched</string>
|
<string name="pref_search_on_start_summary">Open search bar when app is launched</string>
|
||||||
<string name="password_generator_category_title">Password Generator</string>
|
|
||||||
<string name="tap_clear_clipboard">Tap here to clear clipboard</string>
|
<string name="tap_clear_clipboard">Tap here to clear clipboard</string>
|
||||||
<string name="clone_git_repo">The repository must be cloned before syncing changes.</string>
|
<string name="clone_git_repo">The repository must be cloned before syncing changes.</string>
|
||||||
<string name="theme_title">App theme</string>
|
<string name="pref_app_theme_title">App theme</string>
|
||||||
<string name="theme_light">Light</string>
|
<string name="pref_app_theme_value_light">Light</string>
|
||||||
<string name="theme_dark">Dark</string>
|
<string name="pref_app_theme_value_dark">Dark</string>
|
||||||
<string name="theme_battery_saver">Set by Battery Saver</string>
|
<string name="pref_app_theme_value_battery_saver">Set by Battery Saver</string>
|
||||||
<string name="theme_follow_system">System default</string>
|
<string name="pref_app_theme_value_follow_system">System default</string>
|
||||||
<string name="connection_mode_ssh_key">SSH key</string>
|
<string name="connection_mode_ssh_key">SSH key</string>
|
||||||
<string name="connection_mode_basic_authentication">Password</string>
|
<string name="connection_mode_basic_authentication">Password</string>
|
||||||
<string name="connection_mode_openkeychain" translatable="false">OpenKeychain</string>
|
<string name="connection_mode_openkeychain" translatable="false">OpenKeychain</string>
|
||||||
|
@ -389,7 +388,7 @@
|
||||||
<!-- Proxy configuration activity -->
|
<!-- Proxy configuration activity -->
|
||||||
<string name="proxy_hostname">Proxy hostname</string>
|
<string name="proxy_hostname">Proxy hostname</string>
|
||||||
<string name="port">Port</string>
|
<string name="port">Port</string>
|
||||||
<string name="pref_proxy_settings">HTTP(S) proxy settings</string>
|
<string name="pref_edit_proxy_settings">HTTP(S) proxy settings</string>
|
||||||
<string name="invalid_proxy_url">Invalid URL</string>
|
<string name="invalid_proxy_url">Invalid URL</string>
|
||||||
<string name="oreo_autofill_password_fill_and_conditional_save_support">Fill and save passwords (saving requires that no accessibility services are enabled)</string>
|
<string name="oreo_autofill_password_fill_and_conditional_save_support">Fill and save passwords (saving requires that no accessibility services are enabled)</string>
|
||||||
<string name="clear_saved_host_key">Clear saved host key</string>
|
<string name="clear_saved_host_key">Clear saved host key</string>
|
||||||
|
|
|
@ -1,174 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
~ Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
|
||||||
~ SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<PreferenceCategory app:title="@string/pref_autofill_title">
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
app:defaultValue="true"
|
|
||||||
app:key="autofill_enable"
|
|
||||||
app:title="@string/pref_autofill_enable_title" />
|
|
||||||
<ListPreference
|
|
||||||
app:defaultValue="file"
|
|
||||||
app:entries="@array/oreo_autofill_directory_structure_entries"
|
|
||||||
app:entryValues="@array/oreo_autofill_directory_structure_values"
|
|
||||||
app:key="oreo_autofill_directory_structure"
|
|
||||||
app:title="@string/oreo_autofill_preference_directory_structure"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
<EditTextPreference
|
|
||||||
app:key="oreo_autofill_default_username"
|
|
||||||
app:summary="@string/preference_default_username_summary"
|
|
||||||
app:title="@string/preference_default_username_title" />
|
|
||||||
<EditTextPreference
|
|
||||||
app:key="oreo_autofill_custom_public_suffixes"
|
|
||||||
app:summary="@string/preference_custom_public_suffixes_summary"
|
|
||||||
app:title="@string/preference_custom_public_suffixes_title" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/pref_repository_title">
|
|
||||||
<Preference
|
|
||||||
app:key="git_server_info"
|
|
||||||
app:title="@string/pref_edit_server_info" />
|
|
||||||
<Preference
|
|
||||||
app:key="proxy_settings"
|
|
||||||
app:title="@string/pref_proxy_settings" />
|
|
||||||
<Preference
|
|
||||||
app:key="git_config"
|
|
||||||
app:title="@string/pref_edit_git_config" />
|
|
||||||
<Preference
|
|
||||||
app:key="ssh_key"
|
|
||||||
app:title="@string/pref_ssh_title" />
|
|
||||||
<Preference
|
|
||||||
app:key="ssh_keygen"
|
|
||||||
app:title="@string/pref_ssh_keygen_title" />
|
|
||||||
<Preference app:key="clear_saved_pass" />
|
|
||||||
<Preference
|
|
||||||
app:key="ssh_openkeystore_clear_keyid"
|
|
||||||
app:title="@string/ssh_openkeystore_clear_keyid" />
|
|
||||||
<Preference
|
|
||||||
app:key="ssh_see_key"
|
|
||||||
app:title="@string/pref_ssh_see_key_title" />
|
|
||||||
<Preference
|
|
||||||
app:key="git_delete_repo"
|
|
||||||
app:summary="@string/pref_git_delete_repo_summary"
|
|
||||||
app:title="@string/pref_git_delete_repo" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:key="git_external"
|
|
||||||
app:summary="@string/pref_external_repository_summary"
|
|
||||||
app:title="@string/pref_external_repository" />
|
|
||||||
<Preference
|
|
||||||
app:dependency="git_external"
|
|
||||||
app:key="pref_select_external"
|
|
||||||
app:title="@string/pref_select_external_repository" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/password_generator_category_title">
|
|
||||||
<ListPreference
|
|
||||||
app:defaultValue="classic"
|
|
||||||
app:entries="@array/pwgen_provider_labels"
|
|
||||||
app:entryValues="@array/pwgen_provider_values"
|
|
||||||
app:key="pref_key_pwgen_type"
|
|
||||||
app:persistent="true"
|
|
||||||
app:title="@string/xkpwgen_pref_gentype_title"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:key="pref_key_is_custom_dict"
|
|
||||||
app:summaryOff="@string/xkpwgen_pref_custom_dict_summary_off"
|
|
||||||
app:summaryOn="@string/xkpwgen_pref_custom_dict_summary_on"
|
|
||||||
app:title="@string/xkpwgen_pref_custom_dict_title" />
|
|
||||||
<Preference
|
|
||||||
app:dependency="pref_key_is_custom_dict"
|
|
||||||
app:key="pref_key_custom_dict"
|
|
||||||
app:summary="@string/xkpwgen_pref_custom_dict_picker_summary"
|
|
||||||
app:title="@string/xkpwgen_pref_custom_dict_picker_title" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/pref_category_general_title">
|
|
||||||
<ListPreference
|
|
||||||
android:defaultValue="@string/app_theme_def"
|
|
||||||
android:entries="@array/app_theme_options"
|
|
||||||
android:entryValues="@array/app_theme_values"
|
|
||||||
android:key="app_theme"
|
|
||||||
android:summary="%s"
|
|
||||||
android:title="@string/theme_title" />
|
|
||||||
<ListPreference
|
|
||||||
app:defaultValue="FOLDER_FIRST"
|
|
||||||
app:entries="@array/sort_order_entries"
|
|
||||||
app:entryValues="@array/sort_order_values"
|
|
||||||
app:key="sort_order"
|
|
||||||
app:persistent="true"
|
|
||||||
app:summary="%s"
|
|
||||||
app:title="@string/pref_sort_order_title" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="true"
|
|
||||||
app:key="filter_recursively"
|
|
||||||
app:summary="@string/pref_recursive_filter_hint"
|
|
||||||
app:title="@string/pref_recursive_filter" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="false"
|
|
||||||
app:key="search_on_start"
|
|
||||||
app:summary="@string/pref_search_on_start_hint"
|
|
||||||
app:title="@string/pref_search_on_start" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="false"
|
|
||||||
app:key="show_hidden_contents"
|
|
||||||
app:persistent="true"
|
|
||||||
app:summary="@string/pref_show_hidden_summary"
|
|
||||||
app:title="@string/pref_show_hidden_title" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:key="biometric_auth"
|
|
||||||
app:summary="@string/biometric_auth_summary"
|
|
||||||
app:title="@string/biometric_auth_title" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
<PreferenceCategory app:title="@string/pref_category_title_passwords">
|
|
||||||
<EditTextPreference
|
|
||||||
android:inputType="number"
|
|
||||||
app:defaultValue="45"
|
|
||||||
app:key="general_show_time"
|
|
||||||
app:summary="@string/pref_clipboard_timeout_summary"
|
|
||||||
app:title="@string/pref_clipboard_timeout_title" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="true"
|
|
||||||
app:key="show_password"
|
|
||||||
app:summary="@string/show_password_pref_summary"
|
|
||||||
app:title="@string/show_password_pref_title" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="true"
|
|
||||||
app:key="show_extra_content"
|
|
||||||
app:summary="@string/show_extra_content_pref_summary"
|
|
||||||
app:title="@string/show_extra_content_pref_title" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="false"
|
|
||||||
app:dialogTitle="@string/pref_copy_dialog_title"
|
|
||||||
app:key="copy_on_decrypt"
|
|
||||||
app:summary="@string/pref_copy_dialog_title"
|
|
||||||
app:title="@string/pref_copy_title" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/pref_misc_title">
|
|
||||||
<Preference
|
|
||||||
app:key="export_passwords"
|
|
||||||
app:summary="@string/prefs_export_passwords_summary"
|
|
||||||
app:title="@string/prefs_export_passwords_title" />
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="false"
|
|
||||||
app:key="clear_clipboard_20x"
|
|
||||||
app:summary="@string/pref_clear_clipboard_hint"
|
|
||||||
app:title="@string/pref_clear_clipboard_title" />
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:defaultValue="false"
|
|
||||||
app:key="enable_debug_logging"
|
|
||||||
app:summary="@string/pref_debug_logging_summary"
|
|
||||||
app:title="@string/pref_debug_logging_title" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory>
|
|
||||||
<Preference
|
|
||||||
app:icon="@mipmap/ic_launcher"
|
|
||||||
app:key="app_version"
|
|
||||||
app:title="@string/prefs_version" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
</PreferenceScreen>
|
|
|
@ -53,6 +53,7 @@ object Dependencies {
|
||||||
const val jgit = "org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r"
|
const val jgit = "org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r"
|
||||||
const val kotlin_result = "com.michael-bull.kotlin-result:kotlin-result:1.1.9"
|
const val kotlin_result = "com.michael-bull.kotlin-result:kotlin-result:1.1.9"
|
||||||
const val leakcanary = "com.squareup.leakcanary:leakcanary-android:2.5"
|
const val leakcanary = "com.squareup.leakcanary:leakcanary-android:2.5"
|
||||||
|
const val modern_android_prefs = "de.Maxr1998.android:modernpreferences:1.2.0-alpha1"
|
||||||
const val plumber = "com.squareup.leakcanary:plumber-android:2.5"
|
const val plumber = "com.squareup.leakcanary:plumber-android:2.5"
|
||||||
const val sshj = "com.hierynomus:sshj:0.30.0"
|
const val sshj = "com.hierynomus:sshj:0.30.0"
|
||||||
const val ssh_auth = "org.sufficientlysecure:sshauthentication-api:1.0"
|
const val ssh_auth = "org.sufficientlysecure:sshauthentication-api:1.0"
|
||||||
|
|
Loading…
Reference in a new issue