@@ -92,7 +92,19 @@ class LoginActivity : AccountAuthenticatorActivity() {
9292 aboutPrivacyPolicy.setOnClickListener { onPrivacyPolicyClicked() }
9393 signUpButton.setOnClickListener { signUp() }
9494 loginButton.setOnClickListener { performLogin() }
95- loginPassword.setOnEditorActionListener(::onEditorAction)
95+ loginPassword.setOnEditorActionListener { textView, actionId, keyEvent ->
96+ if (binding!! .loginButton.isEnabled && isTriggerAction(actionId, keyEvent)) {
97+ if (actionId == EditorInfo .IME_ACTION_NEXT && lastLoginResult != null ) {
98+ askUserForTwoFactorAuthWithKeyboard()
99+ true
100+ } else {
101+ performLogin()
102+ true
103+ }
104+ } else {
105+ false
106+ }
107+ }
96108
97109 loginPassword.onFocusChangeListener =
98110 View .OnFocusChangeListener (::onPasswordFocusChanged)
@@ -113,6 +125,39 @@ class LoginActivity : AccountAuthenticatorActivity() {
113125 }
114126 }
115127
128+ @VisibleForTesting
129+ fun askUserForTwoFactorAuthWithKeyboard () {
130+ if (binding == null ) {
131+ Timber .w(" Binding is null, reinitializing in askUserForTwoFactorAuthWithKeyboard" )
132+ binding = ActivityLoginBinding .inflate(layoutInflater)
133+ setContentView(binding!! .root)
134+ }
135+ progressDialog!! .dismiss()
136+ if (binding != null ) {
137+ with (binding!! ) {
138+ twoFactorContainer.visibility = View .VISIBLE
139+ twoFactorContainer.hint = getString(if (lastLoginResult is LoginResult .EmailAuthResult ) R .string.email_auth_code else R .string._2fa_code )
140+ loginTwoFactor.visibility = View .VISIBLE
141+ loginTwoFactor.requestFocus()
142+
143+ val imm = getSystemService(INPUT_METHOD_SERVICE ) as InputMethodManager
144+ imm.showSoftInput(loginTwoFactor, InputMethodManager .SHOW_IMPLICIT )
145+
146+ loginTwoFactor.setOnEditorActionListener { _, actionId, event ->
147+ if (actionId == EditorInfo .IME_ACTION_DONE ||
148+ (event != null && event.keyCode == KeyEvent .KEYCODE_ENTER && event.action == KeyEvent .ACTION_DOWN )) {
149+ performLogin()
150+ true
151+ } else {
152+ false
153+ }
154+ }
155+ }
156+ } else {
157+ Timber .e(" Binding is null in askUserForTwoFactorAuthWithKeyboard after reinitialization attempt" )
158+ }
159+ showMessageAndCancelDialog(getString(if (lastLoginResult is LoginResult .EmailAuthResult ) R .string.login_failed_email_auth_needed else R .string.login_failed_2fa_needed))
160+ }
116161 override fun onPostCreate (savedInstanceState : Bundle ? ) {
117162 super .onPostCreate(savedInstanceState)
118163 delegate.onPostCreate(savedInstanceState)
@@ -236,7 +281,7 @@ class LoginActivity : AccountAuthenticatorActivity() {
236281 } else false
237282
238283 private fun isTriggerAction (actionId : Int , keyEvent : KeyEvent ? ) =
239- actionId == EditorInfo .IME_ACTION_DONE || keyEvent?.keyCode == KeyEvent .KEYCODE_ENTER
284+ actionId == EditorInfo .IME_ACTION_NEXT || actionId == EditorInfo . IME_ACTION_DONE || keyEvent?.keyCode == KeyEvent .KEYCODE_ENTER
240285
241286 private fun skipLogin () {
242287 AlertDialog .Builder (this )
@@ -286,14 +331,14 @@ class LoginActivity : AccountAuthenticatorActivity() {
286331 Timber .d(" Requesting 2FA prompt" )
287332 progressDialog!! .dismiss()
288333 lastLoginResult = loginResult
289- askUserForTwoFactorAuth ()
334+ askUserForTwoFactorAuthWithKeyboard ()
290335 }
291336
292- override fun emailAuthPrompt (loginResult : LoginResult , caught : Throwable , token : String? ) {
337+ override fun emailAuthPrompt (loginResult : LoginResult , caught : Throwable , token : String? ) = runOnUiThread {
293338 Timber .d(" Requesting email auth prompt" )
294339 progressDialog!! .dismiss()
295340 lastLoginResult = loginResult
296- askUserForTwoFactorAuth ()
341+ askUserForTwoFactorAuthWithKeyboard ()
297342 }
298343
299344 override fun passwordResetPrompt (token : String? ) = runOnUiThread {
@@ -348,12 +393,31 @@ class LoginActivity : AccountAuthenticatorActivity() {
348393
349394 @VisibleForTesting
350395 fun askUserForTwoFactorAuth () {
396+ if (binding == null ) {
397+ Timber .w(" Binding is null, reinitializing in askUserForTwoFactorAuth" )
398+ binding = ActivityLoginBinding .inflate(layoutInflater)
399+ setContentView(binding!! .root)
400+ }
351401 progressDialog!! .dismiss()
352- with (binding!! ) {
353- twoFactorContainer.visibility = View .VISIBLE
354- twoFactorContainer.hint = getString(if (lastLoginResult is LoginResult .EmailAuthResult ) R .string.email_auth_code else R .string._2fa_code )
355- loginTwoFactor.visibility = View .VISIBLE
356- loginTwoFactor.requestFocus()
402+ if (binding != null ) {
403+ with (binding!! ) {
404+ twoFactorContainer.visibility = View .VISIBLE
405+ twoFactorContainer.hint = getString(if (lastLoginResult is LoginResult .EmailAuthResult ) R .string.email_auth_code else R .string._2fa_code )
406+ loginTwoFactor.visibility = View .VISIBLE
407+ loginTwoFactor.requestFocus()
408+
409+ loginTwoFactor.setOnEditorActionListener { _, actionId, event ->
410+ if (actionId == EditorInfo .IME_ACTION_DONE ||
411+ (event != null && event.keyCode == KeyEvent .KEYCODE_ENTER && event.action == KeyEvent .ACTION_DOWN )) {
412+ performLogin()
413+ true
414+ } else {
415+ false
416+ }
417+ }
418+ }
419+ } else {
420+ Timber .e(" Binding is null in askUserForTwoFactorAuth after reinitialization attempt" )
357421 }
358422 val imm = getSystemService(INPUT_METHOD_SERVICE ) as InputMethodManager
359423 imm.toggleSoftInput(InputMethodManager .SHOW_FORCED , InputMethodManager .HIDE_IMPLICIT_ONLY )
0 commit comments