Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@
interactor.loginSocial(token, authType)
}.onFailure { error ->
logger.e { "Social login error: $error" }
onUnknownError()
if (error is EdxError.InvalidGrantException) {
onInvalidGrantError(authType)
} else {
onUnknownError()
}
}.onSuccess {
logger.d { "Social login (${authType.methodName}) success" }
_uiState.update { it.copy(loginSuccess = true) }
Expand All @@ -224,6 +228,32 @@
}
}

private fun onInvalidGrantError(authType: AuthType? = null, message: (() -> String)? = null) {
message?.let {
logger.e { it() }
}
val providerName = authType?.methodName ?: "Social"
val platformName = resourceManager.getString(CoreRes.string.app_name)

_uiMessage.value = UIMessage.SnackBarMessage(
resourceManager.getString(
CoreRes.string.core_error_no_linked_account_error,
providerName,
platformName
)
)
_uiState.update { it.copy(showProgress = false) }
}

private fun onSignInCancelled() {
_uiMessage.value = UIMessage.SnackBarMessage(
resourceManager.getString(
CoreRes.string.core_sign_in_canceled
)
)
_uiState.update { it.copy(showProgress = false) }
}

private fun onUnknownError(message: (() -> String)? = null) {
message?.let {
logger.e { it() }
Expand All @@ -247,7 +277,7 @@
} else {
_uiState.update { it.copy(showProgress = false) }
}
} ?: onUnknownError()
} ?: onSignInCancelled()

Check warning

Code scanning / detekt

Reports multiple space usages Warning

Unnecessary long whitespace
}

fun openLink(fragmentManager: FragmentManager, links: Map<String, String>, link: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Divider
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults
Expand Down Expand Up @@ -56,7 +54,6 @@ 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.text.TextStyle
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
Expand All @@ -65,10 +62,12 @@ 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.OrDivider
import org.openedx.auth.presentation.ui.PasswordVisibilityIcon
import org.openedx.auth.presentation.ui.SocialAuthView
import org.openedx.core.extension.TextConverter
import org.openedx.core.ui.BackBtn
import org.openedx.core.ui.CustomScaffold
import org.openedx.core.ui.HandleUIMessage
import org.openedx.core.ui.HyperlinkText
import org.openedx.core.ui.OpenEdXButton
Expand Down Expand Up @@ -96,7 +95,7 @@ internal fun LoginScreen(
val scaffoldState = rememberScaffoldState()
val scrollState = rememberScrollState()

Scaffold(
CustomScaffold(
scaffoldState = scaffoldState,
modifier = Modifier
.semantics {
Expand Down Expand Up @@ -493,40 +492,3 @@ private fun SignInScreenTabletPreview() {
)
}
}

@Composable
fun OrDivider(
modifier: Modifier = Modifier,
text: String,
lineColor: Color = MaterialTheme.appColors.textPrimary,
textStyle: TextStyle = MaterialTheme.appTypography.labelLarge,
textColor: Color = MaterialTheme.appColors.textPrimary,
lineThickness: Dp = 0.8.dp,
padding: PaddingValues = PaddingValues(top = 24.dp)
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(padding),
verticalAlignment = Alignment.CenterVertically
) {
Divider(
modifier = Modifier
.weight(1f)
.height(lineThickness),
color = lineColor
)
Text(
text = text,
modifier = Modifier.padding(horizontal = 8.dp),
style = textStyle,
color = textColor
)
Divider(
modifier = Modifier
.weight(1f)
.height(lineThickness),
color = lineColor
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.material.ModalBottomSheetValue
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.rememberModalBottomSheetState
Expand Down Expand Up @@ -63,15 +62,16 @@
import kotlinx.coroutines.launch
import org.openedx.auth.R
import org.openedx.auth.data.model.AuthType
import org.openedx.auth.presentation.signin.compose.OrDivider
import org.openedx.auth.presentation.signup.SignUpUIState
import org.openedx.auth.presentation.ui.ExpandableText
import org.openedx.auth.presentation.ui.OptionalFields
import org.openedx.auth.presentation.ui.OrDivider
import org.openedx.auth.presentation.ui.RequiredFields
import org.openedx.auth.presentation.ui.SocialAuthView
import org.openedx.core.domain.model.RegistrationField
import org.openedx.core.domain.model.RegistrationFieldType
import org.openedx.core.ui.BackBtn
import org.openedx.core.ui.CustomScaffold
import org.openedx.core.ui.HandleUIMessage
import org.openedx.core.ui.OpenEdXButton
import org.openedx.core.ui.SheetContent
Expand Down Expand Up @@ -165,7 +165,7 @@
}
}

Scaffold(
CustomScaffold(
scaffoldState = scaffoldState,
modifier = Modifier
.semantics {
Expand Down Expand Up @@ -348,6 +348,22 @@
)
}
}
if (uiState.isSocialAuthEnabled && uiState.socialAuth == null) {
SocialAuthView(
modifier = buttonWidth,
isGoogleAuthEnabled = uiState.isGoogleAuthEnabled,
isFacebookAuthEnabled = uiState.isFacebookAuthEnabled,
isMicrosoftAuthEnabled = uiState.isMicrosoftAuthEnabled,
isSignIn = false,
) {
keyboardController?.hide()
onRegisterClick(it)
}
OrDivider(text=stringResource(

Check warning

Code scanning / detekt

Reports incorrect argument list wrapping Warning

Argument should be on a separate line (unless all arguments can fit a single line)

Check warning

Code scanning / detekt

Reports missing newlines (e.g. between parentheses of a multi-line function call Warning

Missing newline after "("

Check warning

Code scanning / detekt

Reports spaces around operators Warning

Missing spacing around "="
id = R.string.auth_normal_or_sso),

Check warning

Code scanning / detekt

Reports missing newlines (e.g. between parentheses of a multi-line function call Warning

Missing newline before ")"

Check warning

Code scanning / detekt

Reports incorrect argument list wrapping Warning

Missing newline before ")"
padding = PaddingValues(top = 0.dp)
)
}
RequiredFields(
fields = uiState.requiredFields,
showErrorMap = showErrorMap,
Expand Down Expand Up @@ -448,22 +464,6 @@
}
)
}
if (uiState.isSocialAuthEnabled && uiState.socialAuth == null) {
OrDivider(text=stringResource(
id = R.string.auth_normal_or_sso),
padding = PaddingValues(top = 0.dp)
)
SocialAuthView(
modifier = buttonWidth,
isGoogleAuthEnabled = uiState.isGoogleAuthEnabled,
isFacebookAuthEnabled = uiState.isFacebookAuthEnabled,
isMicrosoftAuthEnabled = uiState.isMicrosoftAuthEnabled,
isSignIn = false,
) {
keyboardController?.hide()
onRegisterClick(it)
}
}
Spacer(Modifier.height(70.dp))
}
}
Expand Down
61 changes: 61 additions & 0 deletions auth/src/main/java/org/openedx/auth/presentation/ui/AuthUI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -16,6 +17,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
Expand All @@ -34,22 +36,26 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.focus.focusTarget
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
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.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.openedx.auth.R
import org.openedx.core.domain.model.RegistrationField
Expand Down Expand Up @@ -570,6 +576,43 @@ internal fun PasswordVisibilityIcon(
}
}

