diff options
author | Harsh Shandilya <me@msfjarvis.dev> | 2021-08-08 13:06:26 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-08 13:06:26 +0530 |
commit | 1738364d2fdb3c4069d55516ea623d49dcebfd48 (patch) | |
tree | 5dd397147b872ec62db00b935ca536216c50e6ae /app | |
parent | 1b54e679b7b6eaf2955c45d4223426650d197461 (diff) |
Make password generator parameter changes reactive (#1480)
* Make XkPassword generator reactive
* Handle empty strings
* Make password generator reactive
* Sync changelog for 1.13.5 release
* Add to changelog
Diffstat (limited to 'app')
3 files changed, 49 insertions, 8 deletions
diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4ae3136e..0ca522f7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -102,6 +102,7 @@ dependencies { implementation(libs.thirdparty.bouncycastle) implementation(libs.thirdparty.eddsa) implementation(libs.thirdparty.fastscroll) + implementation(libs.thirdparty.flowbinding.android) implementation(libs.thirdparty.jgit) { exclude(group = "org.apache.httpcomponents", module = "httpclient") } diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt index 4820521f..ab51cc4e 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt @@ -17,6 +17,7 @@ import androidx.appcompat.widget.AppCompatTextView import androidx.core.os.bundleOf import androidx.fragment.app.DialogFragment import androidx.fragment.app.setFragmentResult +import androidx.lifecycle.lifecycleScope import com.github.michaelbull.result.getOrElse import com.github.michaelbull.result.runCatching import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -28,7 +29,14 @@ import dev.msfjarvis.aps.util.pwgen.PasswordGenerator.generate import dev.msfjarvis.aps.util.pwgen.PasswordGenerator.setPrefs import dev.msfjarvis.aps.util.pwgen.PasswordOption import dev.msfjarvis.aps.util.settings.PreferenceKeys +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach +import reactivecircus.flowbinding.android.widget.afterTextChanges +import reactivecircus.flowbinding.android.widget.checkedChanges +@OptIn(ExperimentalCoroutinesApi::class) class PasswordGeneratorDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -49,9 +57,21 @@ class PasswordGeneratorDialogFragment : DialogFragment() { binding.lowercase.isChecked = !prefs.getBoolean(PasswordOption.NoLowercaseLetters.key, false) binding.ambiguous.isChecked = !prefs.getBoolean(PasswordOption.NoAmbiguousCharacters.key, false) binding.pronounceable.isChecked = !prefs.getBoolean(PasswordOption.FullyRandom.key, true) - binding.lengthNumber.setText(prefs.getInt(PreferenceKeys.LENGTH, 20).toString()) binding.passwordText.typeface = monoTypeface + + merge( + binding.numerals.checkedChanges().skipInitialValue(), + binding.symbols.checkedChanges().skipInitialValue(), + binding.uppercase.checkedChanges().skipInitialValue(), + binding.lowercase.checkedChanges().skipInitialValue(), + binding.ambiguous.checkedChanges().skipInitialValue(), + binding.pronounceable.checkedChanges().skipInitialValue(), + binding.lengthNumber.afterTextChanges().skipInitialValue(), + ) + .onEach { generate(binding.passwordText) } + .launchIn(lifecycleScope) + return builder .run { setTitle(R.string.pwgen_title) diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt index ad252975..645ab9ba 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt @@ -15,6 +15,7 @@ import androidx.core.content.edit import androidx.core.os.bundleOf import androidx.fragment.app.DialogFragment import androidx.fragment.app.setFragmentResult +import androidx.lifecycle.lifecycleScope import com.github.ajalt.timberkt.Timber.tag import com.github.michaelbull.result.fold import com.github.michaelbull.result.getOr @@ -26,8 +27,14 @@ import dev.msfjarvis.aps.ui.crypto.PasswordCreationActivity import dev.msfjarvis.aps.util.extensions.getString import dev.msfjarvis.aps.util.pwgenxkpwd.CapsType import dev.msfjarvis.aps.util.pwgenxkpwd.PasswordBuilder - -/** A placeholder fragment containing a simple view. */ +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach +import reactivecircus.flowbinding.android.widget.afterTextChanges +import reactivecircus.flowbinding.android.widget.selectionEvents + +@OptIn(ExperimentalCoroutinesApi::class) class XkPasswordGeneratorDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -69,21 +76,34 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() { val dialog = builder.setTitle(this.resources.getString(R.string.xkpwgen_title)).create() + // make parameter changes reactive and automatically update passwords + merge( + binding.xkSeparator.afterTextChanges().skipInitialValue(), + binding.xkCapType.selectionEvents().skipInitialValue(), + binding.xkNumWords.afterTextChanges().skipInitialValue(), + binding.xkNumberSymbolMask.afterTextChanges().skipInitialValue(), + ) + .onEach { updatePassword(binding, prefs) } + .launchIn(lifecycleScope) + dialog.setOnShowListener { - setPreferences(binding, prefs) - makeAndSetPassword(binding) + updatePassword(binding, prefs) dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener { - setPreferences(binding, prefs) - makeAndSetPassword(binding) + updatePassword(binding, prefs) } } return dialog } + private fun updatePassword(binding: FragmentXkpwgenBinding, prefs: SharedPreferences) { + setPreferences(binding, prefs) + makeAndSetPassword(binding) + } + private fun makeAndSetPassword(binding: FragmentXkpwgenBinding) { PasswordBuilder(requireContext()) - .setNumberOfWords(Integer.valueOf(binding.xkNumWords.text.toString())) + .setNumberOfWords(binding.xkNumWords.text.toString().ifBlank { "0" }.toInt()) .setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH) .setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH) .setSeparator(binding.xkSeparator.text.toString()) |