@@ -4,13 +4,17 @@ import android.content.Intent
44import android.os.Bundle
55import android.view.KeyEvent
66import android.view.View
7+ import android.view.animation.Animation
8+ import android.view.animation.AnimationUtils
79import android.view.inputmethod.InputMethodManager
810import android.widget.EditText
11+ import android.widget.ScrollView
912import android.widget.TextView
1013import android.widget.Toast
1114import androidx.appcompat.app.AppCompatActivity
1215import androidx.core.content.ContextCompat
1316import androidx.core.widget.doAfterTextChanged
17+ import com.google.android.material.button.MaterialButton
1418import com.ladsers.passtable.android.R
1519import com.ladsers.passtable.android.components.PasswordGeneratorProcessor
1620import com.ladsers.passtable.android.containers.Param
@@ -23,12 +27,15 @@ import com.ladsers.passtable.lib.PasswordGenerator
2327class PasswordGeneratorActivity : AppCompatActivity () {
2428 private lateinit var binding: ActivityPasswordGeneratorBinding
2529 private lateinit var generator: PasswordGenerator
30+ private lateinit var errorWindowAnim: Animation
2631
2732 override fun onCreate (savedInstanceState : Bundle ? ) {
2833 super .onCreate(savedInstanceState)
2934 binding = ActivityPasswordGeneratorBinding .inflate(layoutInflater)
3035 setContentView(binding.root)
3136
37+ errorWindowAnim = AnimationUtils .loadAnimation(this , R .anim.error_window_anim)
38+
3239 binding.toolbar.root.title = getString(R .string.ui_ct_passwordGenerator)
3340 binding.toolbar.root.navigationIcon =
3441 ContextCompat .getDrawable(this , R .drawable.ic_back_arrow)
@@ -39,6 +46,7 @@ class PasswordGeneratorActivity : AppCompatActivity() {
3946 if (y > oldY || y < oldY) binding.toolbar.root.elevation = 7f
4047 if (y == 0 ) binding.toolbar.root.elevation = 0f
4148 }
49+ binding.svLayout.postDelayed({ binding.svLayout.fullScroll(ScrollView .FOCUS_DOWN ) }, 500 )
4250
4351 generator = PasswordGenerator ()
4452
@@ -47,6 +55,10 @@ class PasswordGeneratorActivity : AppCompatActivity() {
4755 binding.passwordLength.textView,
4856 Param .GENERATOR_PASSWORD_LENGTH
4957 )
58+ // special behavior
59+ binding.passwordLength.editText.doAfterTextChanged { x ->
60+ if (x.toString().startsWith(' 0' )) binding.passwordLength.editText.setText(" " )
61+ }
5062 configureEditParamExclude()
5163
5264 configureCollection(
@@ -74,11 +86,26 @@ class PasswordGeneratorActivity : AppCompatActivity() {
7486 Param .GENERATOR_SYMBOLS_MINIMUM
7587 )
7688
77- binding.btOk.setOnClickListener {
78- val intent = Intent ().putExtra(PasswordGeneratorProcessor .ResultKey , " some test string" )
89+ val isCopyMode = intent.getBooleanExtra(PasswordGeneratorProcessor .CopyModeKey , false )
90+ if (isCopyMode) {
91+ (binding.result.btOk as MaterialButton ).icon =
92+ ContextCompat .getDrawable(this , R .drawable.ic_copy)
93+ }
94+
95+ binding.result.btRefresh.setOnClickListener {
96+ generate()
97+ }
98+
99+ binding.result.btOk.setOnClickListener {
100+ val intent = Intent ().putExtra(
101+ PasswordGeneratorProcessor .ResultKey ,
102+ binding.result.etPassword.text.toString()
103+ )
79104 setResult(RESULT_OK , intent)
80105 finish()
81106 }
107+
108+ generate() // auto generation at startup
82109 }
83110
84111 override fun onResume () {
@@ -219,6 +246,75 @@ class PasswordGeneratorActivity : AppCompatActivity() {
219246 }
220247
221248 private fun generate () {
249+ generator.isLowercaseLettersAllowed = binding.lowercaseLetters.swCollectionAllow.isChecked
250+ generator.isCapitalLettersAllowed = binding.capitalLetters.swCollectionAllow.isChecked
251+ generator.isNumbersAllowed = binding.numbers.swCollectionAllow.isChecked
252+ generator.isSymbolsAllowed = binding.symbols.swCollectionAllow.isChecked
253+ generator.isEasySymbolsMode = binding.symbols.rbBasicSet.isChecked
254+ generator.blockChars(binding.exclude.editText.text.toString())
255+
256+ val length = binding.passwordLength.editText.text.toString().toInt()
257+ val minLowercaseLetters =
258+ if (generator.isLowercaseLettersAllowed) binding.lowercaseLetters.etMinimumNumber.text.toString()
259+ .toInt() else 0
260+ val minSymbolsChars =
261+ if (generator.isSymbolsAllowed) binding.symbols.etMinimumNumber.text.toString()
262+ .toInt() else 0
263+ val minCapitalLetters =
264+ if (generator.isCapitalLettersAllowed) binding.capitalLetters.etMinimumNumber.text.toString()
265+ .toInt() else 0
266+ val minNumbers =
267+ if (generator.isNumbersAllowed) binding.numbers.etMinimumNumber.text.toString()
268+ .toInt() else 0
269+
270+ if (! generator.isLowercaseLettersAllowed && ! generator.isCapitalLettersAllowed
271+ && ! generator.isNumbersAllowed && ! generator.isSymbolsAllowed
272+ ) {
273+ badResult(getString(R .string.ui_ct_noCharSetsGeneration))
274+ return
275+ }
276+
277+ if (! generator.checkGenParams(
278+ length,
279+ minLowercaseLetters,
280+ minSymbolsChars,
281+ minCapitalLetters,
282+ minNumbers
283+ )
284+ ) {
285+ badResult(getString(R .string.ui_ct_sumMinNumberExceedsPassLength))
286+ return
287+ }
288+
289+ try {
290+ binding.result.etPassword.text = generator.generate(
291+ length,
292+ minLowercaseLetters,
293+ minSymbolsChars,
294+ minCapitalLetters,
295+ minNumbers
296+ )
297+ goodResult()
298+ } catch (e: IllegalStateException ) {
299+ badResult(getString(R .string.ui_ct_tooManyCharsExcluded))
300+ }
301+ }
302+
303+ private fun goodResult () {
304+ binding.result.btOk.isEnabled = true
305+ binding.result.btRefresh.isEnabled = true
306+ binding.result.clErr.clearAnimation()
307+ binding.result.clErr.visibility = View .GONE
308+ }
222309
310+ private fun badResult (errMsg : String ) {
311+ binding.result.btOk.isEnabled = false
312+ binding.result.btRefresh.isEnabled = false
313+ binding.result.etPassword.text = " "
314+ binding.result.clErr.visibility = View .VISIBLE
315+ binding.result.clErr.clearAnimation()
316+ binding.result.clErr.startAnimation(errorWindowAnim)
317+ binding.result.tvErrMsg.text = errMsg
318+ binding.svLayout.post { binding.svLayout.fullScroll(ScrollView .FOCUS_DOWN ) }
223319 }
224320}
0 commit comments