From 1738364d2fdb3c4069d55516ea623d49dcebfd48 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sun, 8 Aug 2021 13:06:26 +0530 Subject: 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 --- .../ui/dialogs/PasswordGeneratorDialogFragment.kt | 22 +++++++++++++- .../dialogs/XkPasswordGeneratorDialogFragment.kt | 34 +++++++++++++++++----- 2 files changed, 48 insertions(+), 8 deletions(-) (limited to 'app/src/main') 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()) -- cgit v1.2.3