Skip to content

Commit

Permalink
Support login for multiple users
Browse files Browse the repository at this point in the history
  • Loading branch information
LZRS committed Sep 22, 2023
1 parent f3f10d0 commit e121c22
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ data class ApplicationConfiguration(
val languages: List<String> = listOf("en"),
val useDarkTheme: Boolean = false,
val syncInterval: Long = 15,
val syncStrategies: List<String> = listOf(),
val syncStrategy: List<String> = listOf(),
val loginConfig: LoginConfig = LoginConfig(),
val deviceToDeviceSync: DeviceToDeviceSyncConfig? = null,
val snackBarTheme: SnackBarThemeConfig = SnackBarThemeConfig(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import javax.inject.Singleton
import kotlinx.serialization.SerializationException
import org.smartregister.fhircore.engine.util.extension.decodeJson
import org.smartregister.fhircore.engine.util.extension.encodeJson
import org.smartregister.model.practitioner.PractitionerDetails
import timber.log.Timber

@Singleton
Expand Down Expand Up @@ -93,7 +94,14 @@ constructor(@ApplicationContext val context: Context, val gson: Gson) {
/** Write any object by saving it as JSON */
inline fun <reified T> write(key: String, value: T?, encodeWithGson: Boolean = true) {
with(prefs.edit()) {
putString(key, if (encodeWithGson) gson.toJson(value) else value.encodeJson())
putString(
key,
(if (encodeWithGson) gson.toJson(value) else value.encodeJson()).also {
if (value is PractitionerDetails) {
Timber.e(it)
}
},
)
commit()
}
}
Expand Down
1 change: 1 addition & 0 deletions android/quest/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
android:screenOrientation="portrait"
android:installLocation="internalOnly"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize"
tools:ignore="UnusedAttribute,LockedOrientationActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ enum class LoginErrorState {
INVALID_OFFLINE_STATE,
MULTI_USER_LOGIN_ATTEMPT,
UNKNOWN_HOST,
ERROR_MATCHING_SYNC_STRATEGY
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ fun LoginPage(

Surface(
modifier =
modifier
.fillMaxSize()
.scrollable(orientation = Orientation.Vertical, state = rememberScrollState()),
modifier
.fillMaxSize()
.scrollable(orientation = Orientation.Vertical, state = rememberScrollState()),
color = Color.White,
contentColor = contentColorFor(backgroundColor = Color.DarkGray),
) {
Expand All @@ -173,7 +173,10 @@ fun LoginPage(
}
Column(
modifier =
modifier.padding(horizontal = 16.dp).fillMaxHeight().verticalScroll(rememberScrollState()),
modifier
.padding(horizontal = 16.dp)
.fillMaxHeight()
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.SpaceBetween,
) {
Spacer(modifier = modifier.height(20.dp))
Expand All @@ -184,11 +187,11 @@ fun LoginPage(
painter = painterResource(R.drawable.ic_app_logo),
contentDescription = stringResource(id = R.string.app_logo),
modifier =
modifier
.align(Alignment.CenterHorizontally)
.requiredHeight(120.dp)
.requiredWidth(140.dp)
.testTag(APP_LOGO_TAG),
modifier
.align(Alignment.CenterHorizontally)
.requiredHeight(120.dp)
.requiredWidth(140.dp)
.testTag(APP_LOGO_TAG),
)
}
Text(
Expand All @@ -197,11 +200,11 @@ fun LoginPage(
fontWeight = FontWeight.Bold,
fontSize = 32.sp,
modifier =
modifier
.wrapContentWidth()
.padding(vertical = 8.dp)
.align(Alignment.CenterHorizontally)
.testTag(APP_NAME_TEXT_TAG),
modifier
.wrapContentWidth()
.padding(vertical = 8.dp)
.align(Alignment.CenterHorizontally)
.testTag(APP_NAME_TEXT_TAG),
)
Spacer(modifier = modifier.height(40.dp))
Text(text = stringResource(R.string.username), modifier = modifier.padding(vertical = 4.dp))
Expand All @@ -214,25 +217,30 @@ fun LoginPage(
Text(color = Color.LightGray, text = stringResource(R.string.username_sample))
},
modifier =
modifier
.fillMaxWidth()
.padding(vertical = 4.dp)
.background(color = Color.Unspecified)
.testTag(USERNAME_FIELD_TAG)
.focusRequester(usernameFocusRequester),
modifier
.fillMaxWidth()
.padding(vertical = 4.dp)
.background(color = Color.Unspecified)
.testTag(USERNAME_FIELD_TAG)
.focusRequester(usernameFocusRequester),
keyboardActions = KeyboardActions(onDone = { passwordFocusRequester.requestFocus() }),
)
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = modifier.fillMaxWidth()) {
Text(
text = stringResource(R.string.password),
modifier = modifier.wrapContentWidth().padding(vertical = 4.dp),
modifier = modifier
.wrapContentWidth()
.padding(vertical = 4.dp),
)
Text(
text = stringResource(R.string.forgot_password),
color = MaterialTheme.colors.primary,
style = TextStyle(textDecoration = TextDecoration.Underline),
modifier =
modifier.wrapContentWidth().padding(vertical = 8.dp).clickable {
modifier
.wrapContentWidth()
.padding(vertical = 8.dp)
.clickable {
showForgotPasswordDialog = !showForgotPasswordDialog
},
)
Expand All @@ -248,17 +256,17 @@ fun LoginPage(
keyboardOptions =
KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
modifier =
modifier
.fillMaxWidth()
.onFocusEvent { event ->
if (event.isFocused) {
coroutineScope.launch { bringIntoViewRequester.bringIntoView() }
}
modifier
.fillMaxWidth()
.onFocusEvent { event ->
if (event.isFocused) {
coroutineScope.launch { bringIntoViewRequester.bringIntoView() }
}
.padding(vertical = 4.dp)
.background(color = Color.Unspecified)
.testTag(PASSWORD_FIELD_TAG)
.focusRequester(passwordFocusRequester),
}
.padding(vertical = 4.dp)
.background(color = Color.Unspecified)
.testTag(PASSWORD_FIELD_TAG)
.focusRequester(passwordFocusRequester),
trailingIcon = {
val image = if (showPassword) Icons.Filled.Visibility else Icons.Filled.VisibilityOff
IconButton(onClick = { showPassword = !showPassword }) {
Expand Down Expand Up @@ -304,13 +312,15 @@ fun LoginPage(
id = R.string.login_error,
stringResource(R.string.invalid_offline_login_state),
)
LoginErrorState.ERROR_MATCHING_SYNC_STRATEGY ->
stringResource(id = R.string.login_error, stringResource(R.string.error_matching_sync_strategy))
},
modifier =
modifier
.wrapContentWidth()
.padding(vertical = 10.dp)
.align(Alignment.Start)
.testTag(LOGIN_ERROR_TEXT_TAG),
modifier
.wrapContentWidth()
.padding(vertical = 10.dp)
.align(Alignment.Start)
.testTag(LOGIN_ERROR_TEXT_TAG),
)
Spacer(modifier = modifier.height(0.dp))
Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxWidth()) {
Expand All @@ -329,10 +339,10 @@ fun LoginPage(
),
onClick = onLoginButtonClicked,
modifier =
modifier
.fillMaxWidth()
.bringIntoViewRequester(bringIntoViewRequester)
.testTag(LOGIN_BUTTON_TAG),
modifier
.fillMaxWidth()
.bringIntoViewRequester(bringIntoViewRequester)
.testTag(LOGIN_BUTTON_TAG),
elevation = null,
) {
Text(
Expand All @@ -342,7 +352,9 @@ fun LoginPage(
}
if (showProgressBar) {
CircularProgressIndicator(
modifier = modifier.align(Alignment.Center).size(18.dp),
modifier = modifier
.align(Alignment.Center)
.size(18.dp),
strokeWidth = 1.6.dp,
color = Color.White,
)
Expand All @@ -351,25 +363,35 @@ fun LoginPage(
}
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = modifier.fillMaxWidth().padding(vertical = 20.dp),
modifier = modifier
.fillMaxWidth()
.padding(vertical = 20.dp),
verticalAlignment = Alignment.Bottom,
) {
Column {
Text(
text = stringResource(id = R.string.powered_by),
modifier = modifier.wrapContentWidth().padding(vertical = 8.dp).align(Alignment.Start),
modifier = modifier
.wrapContentWidth()
.padding(vertical = 8.dp)
.align(Alignment.Start),
)
Image(
painter = painterResource(id = R.drawable.ic_opensrp_logo),
contentDescription = stringResource(id = R.string.app_logo),
modifier = modifier.align(Alignment.CenterHorizontally).requiredHeight(40.dp),
modifier = modifier
.align(Alignment.CenterHorizontally)
.requiredHeight(40.dp),
)
}

Text(
fontSize = 16.sp,
text = stringResource(id = R.string.app_version, versionCode, versionName),
modifier = modifier.wrapContentWidth().padding(0.dp).testTag(LOGIN_FOOTER),
modifier = modifier
.wrapContentWidth()
.padding(0.dp)
.testTag(LOGIN_FOOTER),
)
}
}
Expand All @@ -396,18 +418,24 @@ fun ForgotPasswordDialog(
},
buttons = {
Row(
modifier = modifier.fillMaxWidth().padding(vertical = 20.dp),
modifier = modifier
.fillMaxWidth()
.padding(vertical = 20.dp),
horizontalArrangement = Arrangement.End,
) {
Text(
text = stringResource(R.string.cancel),
modifier = modifier.padding(horizontal = 10.dp).clickable { onDismissDialog() },
modifier = modifier
.padding(horizontal = 10.dp)
.clickable { onDismissDialog() },
)
Text(
color = MaterialTheme.colors.primary,
text = stringResource(R.string.dial_number),
modifier =
modifier.padding(horizontal = 10.dp).clickable {
modifier
.padding(horizontal = 10.dp)
.clickable {
onDismissDialog()
forgotPassword()
},
Expand Down
Loading

0 comments on commit e121c22

Please sign in to comment.