diff options
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/ui/dialogs')
6 files changed, 397 insertions, 398 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/BasicBottomSheet.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/BasicBottomSheet.kt index e92d87aa..fa188a22 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/BasicBottomSheet.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/BasicBottomSheet.kt @@ -25,138 +25,136 @@ import dev.msfjarvis.aps.util.extensions.resolveAttribute import dev.msfjarvis.aps.util.extensions.viewBinding /** - * [BottomSheetDialogFragment] that exposes a simple [androidx.appcompat.app.AlertDialog] like - * API through [Builder] to create a similar UI, just at the bottom of the screen. + * [BottomSheetDialogFragment] that exposes a simple [androidx.appcompat.app.AlertDialog] like API + * through [Builder] to create a similar UI, just at the bottom of the screen. */ -class BasicBottomSheet private constructor( - val title: String?, - val message: String, - val positiveButtonLabel: String?, - val negativeButtonLabel: String?, - val positiveButtonClickListener: View.OnClickListener?, - val negativeButtonClickListener: View.OnClickListener?, +class BasicBottomSheet +private constructor( + val title: String?, + val message: String, + val positiveButtonLabel: String?, + val negativeButtonLabel: String?, + val positiveButtonClickListener: View.OnClickListener?, + val negativeButtonClickListener: View.OnClickListener?, ) : BottomSheetDialogFragment() { - private val binding by viewBinding(BasicBottomSheetBinding::bind) + private val binding by viewBinding(BasicBottomSheetBinding::bind) - private var behavior: BottomSheetBehavior<FrameLayout>? = null - private val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() { - override fun onSlide(bottomSheet: View, slideOffset: Float) { - } + private var behavior: BottomSheetBehavior<FrameLayout>? = null + private val bottomSheetCallback = + object : BottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, slideOffset: Float) {} - override fun onStateChanged(bottomSheet: View, newState: Int) { - if (newState == BottomSheetBehavior.STATE_COLLAPSED) { - dismiss() - } + override fun onStateChanged(bottomSheet: View, newState: Int) { + if (newState == BottomSheetBehavior.STATE_COLLAPSED) { + dismiss() } + } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - if (savedInstanceState != null) dismiss() - return layoutInflater.inflate(R.layout.basic_bottom_sheet, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - view.viewTreeObserver.removeOnGlobalLayoutListener(this) - val dialog = dialog as BottomSheetDialog? ?: return - behavior = dialog.behavior - behavior?.apply { - state = BottomSheetBehavior.STATE_EXPANDED - peekHeight = 0 - addBottomSheetCallback(bottomSheetCallback) - } - if (!title.isNullOrEmpty()) { - binding.bottomSheetTitle.isVisible = true - binding.bottomSheetTitle.text = title - } - binding.bottomSheetMessage.text = message - if (positiveButtonClickListener != null) { - positiveButtonLabel?.let { buttonLbl -> - binding.bottomSheetOkButton.text = buttonLbl - } - binding.bottomSheetOkButton.isVisible = true - binding.bottomSheetOkButton.setOnClickListener { - positiveButtonClickListener.onClick(it) - dismiss() - } - } - if (negativeButtonClickListener != null) { - binding.bottomSheetCancelButton.isVisible = true - negativeButtonLabel?.let { buttonLbl -> - binding.bottomSheetCancelButton.text = buttonLbl - } - binding.bottomSheetCancelButton.setOnClickListener { - negativeButtonClickListener.onClick(it) - dismiss() - } - } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + if (savedInstanceState != null) dismiss() + return layoutInflater.inflate(R.layout.basic_bottom_sheet, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + view.viewTreeObserver.addOnGlobalLayoutListener( + object : ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + view.viewTreeObserver.removeOnGlobalLayoutListener(this) + val dialog = dialog as BottomSheetDialog? ?: return + behavior = dialog.behavior + behavior?.apply { + state = BottomSheetBehavior.STATE_EXPANDED + peekHeight = 0 + addBottomSheetCallback(bottomSheetCallback) + } + if (!title.isNullOrEmpty()) { + binding.bottomSheetTitle.isVisible = true + binding.bottomSheetTitle.text = title + } + binding.bottomSheetMessage.text = message + if (positiveButtonClickListener != null) { + positiveButtonLabel?.let { buttonLbl -> binding.bottomSheetOkButton.text = buttonLbl } + binding.bottomSheetOkButton.isVisible = true + binding.bottomSheetOkButton.setOnClickListener { + positiveButtonClickListener.onClick(it) + dismiss() + } + } + if (negativeButtonClickListener != null) { + binding.bottomSheetCancelButton.isVisible = true + negativeButtonLabel?.let { buttonLbl -> binding.bottomSheetCancelButton.text = buttonLbl } + binding.bottomSheetCancelButton.setOnClickListener { + negativeButtonClickListener.onClick(it) + dismiss() } - }) - val gradientDrawable = GradientDrawable().apply { - setColor(requireContext().resolveAttribute(android.R.attr.windowBackground)) + } } - view.background = gradientDrawable + } + ) + val gradientDrawable = + GradientDrawable().apply { setColor(requireContext().resolveAttribute(android.R.attr.windowBackground)) } + view.background = gradientDrawable + } + + override fun dismiss() { + super.dismiss() + behavior?.removeBottomSheetCallback(bottomSheetCallback) + } + + class Builder(val context: Context) { + + private var title: String? = null + private var message: String? = null + private var positiveButtonLabel: String? = null + private var negativeButtonLabel: String? = null + private var positiveButtonClickListener: View.OnClickListener? = null + private var negativeButtonClickListener: View.OnClickListener? = null + + fun setTitleRes(@StringRes titleRes: Int): Builder { + this.title = context.resources.getString(titleRes) + return this } - override fun dismiss() { - super.dismiss() - behavior?.removeBottomSheetCallback(bottomSheetCallback) + fun setTitle(title: String): Builder { + this.title = title + return this } - class Builder(val context: Context) { - - private var title: String? = null - private var message: String? = null - private var positiveButtonLabel: String? = null - private var negativeButtonLabel: String? = null - private var positiveButtonClickListener: View.OnClickListener? = null - private var negativeButtonClickListener: View.OnClickListener? = null - - fun setTitleRes(@StringRes titleRes: Int): Builder { - this.title = context.resources.getString(titleRes) - return this - } - - fun setTitle(title: String): Builder { - this.title = title - return this - } - - fun setMessageRes(@StringRes messageRes: Int): Builder { - this.message = context.resources.getString(messageRes) - return this - } + fun setMessageRes(@StringRes messageRes: Int): Builder { + this.message = context.resources.getString(messageRes) + return this + } - fun setMessage(message: String): Builder { - this.message = message - return this - } + fun setMessage(message: String): Builder { + this.message = message + return this + } - fun setPositiveButtonClickListener(buttonLabel: String? = null, listener: View.OnClickListener): Builder { - this.positiveButtonClickListener = listener - this.positiveButtonLabel = buttonLabel - return this - } + fun setPositiveButtonClickListener(buttonLabel: String? = null, listener: View.OnClickListener): Builder { + this.positiveButtonClickListener = listener + this.positiveButtonLabel = buttonLabel + return this + } - fun setNegativeButtonClickListener(buttonLabel: String? = null, listener: View.OnClickListener): Builder { - this.negativeButtonClickListener = listener - this.negativeButtonLabel = buttonLabel - return this - } + fun setNegativeButtonClickListener(buttonLabel: String? = null, listener: View.OnClickListener): Builder { + this.negativeButtonClickListener = listener + this.negativeButtonLabel = buttonLabel + return this + } - fun build(): BasicBottomSheet { - require(message != null) { "Message needs to be set" } - return BasicBottomSheet( - title, - message!!, - positiveButtonLabel, - negativeButtonLabel, - positiveButtonClickListener, - negativeButtonClickListener - ) - } + fun build(): BasicBottomSheet { + require(message != null) { "Message needs to be set" } + return BasicBottomSheet( + title, + message!!, + positiveButtonLabel, + negativeButtonLabel, + positiveButtonClickListener, + negativeButtonClickListener + ) } + } } diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/FolderCreationDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/FolderCreationDialogFragment.kt index 177bfbe3..45dfba2b 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/FolderCreationDialogFragment.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/FolderCreationDialogFragment.kt @@ -30,77 +30,82 @@ import me.msfjarvis.openpgpktx.util.OpenPgpApi class FolderCreationDialogFragment : DialogFragment() { - private lateinit var newFolder: File + private lateinit var newFolder: File - private val keySelectAction = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == AppCompatActivity.RESULT_OK) { - result.data?.getStringArrayExtra(OpenPgpApi.EXTRA_KEY_IDS)?.let { keyIds -> - val gpgIdentifierFile = File(newFolder, ".gpg-id") - gpgIdentifierFile.writeText(keyIds.joinToString("\n")) - val repo = PasswordRepository.getRepository(null) - if (repo != null) { - lifecycleScope.launch { - val repoPath = PasswordRepository.getRepositoryDirectory().absolutePath - requireActivity().commitChange( - getString( - R.string.git_commit_gpg_id, - BasePgpActivity.getLongName(gpgIdentifierFile.parentFile!!.absolutePath, repoPath, gpgIdentifierFile.name) - ), - ) - dismiss() - } - } + private val keySelectAction = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == AppCompatActivity.RESULT_OK) { + result.data?.getStringArrayExtra(OpenPgpApi.EXTRA_KEY_IDS)?.let { keyIds -> + val gpgIdentifierFile = File(newFolder, ".gpg-id") + gpgIdentifierFile.writeText(keyIds.joinToString("\n")) + val repo = PasswordRepository.getRepository(null) + if (repo != null) { + lifecycleScope.launch { + val repoPath = PasswordRepository.getRepositoryDirectory().absolutePath + requireActivity() + .commitChange( + getString( + R.string.git_commit_gpg_id, + BasePgpActivity.getLongName( + gpgIdentifierFile.parentFile!!.absolutePath, + repoPath, + gpgIdentifierFile.name + ) + ), + ) + dismiss() } + } } + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val alertDialogBuilder = MaterialAlertDialogBuilder(requireContext()) - alertDialogBuilder.setTitle(R.string.title_create_folder) - alertDialogBuilder.setView(R.layout.folder_dialog_fragment) - alertDialogBuilder.setPositiveButton(getString(R.string.button_create), null) - alertDialogBuilder.setNegativeButton(getString(android.R.string.cancel)) { _, _ -> - dismiss() - } - val dialog = alertDialogBuilder.create() - dialog.requestInputFocusOnView<TextInputEditText>(R.id.folder_name_text) - dialog.setOnShowListener { - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - createDirectory(requireArguments().getString(CURRENT_DIR_EXTRA)!!) - } - } - return dialog + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val alertDialogBuilder = MaterialAlertDialogBuilder(requireContext()) + alertDialogBuilder.setTitle(R.string.title_create_folder) + alertDialogBuilder.setView(R.layout.folder_dialog_fragment) + alertDialogBuilder.setPositiveButton(getString(R.string.button_create), null) + alertDialogBuilder.setNegativeButton(getString(android.R.string.cancel)) { _, _ -> dismiss() } + val dialog = alertDialogBuilder.create() + dialog.requestInputFocusOnView<TextInputEditText>(R.id.folder_name_text) + dialog.setOnShowListener { + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + createDirectory(requireArguments().getString(CURRENT_DIR_EXTRA)!!) + } } + return dialog + } - private fun createDirectory(currentDir: String) { - val dialog = requireDialog() - val folderNameView = dialog.findViewById<TextInputEditText>(R.id.folder_name_text) - val folderNameViewContainer = dialog.findViewById<TextInputLayout>(R.id.folder_name_container) - newFolder = File("$currentDir/${folderNameView.text}") - folderNameViewContainer.error = when { - newFolder.isFile -> getString(R.string.folder_creation_err_file_exists) - newFolder.isDirectory -> getString(R.string.folder_creation_err_folder_exists) - else -> null - } - if (folderNameViewContainer.error != null) return - newFolder.mkdirs() - (requireActivity() as PasswordStore).refreshPasswordList(newFolder) - if (dialog.findViewById<MaterialCheckBox>(R.id.set_gpg_key).isChecked) { - keySelectAction.launch(Intent(requireContext(), GetKeyIdsActivity::class.java)) - return - } else { - dismiss() - } + private fun createDirectory(currentDir: String) { + val dialog = requireDialog() + val folderNameView = dialog.findViewById<TextInputEditText>(R.id.folder_name_text) + val folderNameViewContainer = dialog.findViewById<TextInputLayout>(R.id.folder_name_container) + newFolder = File("$currentDir/${folderNameView.text}") + folderNameViewContainer.error = + when { + newFolder.isFile -> getString(R.string.folder_creation_err_file_exists) + newFolder.isDirectory -> getString(R.string.folder_creation_err_folder_exists) + else -> null + } + if (folderNameViewContainer.error != null) return + newFolder.mkdirs() + (requireActivity() as PasswordStore).refreshPasswordList(newFolder) + if (dialog.findViewById<MaterialCheckBox>(R.id.set_gpg_key).isChecked) { + keySelectAction.launch(Intent(requireContext(), GetKeyIdsActivity::class.java)) + return + } else { + dismiss() } + } - companion object { + companion object { - private const val CURRENT_DIR_EXTRA = "CURRENT_DIRECTORY" - fun newInstance(startingDirectory: String): FolderCreationDialogFragment { - val extras = bundleOf(CURRENT_DIR_EXTRA to startingDirectory) - val fragment = FolderCreationDialogFragment() - fragment.arguments = extras - return fragment - } + private const val CURRENT_DIR_EXTRA = "CURRENT_DIRECTORY" + fun newInstance(startingDirectory: String): FolderCreationDialogFragment { + val extras = bundleOf(CURRENT_DIR_EXTRA to startingDirectory) + val fragment = FolderCreationDialogFragment() + fragment.arguments = extras + return fragment } + } } diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/ItemCreationBottomSheet.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/ItemCreationBottomSheet.kt index 40a876e1..fcf7b372 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/ItemCreationBottomSheet.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/ItemCreationBottomSheet.kt @@ -25,53 +25,54 @@ import dev.msfjarvis.aps.util.extensions.resolveAttribute class ItemCreationBottomSheet : BottomSheetDialogFragment() { - private var behavior: BottomSheetBehavior<FrameLayout>? = null - private val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() { - override fun onSlide(bottomSheet: View, slideOffset: Float) { - } + private var behavior: BottomSheetBehavior<FrameLayout>? = null + private val bottomSheetCallback = + object : BottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, slideOffset: Float) {} - override fun onStateChanged(bottomSheet: View, newState: Int) { - if (newState == BottomSheetBehavior.STATE_COLLAPSED) { - dismiss() - } + override fun onStateChanged(bottomSheet: View, newState: Int) { + if (newState == BottomSheetBehavior.STATE_COLLAPSED) { + dismiss() } + } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - if (savedInstanceState != null) dismiss() - return inflater.inflate(R.layout.item_create_sheet, container, false) - } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + if (savedInstanceState != null) dismiss() + return inflater.inflate(R.layout.item_create_sheet, container, false) + } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - view.viewTreeObserver.removeOnGlobalLayoutListener(this) - val dialog = dialog as BottomSheetDialog? ?: return - behavior = dialog.behavior - behavior?.apply { - state = BottomSheetBehavior.STATE_EXPANDED - peekHeight = 0 - addBottomSheetCallback(bottomSheetCallback) - } - dialog.findViewById<View>(R.id.create_folder)?.setOnClickListener { - setFragmentResult(ITEM_CREATION_REQUEST_KEY, bundleOf(ACTION_KEY to ACTION_FOLDER)) - dismiss() - } - dialog.findViewById<View>(R.id.create_password)?.setOnClickListener { - setFragmentResult(ITEM_CREATION_REQUEST_KEY, bundleOf(ACTION_KEY to ACTION_PASSWORD)) - dismiss() - } - } - }) - val gradientDrawable = GradientDrawable().apply { - setColor(requireContext().resolveAttribute(android.R.attr.windowBackground)) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + view.viewTreeObserver.addOnGlobalLayoutListener( + object : ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + view.viewTreeObserver.removeOnGlobalLayoutListener(this) + val dialog = dialog as BottomSheetDialog? ?: return + behavior = dialog.behavior + behavior?.apply { + state = BottomSheetBehavior.STATE_EXPANDED + peekHeight = 0 + addBottomSheetCallback(bottomSheetCallback) + } + dialog.findViewById<View>(R.id.create_folder)?.setOnClickListener { + setFragmentResult(ITEM_CREATION_REQUEST_KEY, bundleOf(ACTION_KEY to ACTION_FOLDER)) + dismiss() + } + dialog.findViewById<View>(R.id.create_password)?.setOnClickListener { + setFragmentResult(ITEM_CREATION_REQUEST_KEY, bundleOf(ACTION_KEY to ACTION_PASSWORD)) + dismiss() + } } - view.background = gradientDrawable - } + } + ) + val gradientDrawable = + GradientDrawable().apply { setColor(requireContext().resolveAttribute(android.R.attr.windowBackground)) } + view.background = gradientDrawable + } - override fun dismiss() { - super.dismiss() - behavior?.removeBottomSheetCallback(bottomSheetCallback) - } + override fun dismiss() { + super.dismiss() + behavior?.removeBottomSheetCallback(bottomSheetCallback) + } } diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/OtpImportDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/OtpImportDialogFragment.kt index 44c7a43a..5507218b 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/OtpImportDialogFragment.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/OtpImportDialogFragment.kt @@ -20,32 +20,30 @@ import dev.msfjarvis.aps.util.extensions.requestInputFocusOnView class OtpImportDialogFragment : DialogFragment() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = MaterialAlertDialogBuilder(requireContext()) - val binding = FragmentManualOtpEntryBinding.inflate(layoutInflater) - builder.setView(binding.root) - builder.setPositiveButton(android.R.string.ok) { _, _ -> - setFragmentResult( - PasswordCreationActivity.OTP_RESULT_REQUEST_KEY, - bundleOf( - PasswordCreationActivity.RESULT to getTOTPUri(binding) - ) - ) - } - val dialog = builder.create() - dialog.requestInputFocusOnView<TextInputEditText>(R.id.secret) - return dialog + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val builder = MaterialAlertDialogBuilder(requireContext()) + val binding = FragmentManualOtpEntryBinding.inflate(layoutInflater) + builder.setView(binding.root) + builder.setPositiveButton(android.R.string.ok) { _, _ -> + setFragmentResult( + PasswordCreationActivity.OTP_RESULT_REQUEST_KEY, + bundleOf(PasswordCreationActivity.RESULT to getTOTPUri(binding)) + ) } + val dialog = builder.create() + dialog.requestInputFocusOnView<TextInputEditText>(R.id.secret) + return dialog + } - private fun getTOTPUri(binding: FragmentManualOtpEntryBinding): String { - val secret = binding.secret.text.toString() - val account = binding.account.text.toString() - if (secret.isBlank()) return "" - val builder = Uri.Builder() - builder.scheme("otpauth") - builder.authority("totp") - builder.appendQueryParameter("secret", secret) - if (account.isNotBlank()) builder.appendQueryParameter("issuer", account) - return builder.build().toString() - } + private fun getTOTPUri(binding: FragmentManualOtpEntryBinding): String { + val secret = binding.secret.text.toString() + val account = binding.account.text.toString() + if (secret.isBlank()) return "" + val builder = Uri.Builder() + builder.scheme("otpauth") + builder.authority("totp") + builder.appendQueryParameter("secret", secret) + if (account.isNotBlank()) builder.appendQueryParameter("issuer", account) + return builder.build().toString() + } } diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt index ad9fad1d..16a9eefb 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 @@ -31,72 +31,70 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys class PasswordGeneratorDialogFragment : DialogFragment() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = MaterialAlertDialogBuilder(requireContext()) - val callingActivity = requireActivity() - val binding = FragmentPwgenBinding.inflate(layoutInflater) - val monoTypeface = Typeface.createFromAsset(callingActivity.assets, "fonts/sourcecodepro.ttf") - val prefs = requireActivity().applicationContext - .getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE) + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val builder = MaterialAlertDialogBuilder(requireContext()) + val callingActivity = requireActivity() + val binding = FragmentPwgenBinding.inflate(layoutInflater) + val monoTypeface = Typeface.createFromAsset(callingActivity.assets, "fonts/sourcecodepro.ttf") + val prefs = requireActivity().applicationContext.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE) - builder.setView(binding.root) + builder.setView(binding.root) - binding.numerals.isChecked = !prefs.getBoolean(PasswordOption.NoDigits.key, false) - binding.symbols.isChecked = prefs.getBoolean(PasswordOption.AtLeastOneSymbol.key, false) - binding.uppercase.isChecked = !prefs.getBoolean(PasswordOption.NoUppercaseLetters.key, false) - binding.lowercase.isChecked = !prefs.getBoolean(PasswordOption.NoLowercaseLetters.key, false) - binding.ambiguous.isChecked = !prefs.getBoolean(PasswordOption.NoAmbiguousCharacters.key, false) - binding.pronounceable.isChecked = !prefs.getBoolean(PasswordOption.FullyRandom.key, true) + binding.numerals.isChecked = !prefs.getBoolean(PasswordOption.NoDigits.key, false) + binding.symbols.isChecked = prefs.getBoolean(PasswordOption.AtLeastOneSymbol.key, false) + binding.uppercase.isChecked = !prefs.getBoolean(PasswordOption.NoUppercaseLetters.key, false) + binding.lowercase.isChecked = !prefs.getBoolean(PasswordOption.NoLowercaseLetters.key, false) + binding.ambiguous.isChecked = !prefs.getBoolean(PasswordOption.NoAmbiguousCharacters.key, false) + binding.pronounceable.isChecked = !prefs.getBoolean(PasswordOption.FullyRandom.key, true) - binding.lengthNumber.setText(prefs.getInt(PreferenceKeys.LENGTH, 20).toString()) - binding.passwordText.typeface = monoTypeface - return builder.run { - setTitle(R.string.pwgen_title) - setPositiveButton(R.string.dialog_ok) { _, _ -> - setFragmentResult( - PasswordCreationActivity.PASSWORD_RESULT_REQUEST_KEY, - bundleOf(PasswordCreationActivity.RESULT to "${binding.passwordText.text}") - ) - } - setNeutralButton(R.string.dialog_cancel) { _, _ -> } - setNegativeButton(R.string.pwgen_generate, null) - create() - }.apply { - setOnShowListener { - generate(binding.passwordText) - getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener { - generate(binding.passwordText) - } - } + binding.lengthNumber.setText(prefs.getInt(PreferenceKeys.LENGTH, 20).toString()) + binding.passwordText.typeface = monoTypeface + return builder + .run { + setTitle(R.string.pwgen_title) + setPositiveButton(R.string.dialog_ok) { _, _ -> + setFragmentResult( + PasswordCreationActivity.PASSWORD_RESULT_REQUEST_KEY, + bundleOf(PasswordCreationActivity.RESULT to "${binding.passwordText.text}") + ) } - } - - private fun generate(passwordField: AppCompatTextView) { - setPreferences() - passwordField.text = runCatching { - generate(requireContext().applicationContext) - }.getOrElse { e -> - Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show() - "" + setNeutralButton(R.string.dialog_cancel) { _, _ -> } + setNegativeButton(R.string.pwgen_generate, null) + create() + } + .apply { + setOnShowListener { + generate(binding.passwordText) + getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener { generate(binding.passwordText) } } - } + } + } + + private fun generate(passwordField: AppCompatTextView) { + setPreferences() + passwordField.text = + runCatching { generate(requireContext().applicationContext) }.getOrElse { e -> + Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show() + "" + } + } - private fun isChecked(@IdRes id: Int): Boolean { - return requireDialog().findViewById<CheckBox>(id).isChecked - } + private fun isChecked(@IdRes id: Int): Boolean { + return requireDialog().findViewById<CheckBox>(id).isChecked + } - private fun setPreferences() { - val preferences = listOfNotNull( - PasswordOption.NoDigits.takeIf { !isChecked(R.id.numerals) }, - PasswordOption.AtLeastOneSymbol.takeIf { isChecked(R.id.symbols) }, - PasswordOption.NoUppercaseLetters.takeIf { !isChecked(R.id.uppercase) }, - PasswordOption.NoAmbiguousCharacters.takeIf { !isChecked(R.id.ambiguous) }, - PasswordOption.FullyRandom.takeIf { !isChecked(R.id.pronounceable) }, - PasswordOption.NoLowercaseLetters.takeIf { !isChecked(R.id.lowercase) } - ) - val lengthText = requireDialog().findViewById<EditText>(R.id.lengthNumber).text.toString() - val length = lengthText.toIntOrNull()?.takeIf { it >= 0 } - ?: PasswordGenerator.DEFAULT_LENGTH - setPrefs(requireActivity().applicationContext, preferences, length) - } + private fun setPreferences() { + val preferences = + listOfNotNull( + PasswordOption.NoDigits.takeIf { !isChecked(R.id.numerals) }, + PasswordOption.AtLeastOneSymbol.takeIf { isChecked(R.id.symbols) }, + PasswordOption.NoUppercaseLetters.takeIf { !isChecked(R.id.uppercase) }, + PasswordOption.NoAmbiguousCharacters.takeIf { !isChecked(R.id.ambiguous) }, + PasswordOption.FullyRandom.takeIf { !isChecked(R.id.pronounceable) }, + PasswordOption.NoLowercaseLetters.takeIf { !isChecked(R.id.lowercase) } + ) + val lengthText = requireDialog().findViewById<EditText>(R.id.lengthNumber).text.toString() + val length = lengthText.toIntOrNull()?.takeIf { it >= 0 } ?: PasswordGenerator.DEFAULT_LENGTH + setPrefs(requireActivity().applicationContext, preferences, length) + } } 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 0e7b0a1d..e2e7426b 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 @@ -27,103 +27,102 @@ 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. */ +/** A placeholder fragment containing a simple view. */ class XkPasswordGeneratorDialogFragment : DialogFragment() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = MaterialAlertDialogBuilder(requireContext()) - val callingActivity = requireActivity() - val inflater = callingActivity.layoutInflater - val binding = FragmentXkpwgenBinding.inflate(inflater) - val monoTypeface = Typeface.createFromAsset(callingActivity.assets, "fonts/sourcecodepro.ttf") - val prefs = callingActivity.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE) - - builder.setView(binding.root) - - val previousStoredCapStyle: String = runCatching { - prefs.getString(PREF_KEY_CAPITALS_STYLE)!! - }.getOr(DEFAULT_CAPS_STYLE) - - val lastCapitalsStyleIndex: Int = runCatching { - CapsType.valueOf(previousStoredCapStyle).ordinal - }.getOr(DEFAULT_CAPS_INDEX) - binding.xkCapType.setSelection(lastCapitalsStyleIndex) - binding.xkNumWords.setText(prefs.getString(PREF_KEY_NUM_WORDS, DEFAULT_NUMBER_OF_WORDS)) - - binding.xkSeparator.setText(prefs.getString(PREF_KEY_SEPARATOR, DEFAULT_WORD_SEPARATOR)) - binding.xkNumberSymbolMask.setText(prefs.getString(PREF_KEY_EXTRA_SYMBOLS_MASK, DEFAULT_EXTRA_SYMBOLS_MASK)) - - binding.xkPasswordText.typeface = monoTypeface - - builder.setPositiveButton(resources.getString(R.string.dialog_ok)) { _, _ -> - setPreferences(binding, prefs) - setFragmentResult( - PasswordCreationActivity.PASSWORD_RESULT_REQUEST_KEY, - bundleOf(PasswordCreationActivity.RESULT to "${binding.xkPasswordText.text}") - ) - } - - // flip neutral and negative buttons - builder.setNeutralButton(resources.getString(R.string.dialog_cancel)) { _, _ -> } - builder.setNegativeButton(resources.getString(R.string.pwgen_generate), null) - - val dialog = builder.setTitle(this.resources.getString(R.string.xkpwgen_title)).create() - - dialog.setOnShowListener { - setPreferences(binding, prefs) - makeAndSetPassword(binding) - - dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener { - setPreferences(binding, prefs) - makeAndSetPassword(binding) - } - } - return dialog - } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val builder = MaterialAlertDialogBuilder(requireContext()) + val callingActivity = requireActivity() + val inflater = callingActivity.layoutInflater + val binding = FragmentXkpwgenBinding.inflate(inflater) + val monoTypeface = Typeface.createFromAsset(callingActivity.assets, "fonts/sourcecodepro.ttf") + val prefs = callingActivity.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE) - private fun makeAndSetPassword(binding: FragmentXkpwgenBinding) { - PasswordBuilder(requireContext()) - .setNumberOfWords(Integer.valueOf(binding.xkNumWords.text.toString())) - .setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH) - .setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH) - .setSeparator(binding.xkSeparator.text.toString()) - .appendNumbers(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_DIGIT }) - .appendSymbols(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_SYMBOL }) - .setCapitalization(CapsType.valueOf(binding.xkCapType.selectedItem.toString())).create() - .fold( - success = { binding.xkPasswordText.text = it }, - failure = { e -> - Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show() - tag("xkpw").e(e, "failure generating xkpasswd") - binding.xkPasswordText.text = FALLBACK_ERROR_PASS - }, - ) - } + builder.setView(binding.root) + + val previousStoredCapStyle: String = + runCatching { prefs.getString(PREF_KEY_CAPITALS_STYLE)!! }.getOr(DEFAULT_CAPS_STYLE) + + val lastCapitalsStyleIndex: Int = + runCatching { CapsType.valueOf(previousStoredCapStyle).ordinal }.getOr(DEFAULT_CAPS_INDEX) + binding.xkCapType.setSelection(lastCapitalsStyleIndex) + binding.xkNumWords.setText(prefs.getString(PREF_KEY_NUM_WORDS, DEFAULT_NUMBER_OF_WORDS)) + + binding.xkSeparator.setText(prefs.getString(PREF_KEY_SEPARATOR, DEFAULT_WORD_SEPARATOR)) + binding.xkNumberSymbolMask.setText(prefs.getString(PREF_KEY_EXTRA_SYMBOLS_MASK, DEFAULT_EXTRA_SYMBOLS_MASK)) - private fun setPreferences(binding: FragmentXkpwgenBinding, prefs: SharedPreferences) { - prefs.edit { - putString(PREF_KEY_CAPITALS_STYLE, binding.xkCapType.selectedItem.toString()) - putString(PREF_KEY_NUM_WORDS, binding.xkNumWords.text.toString()) - putString(PREF_KEY_SEPARATOR, binding.xkSeparator.text.toString()) - putString(PREF_KEY_EXTRA_SYMBOLS_MASK, binding.xkNumberSymbolMask.text.toString()) - } + binding.xkPasswordText.typeface = monoTypeface + + builder.setPositiveButton(resources.getString(R.string.dialog_ok)) { _, _ -> + setPreferences(binding, prefs) + setFragmentResult( + PasswordCreationActivity.PASSWORD_RESULT_REQUEST_KEY, + bundleOf(PasswordCreationActivity.RESULT to "${binding.xkPasswordText.text}") + ) } - companion object { - - const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style" - const val PREF_KEY_NUM_WORDS = "pref_key_num_words" - const val PREF_KEY_SEPARATOR = "pref_key_separator" - const val PREF_KEY_EXTRA_SYMBOLS_MASK = "pref_key_xkpwgen_extra_symbols_mask" - val DEFAULT_CAPS_STYLE = CapsType.Sentence.name - val DEFAULT_CAPS_INDEX = CapsType.Sentence.ordinal - const val DEFAULT_NUMBER_OF_WORDS = "3" - const val DEFAULT_WORD_SEPARATOR = "." - const val DEFAULT_EXTRA_SYMBOLS_MASK = "ds" - const val DEFAULT_MIN_WORD_LENGTH = 3 - const val DEFAULT_MAX_WORD_LENGTH = 9 - const val FALLBACK_ERROR_PASS = "42" - const val EXTRA_CHAR_PLACEHOLDER_DIGIT = 'd' - const val EXTRA_CHAR_PLACEHOLDER_SYMBOL = 's' + // flip neutral and negative buttons + builder.setNeutralButton(resources.getString(R.string.dialog_cancel)) { _, _ -> } + builder.setNegativeButton(resources.getString(R.string.pwgen_generate), null) + + val dialog = builder.setTitle(this.resources.getString(R.string.xkpwgen_title)).create() + + dialog.setOnShowListener { + setPreferences(binding, prefs) + makeAndSetPassword(binding) + + dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener { + setPreferences(binding, prefs) + makeAndSetPassword(binding) + } + } + return dialog + } + + private fun makeAndSetPassword(binding: FragmentXkpwgenBinding) { + PasswordBuilder(requireContext()) + .setNumberOfWords(Integer.valueOf(binding.xkNumWords.text.toString())) + .setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH) + .setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH) + .setSeparator(binding.xkSeparator.text.toString()) + .appendNumbers(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_DIGIT }) + .appendSymbols(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_SYMBOL }) + .setCapitalization(CapsType.valueOf(binding.xkCapType.selectedItem.toString())) + .create() + .fold( + success = { binding.xkPasswordText.text = it }, + failure = { e -> + Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show() + tag("xkpw").e(e, "failure generating xkpasswd") + binding.xkPasswordText.text = FALLBACK_ERROR_PASS + }, + ) + } + + private fun setPreferences(binding: FragmentXkpwgenBinding, prefs: SharedPreferences) { + prefs.edit { + putString(PREF_KEY_CAPITALS_STYLE, binding.xkCapType.selectedItem.toString()) + putString(PREF_KEY_NUM_WORDS, binding.xkNumWords.text.toString()) + putString(PREF_KEY_SEPARATOR, binding.xkSeparator.text.toString()) + putString(PREF_KEY_EXTRA_SYMBOLS_MASK, binding.xkNumberSymbolMask.text.toString()) } + } + + companion object { + + const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style" + const val PREF_KEY_NUM_WORDS = "pref_key_num_words" + const val PREF_KEY_SEPARATOR = "pref_key_separator" + const val PREF_KEY_EXTRA_SYMBOLS_MASK = "pref_key_xkpwgen_extra_symbols_mask" + val DEFAULT_CAPS_STYLE = CapsType.Sentence.name + val DEFAULT_CAPS_INDEX = CapsType.Sentence.ordinal + const val DEFAULT_NUMBER_OF_WORDS = "3" + const val DEFAULT_WORD_SEPARATOR = "." + const val DEFAULT_EXTRA_SYMBOLS_MASK = "ds" + const val DEFAULT_MIN_WORD_LENGTH = 3 + const val DEFAULT_MAX_WORD_LENGTH = 9 + const val FALLBACK_ERROR_PASS = "42" + const val EXTRA_CHAR_PLACEHOLDER_DIGIT = 'd' + const val EXTRA_CHAR_PLACEHOLDER_SYMBOL = 's' + } } |
