Skip to content

Commit e121c22

Browse files
committed
Support login for multiple users
1 parent f3f10d0 commit e121c22

10 files changed

Lines changed: 235 additions & 147 deletions

File tree

‎android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/app/ApplicationConfiguration.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ data class ApplicationConfiguration(
2929
val languages: List<String> = listOf("en"),
3030
val useDarkTheme: Boolean = false,
3131
val syncInterval: Long = 15,
32-
val syncStrategies: List<String> = listOf(),
32+
val syncStrategy: List<String> = listOf(),
3333
val loginConfig: LoginConfig = LoginConfig(),
3434
val deviceToDeviceSync: DeviceToDeviceSyncConfig? = null,
3535
val snackBarTheme: SnackBarThemeConfig = SnackBarThemeConfig(),

‎android/engine/src/main/java/org/smartregister/fhircore/engine/util/SharedPreferencesHelper.kt‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import javax.inject.Singleton
2727
import kotlinx.serialization.SerializationException
2828
import org.smartregister.fhircore.engine.util.extension.decodeJson
2929
import org.smartregister.fhircore.engine.util.extension.encodeJson
30+
import org.smartregister.model.practitioner.PractitionerDetails
3031
import timber.log.Timber
3132

3233
@Singleton
@@ -93,7 +94,14 @@ constructor(@ApplicationContext val context: Context, val gson: Gson) {
9394
/** Write any object by saving it as JSON */
9495
inline fun <reified T> write(key: String, value: T?, encodeWithGson: Boolean = true) {
9596
with(prefs.edit()) {
96-
putString(key, if (encodeWithGson) gson.toJson(value) else value.encodeJson())
97+
putString(
98+
key,
99+
(if (encodeWithGson) gson.toJson(value) else value.encodeJson()).also {
100+
if (value is PractitionerDetails) {
101+
Timber.e(it)
102+
}
103+
},
104+
)
97105
commit()
98106
}
99107
}

‎android/quest/src/main/AndroidManifest.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
android:screenOrientation="portrait"
1414
android:installLocation="internalOnly"
1515
android:supportsRtl="true"
16+
android:networkSecurityConfig="@xml/network_security_config"
1617
android:theme="@style/AppTheme.NoActionBar"
1718
android:windowSoftInputMode="adjustResize"
1819
tools:ignore="UnusedAttribute,LockedOrientationActivity"

‎android/quest/src/main/java/org/smartregister/fhircore/quest/ui/login/LoginErrorState.kt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ enum class LoginErrorState {
2222
INVALID_OFFLINE_STATE,
2323
MULTI_USER_LOGIN_ATTEMPT,
2424
UNKNOWN_HOST,
25+
ERROR_MATCHING_SYNC_STRATEGY
2526
}

‎android/quest/src/main/java/org/smartregister/fhircore/quest/ui/login/LoginScreen.kt‎

Lines changed: 77 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ fun LoginPage(
159159

160160
Surface(
161161
modifier =
162-
modifier
163-
.fillMaxSize()
164-
.scrollable(orientation = Orientation.Vertical, state = rememberScrollState()),
162+
modifier
163+
.fillMaxSize()
164+
.scrollable(orientation = Orientation.Vertical, state = rememberScrollState()),
165165
color = Color.White,
166166
contentColor = contentColorFor(backgroundColor = Color.DarkGray),
167167
) {
@@ -173,7 +173,10 @@ fun LoginPage(
173173
}
174174
Column(
175175
modifier =
176-
modifier.padding(horizontal = 16.dp).fillMaxHeight().verticalScroll(rememberScrollState()),
176+
modifier
177+
.padding(horizontal = 16.dp)
178+
.fillMaxHeight()
179+
.verticalScroll(rememberScrollState()),
177180
verticalArrangement = Arrangement.SpaceBetween,
178181
) {
179182
Spacer(modifier = modifier.height(20.dp))
@@ -184,11 +187,11 @@ fun LoginPage(
184187
painter = painterResource(R.drawable.ic_app_logo),
185188
contentDescription = stringResource(id = R.string.app_logo),
186189
modifier =
187-
modifier
188-
.align(Alignment.CenterHorizontally)
189-
.requiredHeight(120.dp)
190-
.requiredWidth(140.dp)
191-
.testTag(APP_LOGO_TAG),
190+
modifier
191+
.align(Alignment.CenterHorizontally)
192+
.requiredHeight(120.dp)
193+
.requiredWidth(140.dp)
194+
.testTag(APP_LOGO_TAG),
192195
)
193196
}
194197
Text(
@@ -197,11 +200,11 @@ fun LoginPage(
197200
fontWeight = FontWeight.Bold,
198201
fontSize = 32.sp,
199202
modifier =
200-
modifier
201-
.wrapContentWidth()
202-
.padding(vertical = 8.dp)
203-
.align(Alignment.CenterHorizontally)
204-
.testTag(APP_NAME_TEXT_TAG),
203+
modifier
204+
.wrapContentWidth()
205+
.padding(vertical = 8.dp)
206+
.align(Alignment.CenterHorizontally)
207+
.testTag(APP_NAME_TEXT_TAG),
205208
)
206209
Spacer(modifier = modifier.height(40.dp))
207210
Text(text = stringResource(R.string.username), modifier = modifier.padding(vertical = 4.dp))
@@ -214,25 +217,30 @@ fun LoginPage(
214217
Text(color = Color.LightGray, text = stringResource(R.string.username_sample))
215218
},
216219
modifier =
217-
modifier
218-
.fillMaxWidth()
219-
.padding(vertical = 4.dp)
220-
.background(color = Color.Unspecified)
221-
.testTag(USERNAME_FIELD_TAG)
222-
.focusRequester(usernameFocusRequester),
220+
modifier
221+
.fillMaxWidth()
222+
.padding(vertical = 4.dp)
223+
.background(color = Color.Unspecified)
224+
.testTag(USERNAME_FIELD_TAG)
225+
.focusRequester(usernameFocusRequester),
223226
keyboardActions = KeyboardActions(onDone = { passwordFocusRequester.requestFocus() }),
224227
)
225228
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = modifier.fillMaxWidth()) {
226229
Text(
227230
text = stringResource(R.string.password),
228-
modifier = modifier.wrapContentWidth().padding(vertical = 4.dp),
231+
modifier = modifier
232+
.wrapContentWidth()
233+
.padding(vertical = 4.dp),
229234
)
230235
Text(
231236
text = stringResource(R.string.forgot_password),
232237
color = MaterialTheme.colors.primary,
233238
style = TextStyle(textDecoration = TextDecoration.Underline),
234239
modifier =
235-
modifier.wrapContentWidth().padding(vertical = 8.dp).clickable {
240+
modifier
241+
.wrapContentWidth()
242+
.padding(vertical = 8.dp)
243+
.clickable {
236244
showForgotPasswordDialog = !showForgotPasswordDialog
237245
},
238246
)
@@ -248,17 +256,17 @@ fun LoginPage(
248256
keyboardOptions =
249257
KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
250258
modifier =
251-
modifier
252-
.fillMaxWidth()
253-
.onFocusEvent { event ->
254-
if (event.isFocused) {
255-
coroutineScope.launch { bringIntoViewRequester.bringIntoView() }
256-
}
259+
modifier
260+
.fillMaxWidth()
261+
.onFocusEvent { event ->
262+
if (event.isFocused) {
263+
coroutineScope.launch { bringIntoViewRequester.bringIntoView() }
257264
}
258-
.padding(vertical = 4.dp)
259-
.background(color = Color.Unspecified)
260-
.testTag(PASSWORD_FIELD_TAG)
261-
.focusRequester(passwordFocusRequester),
265+
}
266+
.padding(vertical = 4.dp)
267+
.background(color = Color.Unspecified)
268+
.testTag(PASSWORD_FIELD_TAG)
269+
.focusRequester(passwordFocusRequester),
262270
trailingIcon = {
263271
val image = if (showPassword) Icons.Filled.Visibility else Icons.Filled.VisibilityOff
264272
IconButton(onClick = { showPassword = !showPassword }) {
@@ -304,13 +312,15 @@ fun LoginPage(
304312
id = R.string.login_error,
305313
stringResource(R.string.invalid_offline_login_state),
306314
)
315+
LoginErrorState.ERROR_MATCHING_SYNC_STRATEGY ->
316+
stringResource(id = R.string.login_error, stringResource(R.string.error_matching_sync_strategy))
307317
},
308318
modifier =
309-
modifier
310-
.wrapContentWidth()
311-
.padding(vertical = 10.dp)
312-
.align(Alignment.Start)
313-
.testTag(LOGIN_ERROR_TEXT_TAG),
319+
modifier
320+
.wrapContentWidth()
321+
.padding(vertical = 10.dp)
322+
.align(Alignment.Start)
323+
.testTag(LOGIN_ERROR_TEXT_TAG),
314324
)
315325
Spacer(modifier = modifier.height(0.dp))
316326
Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxWidth()) {
@@ -329,10 +339,10 @@ fun LoginPage(
329339
),
330340
onClick = onLoginButtonClicked,
331341
modifier =
332-
modifier
333-
.fillMaxWidth()
334-
.bringIntoViewRequester(bringIntoViewRequester)
335-
.testTag(LOGIN_BUTTON_TAG),
342+
modifier
343+
.fillMaxWidth()
344+
.bringIntoViewRequester(bringIntoViewRequester)
345+
.testTag(LOGIN_BUTTON_TAG),
336346
elevation = null,
337347
) {
338348
Text(
@@ -342,7 +352,9 @@ fun LoginPage(
342352
}
343353
if (showProgressBar) {
344354
CircularProgressIndicator(
345-
modifier = modifier.align(Alignment.Center).size(18.dp),
355+
modifier = modifier
356+
.align(Alignment.Center)
357+
.size(18.dp),
346358
strokeWidth = 1.6.dp,
347359
color = Color.White,
348360
)
@@ -351,25 +363,35 @@ fun LoginPage(
351363
}
352364
Row(
353365
horizontalArrangement = Arrangement.SpaceBetween,
354-
modifier = modifier.fillMaxWidth().padding(vertical = 20.dp),
366+
modifier = modifier
367+
.fillMaxWidth()
368+
.padding(vertical = 20.dp),
355369
verticalAlignment = Alignment.Bottom,
356370
) {
357371
Column {
358372
Text(
359373
text = stringResource(id = R.string.powered_by),
360-
modifier = modifier.wrapContentWidth().padding(vertical = 8.dp).align(Alignment.Start),
374+
modifier = modifier
375+
.wrapContentWidth()
376+
.padding(vertical = 8.dp)
377+
.align(Alignment.Start),
361378
)
362379
Image(
363380
painter = painterResource(id = R.drawable.ic_opensrp_logo),
364381
contentDescription = stringResource(id = R.string.app_logo),
365-
modifier = modifier.align(Alignment.CenterHorizontally).requiredHeight(40.dp),
382+
modifier = modifier
383+
.align(Alignment.CenterHorizontally)
384+
.requiredHeight(40.dp),
366385
)
367386
}
368387

369388
Text(
370389
fontSize = 16.sp,
371390
text = stringResource(id = R.string.app_version, versionCode, versionName),
372-
modifier = modifier.wrapContentWidth().padding(0.dp).testTag(LOGIN_FOOTER),
391+
modifier = modifier
392+
.wrapContentWidth()
393+
.padding(0.dp)
394+
.testTag(LOGIN_FOOTER),
373395
)
374396
}
375397
}
@@ -396,18 +418,24 @@ fun ForgotPasswordDialog(
396418
},
397419
buttons = {
398420
Row(
399-
modifier = modifier.fillMaxWidth().padding(vertical = 20.dp),
421+
modifier = modifier
422+
.fillMaxWidth()
423+
.padding(vertical = 20.dp),
400424
horizontalArrangement = Arrangement.End,
401425
) {
402426
Text(
403427
text = stringResource(R.string.cancel),
404-
modifier = modifier.padding(horizontal = 10.dp).clickable { onDismissDialog() },
428+
modifier = modifier
429+
.padding(horizontal = 10.dp)
430+
.clickable { onDismissDialog() },
405431
)
406432
Text(
407433
color = MaterialTheme.colors.primary,
408434
text = stringResource(R.string.dial_number),
409435
modifier =
410-
modifier.padding(horizontal = 10.dp).clickable {
436+
modifier
437+
.padding(horizontal = 10.dp)
438+
.clickable {
411439
onDismissDialog()
412440
forgotPassword()
413441
},

0 commit comments

Comments
 (0)