@Composable
fun OrDivider(
modifier: Modifier = Modifier,
text: String,
lineColor: Color = MaterialTheme.appColors.textPrimary,
textStyle: TextStyle = MaterialTheme.appTypography.labelLarge,
textColor: Color = MaterialTheme.appColors.textPrimary,
lineThickness: Dp = 0.8.dp,
padding: PaddingValues = PaddingValues(top = 24.dp)
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(padding),
verticalAlignment = Alignment.CenterVertically
) {
Divider(
modifier = Modifier
.weight(1f)
.height(lineThickness),
color = lineColor
)
Text(
text = text,
modifier = Modifier.padding(horizontal = 8.dp),
style = textStyle,
color = textColor
)
Divider(
modifier = Modifier
.weight(1f)
.height(lineThickness),
color = lineColor
)
}
}

@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
Expand Down Expand Up @@ -654,6 +697,24 @@ private fun SheetContentPreview() {
}
}

@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun OrDividerPreview() {
OpenEdXTheme {
Column(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.appColors.background)
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OrDivider(text = "OR")
}
}
}

private val option = RegistrationField.Option("def", "Bachelor", "Android")

private val field = RegistrationField(
Expand Down
26 changes: 26 additions & 0 deletions core/src/main/java/org/openedx/core/ui/ComposeCommon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.ScaffoldState
import androidx.compose.material.Snackbar
import androidx.compose.material.SnackbarHost
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
Expand Down Expand Up @@ -1405,6 +1407,30 @@ private fun RoundTab(
}
}

@Composable
fun CustomScaffold(
scaffoldState: ScaffoldState,
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.appColors.background,
content: @Composable (PaddingValues) -> Unit
) {
androidx.compose.material.Scaffold(
modifier = modifier.fillMaxSize(),
scaffoldState = scaffoldState,
backgroundColor = backgroundColor,
snackbarHost = { hostState ->
SnackbarHost(hostState = hostState) { data ->
Snackbar(
snackbarData = data,
backgroundColor = MaterialTheme.appColors.error,
contentColor = Color.White,
)
}
},
content = content
)
}

@Preview
@Composable
private fun StaticSearchBarPreview() {
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
<string name="core_error_invalid_grant">Invalid credentials</string>
<string name="core_error_no_connection">Slow or no internet connection</string>
<string name="core_error_unknown_error">Something went wrong</string>
<string name="core_error_no_linked_account_error">
This %1$s account is not linked with any %2$s account. Please register.
</string>
<string name="core_sign_in_canceled">The user canceled the sign-in flow.</string>
<string name="core_error_try_again">Try again</string>
<string name="core_privacy_policy">Privacy Policy</string>
<string name="core_cookie_policy" translatable="false">Cookie policy</string>
Expand Down
2 changes: 1 addition & 1 deletion default_config/dev/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ WHATS_NEW_ENABLED: false
#feature flag enable Social Login buttons
SOCIAL_AUTH_ENABLED: false
#Enables the pre login courses discovery experience
PRE_LOGIN_EXPERIENCE_ENABLED: false
PRE_LOGIN_EXPERIENCE_ENABLED: true
#feature flag to enable registration from app
REGISTRATION_ENABLED: true
#feature flag to do the authentication flow in the browser to log in
Expand Down
2 changes: 1 addition & 1 deletion default_config/prod/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ WHATS_NEW_ENABLED: false
#feature flag enable Social Login buttons
SOCIAL_AUTH_ENABLED: false
#Enables the pre login courses discovery experience
PRE_LOGIN_EXPERIENCE_ENABLED: false
PRE_LOGIN_EXPERIENCE_ENABLED: true
#feature flag to enable registration from app
REGISTRATION_ENABLED: true
#feature flag to do the authentication flow in the browser to log in
Expand Down
Loading
Loading