diff --git a/auth/src/main/java/org/openedx/auth/presentation/signin/compose/SignInView.kt b/auth/src/main/java/org/openedx/auth/presentation/signin/compose/SignInView.kt
index 37309cadf..783a60a99 100644
--- a/auth/src/main/java/org/openedx/auth/presentation/signin/compose/SignInView.kt
+++ b/auth/src/main/java/org/openedx/auth/presentation/signin/compose/SignInView.kt
@@ -49,6 +49,7 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.TextFieldValue
+import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
@@ -58,6 +59,7 @@ import org.openedx.auth.R
import org.openedx.auth.presentation.signin.AuthEvent
import org.openedx.auth.presentation.signin.SignInUIState
import org.openedx.auth.presentation.ui.LoginTextField
+import org.openedx.auth.presentation.ui.PasswordVisibilityIcon
import org.openedx.auth.presentation.ui.SocialAuthView
import org.openedx.core.UIMessage
import org.openedx.core.extension.TextConverter
@@ -305,11 +307,11 @@ private fun PasswordTextField(
onPressDone: () -> Unit,
) {
var passwordTextFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) {
- mutableStateOf(
- TextFieldValue("")
- )
+ mutableStateOf(TextFieldValue(""))
}
+ var isPasswordVisible by remember { mutableStateOf(false) }
val focusManager = LocalFocusManager.current
+
Text(
modifier = Modifier
.testTag("txt_password_label")
@@ -318,7 +320,9 @@ private fun PasswordTextField(
color = MaterialTheme.appColors.textPrimary,
style = MaterialTheme.appTypography.labelLarge
)
+
Spacer(modifier = Modifier.height(8.dp))
+
OutlinedTextField(
modifier = modifier.testTag("tf_password"),
value = passwordTextFieldValue,
@@ -341,11 +345,18 @@ private fun PasswordTextField(
style = MaterialTheme.appTypography.bodyMedium
)
},
+ trailingIcon = {
+ PasswordVisibilityIcon(
+ isPasswordVisible = isPasswordVisible,
+ onClick = { isPasswordVisible = !isPasswordVisible }
+ )
+ },
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Done
),
- visualTransformation = PasswordVisualTransformation(),
+ visualTransformation = if (isPasswordVisible) VisualTransformation.None
+ else PasswordVisualTransformation(),
keyboardActions = KeyboardActions {
focusManager.clearFocus()
onPressDone()
diff --git a/auth/src/main/java/org/openedx/auth/presentation/signup/SignUpViewModel.kt b/auth/src/main/java/org/openedx/auth/presentation/signup/SignUpViewModel.kt
index 8fafe40ff..08bbce466 100644
--- a/auth/src/main/java/org/openedx/auth/presentation/signup/SignUpViewModel.kt
+++ b/auth/src/main/java/org/openedx/auth/presentation/signup/SignUpViewModel.kt
@@ -226,9 +226,14 @@ class SignUpViewModel(
interactor.loginSocial(socialAuth.accessToken, socialAuth.authType)
}.onFailure {
val fields = uiState.value.allFields.toMutableList()
- .filter { field -> field.type != RegistrationFieldType.PASSWORD }
- updateField(ApiConstants.NAME, socialAuth.name)
- updateField(ApiConstants.EMAIL, socialAuth.email)
+ .filter { it.type != RegistrationFieldType.PASSWORD }
+ .map { field ->
+ when (field.name) {
+ ApiConstants.NAME -> field.copy(placeholder = socialAuth.name)
+ ApiConstants.EMAIL -> field.copy(placeholder = socialAuth.email)
+ else -> field
+ }
+ }
setErrorInstructions(emptyMap())
_uiState.update {
it.copy(
diff --git a/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SignUpView.kt b/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SignUpView.kt
index 42fd894df..2872c579b 100644
--- a/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SignUpView.kt
+++ b/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SignUpView.kt
@@ -53,6 +53,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
+import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Devices
@@ -317,10 +318,11 @@ internal fun SignUpView(
Text(
modifier = Modifier
.fillMaxWidth()
- .padding(top = 4.dp),
+ .padding(top = 8.dp),
text = stringResource(
id = R.string.auth_compete_registration
),
+ fontWeight = FontWeight.Bold,
color = MaterialTheme.appColors.textPrimary,
style = MaterialTheme.appTypography.titleSmall
)
diff --git a/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SocialSignedView.kt b/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SocialSignedView.kt
index 25a9434d1..b2dee1919 100644
--- a/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SocialSignedView.kt
+++ b/auth/src/main/java/org/openedx/auth/presentation/signup/compose/SocialSignedView.kt
@@ -3,11 +3,15 @@ package org.openedx.auth.presentation.signup.compose
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Devices
@@ -26,21 +30,36 @@ internal fun SocialSignedView(authType: AuthType) {
Column(
modifier = Modifier
.background(
- color = MaterialTheme.appColors.secondary,
+ color = MaterialTheme.appColors.authSSOSuccessBackground,
shape = MaterialTheme.appShapes.buttonShape
)
.padding(20.dp)
) {
- Text(
- fontSize = 18.sp,
- fontWeight = FontWeight.Bold,
- text = stringResource(
- id = R.string.auth_social_signed_title,
- authType.methodName
+ Row {
+ Icon(
+ modifier = Modifier
+ .padding(end = 8.dp)
+ .size(20.dp),
+ painter = painterResource(id = coreR.drawable.ic_core_check),
+ tint = MaterialTheme.appColors.successBackground,
+ contentDescription = ""
)
- )
+
+ Text(
+ fontSize = 18.sp,
+ fontWeight = FontWeight.Bold,
+ color = MaterialTheme.colors.primary,
+ text = stringResource(
+ id = R.string.auth_social_signed_title,
+ authType.methodName
+ )
+ )
+ }
+
Text(
- modifier = Modifier.padding(top = 8.dp),
+ modifier = Modifier.padding(top = 8.dp, start = 28.dp),
+ fontSize = 14.sp,
+ fontWeight = FontWeight.Normal,
text = stringResource(
id = R.string.auth_social_signed_desc,
stringResource(id = coreR.string.app_name)
diff --git a/auth/src/main/java/org/openedx/auth/presentation/ui/AuthUI.kt b/auth/src/main/java/org/openedx/auth/presentation/ui/AuthUI.kt
index 90fb91ee1..16d75492b 100644
--- a/auth/src/main/java/org/openedx/auth/presentation/ui/AuthUI.kt
+++ b/auth/src/main/java/org/openedx/auth/presentation/ui/AuthUI.kt
@@ -16,6 +16,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
@@ -23,6 +24,8 @@ import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.ExpandMore
+import androidx.compose.material.icons.filled.Visibility
+import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -70,7 +73,10 @@ fun RequiredFields(
) {
fields.forEach { field ->
when (field.type) {
- RegistrationFieldType.TEXT, RegistrationFieldType.EMAIL, RegistrationFieldType.CONFIRM_EMAIL, RegistrationFieldType.PASSWORD -> {
+ RegistrationFieldType.TEXT,
+ RegistrationFieldType.EMAIL,
+ RegistrationFieldType.CONFIRM_EMAIL,
+ RegistrationFieldType.PASSWORD -> {
InputRegistrationField(
modifier = Modifier.fillMaxWidth(),
isErrorShown = showErrorMap[field.name] ?: true,
@@ -289,11 +295,15 @@ fun InputRegistrationField(
var inputRegistrationFieldValue by rememberSaveable {
mutableStateOf(registrationField.placeholder)
}
+ var isPasswordVisible by remember { mutableStateOf(false) }
+
val focusManager = LocalFocusManager.current
- val visualTransformation = if (registrationField.type == RegistrationFieldType.PASSWORD) {
- PasswordVisualTransformation()
- } else {
- VisualTransformation.None
+ val visualTransformation = remember(isPasswordVisible) {
+ if (registrationField.type == RegistrationFieldType.PASSWORD && !isPasswordVisible) {
+ PasswordVisualTransformation()
+ } else {
+ VisualTransformation.None
+ }
}
val keyboardType = when (registrationField.type) {
RegistrationFieldType.CONFIRM_EMAIL, RegistrationFieldType.EMAIL -> KeyboardType.Email
@@ -315,6 +325,18 @@ fun InputRegistrationField(
} else {
registrationField.instructions
}
+ val trailingIcon: @Composable (() -> Unit)? =
+ if (registrationField.type == RegistrationFieldType.PASSWORD) {
+ {
+ PasswordVisibilityIcon(
+ isPasswordVisible = isPasswordVisible,
+ onClick = { isPasswordVisible = !isPasswordVisible }
+ )
+ }
+ } else {
+ null
+ }
+
Column {
Text(
modifier = Modifier
@@ -359,6 +381,7 @@ fun InputRegistrationField(
keyboardActions = KeyboardActions {
focusManager.moveFocus(FocusDirection.Down)
},
+ trailingIcon = trailingIcon,
textStyle = MaterialTheme.appTypography.bodyMedium,
singleLine = isSingleLine,
modifier = modifier.testTag("tf_${registrationField.name.tagId()}")
@@ -418,6 +441,7 @@ fun SelectableRegisterField(
OutlinedTextField(
readOnly = true,
enabled = false,
+ singleLine = true,
value = initialValue,
colors = TextFieldDefaults.outlinedTextFieldColors(
unfocusedBorderColor = MaterialTheme.appColors.textFieldBorder,
@@ -510,6 +534,26 @@ fun ExpandableText(
}
}
+@Composable
+internal fun PasswordVisibilityIcon(
+ isPasswordVisible: Boolean,
+ onClick: () -> Unit
+) {
+ val (image, description) = if (isPasswordVisible) {
+ Icons.Filled.VisibilityOff to stringResource(R.string.auth_accessibility_hide_password)
+ } else {
+ Icons.Filled.Visibility to stringResource(R.string.auth_accessibility_show_password)
+ }
+
+ IconButton(onClick = onClick) {
+ Icon(
+ imageVector = image,
+ contentDescription = description,
+ tint = MaterialTheme.appColors.onSurface
+ )
+ }
+}
+
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
diff --git a/auth/src/main/res/values/strings.xml b/auth/src/main/res/values/strings.xml
index 49b3e0bbd..642185915 100644
--- a/auth/src/main/res/values/strings.xml
+++ b/auth/src/main/res/values/strings.xml
@@ -39,4 +39,6 @@
By creating an account, you agree to the %1$s and %2$s and you acknowledge that %3$s and each Member process your personal data in accordance with the %4$s.
By signing in to this app, you agree to the %1$s and %2$s and you acknowledge that %3$s and each Member process your personal data in accordance with the %4$s.
%2$s]]>
+ Show password
+ Hide password
diff --git a/core/src/main/java/org/openedx/core/ui/theme/AppColors.kt b/core/src/main/java/org/openedx/core/ui/theme/AppColors.kt
index 625c52b27..37783b820 100644
--- a/core/src/main/java/org/openedx/core/ui/theme/AppColors.kt
+++ b/core/src/main/java/org/openedx/core/ui/theme/AppColors.kt
@@ -51,6 +51,7 @@ data class AppColors(
val inactiveButtonText: Color,
val successGreen: Color,
+ val successBackground: Color,
val datesSectionBarPastDue: Color,
val datesSectionBarToday: Color,
@@ -58,6 +59,7 @@ data class AppColors(
val datesSectionBarNextWeek: Color,
val datesSectionBarUpcoming: Color,
+ val authSSOSuccessBackground: Color,
val authGoogleButtonBackground: Color,
val authFacebookButtonBackground: Color,
val authMicrosoftButtonBackground: Color,
diff --git a/core/src/main/java/org/openedx/core/ui/theme/Theme.kt b/core/src/main/java/org/openedx/core/ui/theme/Theme.kt
index 88c973105..8fe1eb8ff 100644
--- a/core/src/main/java/org/openedx/core/ui/theme/Theme.kt
+++ b/core/src/main/java/org/openedx/core/ui/theme/Theme.kt
@@ -69,6 +69,7 @@ private val DarkColorPalette = AppColors(
inactiveButtonText = dark_primary_button_text,
successGreen = dark_success_green,
+ successBackground = dark_success_background,
datesSectionBarPastDue = dark_dates_section_bar_past_due,
datesSectionBarToday = dark_dates_section_bar_today,
@@ -76,6 +77,7 @@ private val DarkColorPalette = AppColors(
datesSectionBarNextWeek = dark_dates_section_bar_next_week,
datesSectionBarUpcoming = dark_dates_section_bar_upcoming,
+ authSSOSuccessBackground = dark_auth_sso_success_background,
authGoogleButtonBackground = dark_auth_google_button_background,
authFacebookButtonBackground = dark_auth_facebook_button_background,
authMicrosoftButtonBackground = dark_auth_microsoft_button_background,
@@ -156,6 +158,7 @@ private val LightColorPalette = AppColors(
inactiveButtonText = light_primary_button_text,
successGreen = light_success_green,
+ successBackground = light_success_background,
datesSectionBarPastDue = light_dates_section_bar_past_due,
datesSectionBarToday = light_dates_section_bar_today,
@@ -163,6 +166,7 @@ private val LightColorPalette = AppColors(
datesSectionBarNextWeek = light_dates_section_bar_next_week,
datesSectionBarUpcoming = light_dates_section_bar_upcoming,
+ authSSOSuccessBackground = light_auth_sso_success_background,
authGoogleButtonBackground = light_auth_google_button_background,
authFacebookButtonBackground = light_auth_facebook_button_background,
authMicrosoftButtonBackground = light_auth_microsoft_button_background,
diff --git a/course/src/main/res/drawable/ic_course_check.xml b/core/src/main/res/drawable/ic_core_check.xml
similarity index 100%
rename from course/src/main/res/drawable/ic_course_check.xml
rename to core/src/main/res/drawable/ic_core_check.xml
diff --git a/core/src/openedx/org/openedx/core/ui/theme/Colors.kt b/core/src/openedx/org/openedx/core/ui/theme/Colors.kt
index 855d557d3..ffc0b64e2 100644
--- a/core/src/openedx/org/openedx/core/ui/theme/Colors.kt
+++ b/core/src/openedx/org/openedx/core/ui/theme/Colors.kt
@@ -52,11 +52,13 @@ val light_info = Color(0xFF42AAFF)
val light_rate_stars = Color(0xFFFFC94D)
val light_inactive_button_background = Color(0xFFCCD4E0)
val light_success_green = Color(0xFF198571)
+val light_success_background = Color(0xFF0D7D4D)
val light_dates_section_bar_past_due = light_warning
val light_dates_section_bar_today = light_info
val light_dates_section_bar_this_week = light_text_primary_variant
val light_dates_section_bar_next_week = light_text_field_border
val light_dates_section_bar_upcoming = Color(0xFFCCD4E0)
+val light_auth_sso_success_background = light_secondary
val light_auth_google_button_background = Color.White
val light_auth_facebook_button_background = Color(0xFF0866FF)
val light_auth_microsoft_button_background = Color(0xFA000000)
@@ -124,11 +126,13 @@ val dark_onInfo = Color.White
val dark_rate_stars = Color(0xFFFFC94D)
val dark_inactive_button_background = Color(0xFFCCD4E0)
val dark_success_green = Color(0xFF198571)
+val dark_success_background = Color.White
val dark_dates_section_bar_past_due = dark_warning
val dark_dates_section_bar_today = dark_info
val dark_dates_section_bar_this_week = dark_text_primary_variant
val dark_dates_section_bar_next_week = dark_text_field_border
val dark_dates_section_bar_upcoming = Color(0xFFCCD4E0)
+val dark_auth_sso_success_background = dark_secondary
val dark_auth_google_button_background = Color(0xFF19212F)
val dark_auth_facebook_button_background = Color(0xFF0866FF)
val dark_auth_microsoft_button_background = Color(0xFA000000)
diff --git a/course/src/main/java/org/openedx/course/presentation/ui/CourseUI.kt b/course/src/main/java/org/openedx/course/presentation/ui/CourseUI.kt
index 27da57afb..3a40728dd 100644
--- a/course/src/main/java/org/openedx/course/presentation/ui/CourseUI.kt
+++ b/course/src/main/java/org/openedx/course/presentation/ui/CourseUI.kt
@@ -910,7 +910,7 @@ fun SubSectionUnitsList(
modifier = Modifier
.size(16.dp)
.alpha(if (unit.isCompleted()) 1f else 0f),
- painter = painterResource(id = R.drawable.ic_course_check),
+ painter = painterResource(id = coreR.drawable.ic_core_check),
contentDescription = "done"
)
Text(