Skip to content

Commit 1eb741a

Browse files
PM-11356 prevent extra soft-keyboard showing. (#4845)
1 parent e10ca9a commit 1eb741a

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/vaultunlock/VaultUnlockScreen.kt

+16-1
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ import com.x8bit.bitwarden.ui.platform.manager.biometrics.BiometricsManager
6767
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
6868
import kotlinx.collections.immutable.persistentListOf
6969
import kotlinx.collections.immutable.toImmutableList
70+
import kotlinx.coroutines.delay
7071
import javax.crypto.Cipher
7172

73+
private const val AUTO_FOCUS_DELAY = 415L
74+
7275
/**
7376
* The top level composable for the Vault Unlock screen.
7477
*/
@@ -251,6 +254,18 @@ fun VaultUnlockScreen(
251254
) {
252255
Spacer(modifier = Modifier.height(12.dp))
253256
if (!state.hideInput) {
257+
// When switching from an unlocked account to a locked account, the
258+
// current activity is recreated and therefore the composition takes place
259+
// twice. Adding this delay prevents the MP or Pin field
260+
// from auto focusing on the first composition which creates a visual jank where
261+
// the keyboard shows, disappears, and then shows again.
262+
var autoFocusDelayCompleted by rememberSaveable {
263+
mutableStateOf(false)
264+
}
265+
LaunchedEffect(Unit) {
266+
delay(AUTO_FOCUS_DELAY)
267+
autoFocusDelayCompleted = true
268+
}
254269
BitwardenPasswordField(
255270
label = state.vaultUnlockType.unlockScreenInputLabel(),
256271
value = state.input,
@@ -261,7 +276,7 @@ fun VaultUnlockScreen(
261276
showPasswordTestTag = state
262277
.vaultUnlockType
263278
.inputFieldVisibilityToggleTestTag,
264-
autoFocus = state.showKeyboard,
279+
autoFocus = state.showKeyboard && autoFocusDelayCompleted,
265280
imeAction = ImeAction.Done,
266281
keyboardActions = KeyboardActions(
267282
onDone = remember(viewModel) {

app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/vaultunlock/VaultUnlockScreenTest.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.x8bit.bitwarden.data.auth.repository.model.VaultUnlockType
2323
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialAssertionResult
2424
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2GetCredentialsResult
2525
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
26+
import com.x8bit.bitwarden.data.util.advanceTimeByAndRunCurrent
2627
import com.x8bit.bitwarden.ui.autofill.fido2.manager.Fido2CompletionManager
2728
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
2829
import com.x8bit.bitwarden.ui.platform.base.util.asText
@@ -50,6 +51,7 @@ import io.mockk.slot
5051
import io.mockk.verify
5152
import kotlinx.coroutines.flow.MutableStateFlow
5253
import kotlinx.coroutines.flow.update
54+
import kotlinx.coroutines.test.runTest
5355
import org.junit.Before
5456
import org.junit.Test
5557
import javax.crypto.Cipher
@@ -474,8 +476,9 @@ class VaultUnlockScreenTest : BaseComposeTest() {
474476
}
475477

476478
@Test
477-
fun `state with input and without biometrics should request focus on input field`() {
479+
fun `state with input and without biometrics should request focus on input field`() = runTest {
478480
mutableStateFlow.update { it.copy(hideInput = false, isBiometricEnabled = false) }
481+
dispatcher.advanceTimeByAndRunCurrent(500L)
479482
composeTestRule
480483
.onNodeWithText("Master password")
481484
.performScrollTo()

0 commit comments

Comments
 (0)