Skip to content

Commit

Permalink
Edured-101: Changing the screens layout so that when the keyboard is …
Browse files Browse the repository at this point in the history
…visible, any input fields and/or buttons are still visible. To make this happen, the top bar will exclude handling the window insets for the navigation bars and ime and pass the content padding like the standard scaffold.

Moreover, the keyboard state can be observed as a state and elements in the screen can be hidden/made visible based on the keyboard state. This is preferable over handling it via focusevents because the focus request/status are asynchronous and can easily result in an unwanted state when there is more than one focusable input field.
Button must require specific height, otherwise height becomes 0 when keyboard is shown.

Screens impacted: DeleteAccountFirstConfirmScreen, ManageAccountScreen, OauthScreen, RequestEduIdEmailSentScreen, RequestEduIdStartScreen, SecurityScreen, WelcomeStartScreen, TwoFactorKeyScreen, TwoFactorKeyDeleteScreen, RequestAuthenticationScreen, DeepLinkScreen, AuthenticationCompletedScreen, PersonalInfoScreen, DataAndActivityScreen,RequestEduIdCreatedScreen, EnableBiometricScreen

Automatically showing keyboard, focus on input field, submit button(s) visible:
DeleteAccountSecondConfirmScreen, EditNameScreen, PhoneRequestCodeScreen, RequestEduIdFormScreen,
ConfirmCodeScreen(Added automatic paste of the sms code. That is why the keyboard is not automatically shown for the confirm sms code screen, it's either or.), ResetPasswordConfirmScreen(includes animating visibility for title & spacing to make room for keyboard & button), RequestEduIdCreatedScreen,
AuthenticationPinBiometricScreen: show keyboard when biometric is skipped or fails. Makes sure buttons are visible above the keyboard. Making sure the PIN input during enrollment is also correct.

 Other fixes:
 Fixed correctly showing error messages for during registration
 Correct the ripple animation by applying the padding to the right elements
 Fix issue with capitalized letter for email field
 Edured-110: only show number's keyboard on the PIN input screens
  • Loading branch information
Iulia Stana committed May 25, 2023
1 parent baa5eeb commit d7e390b
Show file tree
Hide file tree
Showing 39 changed files with 1,326 additions and 902 deletions.
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize">

<activity-alias
android:name="org.tiqr.core.MainActivity"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/kotlin/nl/eduid/MainComposeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.core.view.WindowCompat
import androidx.navigation.compose.rememberNavController
import dagger.hilt.android.AndroidEntryPoint
import nl.eduid.graphs.MainGraph
Expand All @@ -15,6 +16,7 @@ class MainComposeActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
EduidAppAndroidTheme {
MainGraph(navController = rememberNavController())
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/kotlin/nl/eduid/graphs/MainGraph.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import nl.eduid.screens.deleteaccountsecondconfirm.DeleteAccountSecondConfirmVie
import nl.eduid.screens.editemail.EditEmailScreen
import nl.eduid.screens.editemail.EditEmailViewModel
import nl.eduid.screens.editname.EditNameScreen
import nl.eduid.screens.firsttimedialog.LinkAccountViewModel
import nl.eduid.screens.firsttimedialog.FirstTimeDialogScreen
import nl.eduid.screens.firsttimedialog.LinkAccountViewModel
import nl.eduid.screens.homepage.HomePageScreen
import nl.eduid.screens.homepage.HomePageViewModel
import nl.eduid.screens.manageaccount.ManageAccountScreen
Expand All @@ -38,20 +38,20 @@ import nl.eduid.screens.personalinfo.PersonalInfoViewModel
import nl.eduid.screens.pinsetup.NextStep
import nl.eduid.screens.pinsetup.RegistrationPinSetupScreen
import nl.eduid.screens.pinsetup.RegistrationPinSetupViewModel
import nl.eduid.screens.requestiddetails.RequestEduIdFormScreen
import nl.eduid.screens.requestiddetails.RequestEduIdFormViewModel
import nl.eduid.screens.requestidlinksent.RequestEduIdEmailSentScreen
import nl.eduid.screens.recovery.confirmsms.ConfirmCodeScreen
import nl.eduid.screens.recovery.confirmsms.ConfirmCodeViewModel
import nl.eduid.screens.recovery.requestsms.PhoneRequestCodeScreen
import nl.eduid.screens.recovery.requestsms.PhoneRequestCodeViewModel
import nl.eduid.screens.requestiddetails.RequestEduIdFormScreen
import nl.eduid.screens.requestiddetails.RequestEduIdFormViewModel
import nl.eduid.screens.requestidlinksent.RequestEduIdEmailSentScreen
import nl.eduid.screens.requestidstart.RequestEduIdStartScreen
import nl.eduid.screens.scan.ScanScreen
import nl.eduid.screens.scan.StatelessScanViewModel
import nl.eduid.screens.start.WelcomeStartScreen
import nl.eduid.screens.start.WelcomeStartViewModel
import nl.eduid.screens.security.SecurityScreen
import nl.eduid.screens.security.SecurityViewModel
import nl.eduid.screens.start.WelcomeStartScreen
import nl.eduid.screens.start.WelcomeStartViewModel
import nl.eduid.screens.twofactorkey.TwoFactorKeyScreen
import nl.eduid.screens.twofactorkey.TwoFactorKeyViewModel
import nl.eduid.screens.twofactorkeydelete.TwoFactorKeyDeleteScreen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package nl.eduid.screens.accountlinked

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.LinearProgressIndicator
Expand Down Expand Up @@ -33,15 +36,23 @@ import nl.eduid.ui.theme.TextGreen
fun AccountLinkedScreen(
viewModel: PersonalInfoViewModel,
continueToHome: () -> Unit,
) = EduIdTopAppBar(
withBackIcon = false
) {
AccountLinkedContent(
personalInfo = viewModel.uiState.personalInfo,
isLoading = viewModel.uiState.isLoading,
errorData = viewModel.uiState.errorData,
dismissError = viewModel::clearErrorData,
continueToHome = continueToHome,
removeConnection = { index -> viewModel.removeConnection(index) },
)
Column(
modifier = Modifier
.fillMaxSize()
.padding(it)
) {
AccountLinkedContent(
personalInfo = viewModel.uiState.personalInfo,
isLoading = viewModel.uiState.isLoading,
errorData = viewModel.uiState.errorData,
dismissError = viewModel::clearErrorData,
continueToHome = continueToHome,
removeConnection = { index -> viewModel.removeConnection(index) },
)
}
}

@Composable
Expand All @@ -52,88 +63,85 @@ private fun AccountLinkedContent(
dismissError: () -> Unit = {},
continueToHome: () -> Unit = {},
removeConnection: (Int) -> Unit = {},
) = EduIdTopAppBar(
withBackIcon = false
) = Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.navigationBarsPadding()
.padding(start = 24.dp, end = 24.dp, bottom = 24.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
) {
if (errorData != null) {
val context = LocalContext.current
AlertDialogWithSingleButton(
title = errorData.title(context),
explanation = errorData.message(context),
buttonLabel = stringResource(R.string.button_ok),
onDismiss = dismissError
)
}
Spacer(Modifier.height(36.dp))
Text(
style = MaterialTheme.typography.titleLarge.copy(
textAlign = TextAlign.Start, color = TextGreen
),
text = stringResource(R.string.account_linked_title),
modifier = Modifier.fillMaxWidth()
if (errorData != null) {
val context = LocalContext.current
AlertDialogWithSingleButton(
title = errorData.title(context),
explanation = errorData.message(context),
buttonLabel = stringResource(R.string.button_ok),
onDismiss = dismissError
)
Spacer(Modifier.height(12.dp))
Text(
style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.SemiBold),
text = stringResource(R.string.account_linked_subtitle),
}
Spacer(Modifier.height(36.dp))
Text(
style = MaterialTheme.typography.titleLarge.copy(
textAlign = TextAlign.Start, color = TextGreen
),
text = stringResource(R.string.account_linked_title),
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.height(12.dp))
Text(
style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.SemiBold),
text = stringResource(R.string.account_linked_subtitle),
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.height(12.dp))
Text(
style = MaterialTheme.typography.bodyLarge,
text = stringResource(R.string.account_linked_description),
modifier = Modifier.fillMaxWidth()
)
if (isLoading) {
Spacer(modifier = Modifier.height(16.dp))
LinearProgressIndicator(
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
} else {
Spacer(Modifier.height(12.dp))
Text(
style = MaterialTheme.typography.bodyLarge,
text = stringResource(R.string.account_linked_description),
modifier = Modifier.fillMaxWidth()
)
if (isLoading) {
Spacer(modifier = Modifier.height(16.dp))
LinearProgressIndicator(
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
}
InfoField(
title = personalInfo.name,
subtitle = if (personalInfo.nameProvider == null) {
stringResource(R.string.infotab_providedby_you)
} else {
Spacer(Modifier.height(12.dp))
}
InfoField(
title = personalInfo.name,
subtitle = if (personalInfo.nameProvider == null) {
stringResource(R.string.infotab_providedby_you)
} else {
stringResource(R.string.infotab_providedby, personalInfo.nameProvider)
},
endIcon = R.drawable.shield_tick_blue,
label = stringResource(R.string.infotab_fullname)
stringResource(R.string.infotab_providedby, personalInfo.nameProvider)
},
endIcon = R.drawable.shield_tick_blue,
label = stringResource(R.string.infotab_fullname)
)
Spacer(Modifier.height(16.dp))
if (personalInfo.institutionAccounts.isNotEmpty()) {
Text(
text = stringResource(R.string.infotab_role_institution),
style = MaterialTheme.typography.bodyLarge.copy(
textAlign = TextAlign.Start,
fontWeight = FontWeight.SemiBold,
),
)
Spacer(Modifier.height(16.dp))
if (personalInfo.institutionAccounts.isNotEmpty()) {
Text(
text = stringResource(R.string.infotab_role_institution),
style = MaterialTheme.typography.bodyLarge.copy(
textAlign = TextAlign.Start,
fontWeight = FontWeight.SemiBold,
),
)
Spacer(Modifier.height(6.dp))
}
personalInfo.institutionAccounts.forEachIndexed { index, account ->
ConnectionCard(
title = account.role,
subtitle = stringResource(R.string.infotab_at, account.roleProvider),
institutionInfo = account,
onRemoveConnection = { removeConnection(index) },
)
}
PrimaryButton(
text = stringResource(R.string.button_continue),
onClick = continueToHome,
modifier = Modifier.fillMaxWidth(),
Spacer(Modifier.height(6.dp))
}
personalInfo.institutionAccounts.forEachIndexed { index, account ->
ConnectionCard(
title = account.role,
subtitle = stringResource(R.string.infotab_at, account.roleProvider),
institutionInfo = account,
onRemoveConnection = { removeConnection(index) },
)
Spacer(Modifier.height(40.dp))
}
PrimaryButton(
text = stringResource(R.string.button_continue),
onClick = continueToHome,
modifier = Modifier
.fillMaxWidth() ,
)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package nl.eduid.screens.authorize
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
Expand All @@ -25,21 +26,25 @@ import nl.eduid.ui.PrimaryButton
import nl.eduid.ui.theme.EduidAppAndroidTheme
import nl.eduid.ui.theme.TextGreen
import nl.eduid.ui.theme.findActivity
import timber.log.Timber

@Composable
fun AuthenticationCompletedScreen(goHome: () -> Unit = {}) = EduIdTopAppBar(
withBackIcon = false
) {
val activity = LocalContext.current.findActivity()
Column(modifier = Modifier.fillMaxSize()) {
val context = LocalContext.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(it)
.padding(horizontal = 24.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
Text(
style = MaterialTheme.typography.titleLarge.copy(
textAlign = TextAlign.Start, color = TextGreen
), text = stringResource(R.string.authorize_title), modifier = Modifier.fillMaxWidth()
)
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Expand All @@ -60,15 +65,17 @@ fun AuthenticationCompletedScreen(goHome: () -> Unit = {}) = EduIdTopAppBar(
)
}
PrimaryButton(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth()
.weight(1f, false)
.navigationBarsPadding()
.padding(bottom = 24.dp),
text = stringResource(R.string.button_ok),
onClick = {
Timber.e("Finishing activity: ${activity.hashCode()}")
goHome()
activity.finish()
context.findActivity().finish()
},
)
Spacer(Modifier.height(24.dp))
}
}

Expand Down
Loading

0 comments on commit d7e390b

Please sign in to comment.