Skip to content

Commit

Permalink
Social signup (#208)
Browse files Browse the repository at this point in the history
* feat: social auth buttons on sign up

* refactor: decrease subscriptions count in signup

* feat: social sign up

* refactor: after merge

* fix: tests

* fix: tests

* fix: addressed PR comments

* fix: added different resources for sign up
  • Loading branch information
k1rill authored Feb 12, 2024
1 parent a4854e3 commit e6876be
Show file tree
Hide file tree
Showing 24 changed files with 1,245 additions and 886 deletions.
6 changes: 4 additions & 2 deletions app/src/main/java/org/openedx/app/MainFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ class MainFragment : Fragment(R.layout.fragment_main) {
}

requireArguments().apply {
this.getString(ARG_COURSE_ID, null)?.apply {
router.navigateToCourseDetail(parentFragmentManager, this)
this.getString(ARG_COURSE_ID, null)?.let {
if (it.isNotBlank()) {
router.navigateToCourseDetail(parentFragmentManager, it)
}
}
this.putString(ARG_COURSE_ID, null)
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/openedx/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.openedx.auth.presentation.AuthRouter
import org.openedx.auth.presentation.sso.FacebookAuthHelper
import org.openedx.auth.presentation.sso.GoogleAuthHelper
import org.openedx.auth.presentation.sso.MicrosoftAuthHelper
import org.openedx.auth.presentation.sso.OAuthHelper
import org.openedx.core.config.Config
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.data.storage.InAppReviewPreferences
Expand Down Expand Up @@ -157,6 +158,7 @@ val appModule = module {
factory { FacebookAuthHelper() }
factory { GoogleAuthHelper(get()) }
factory { MicrosoftAuthHelper() }
factory { OAuthHelper(get(), get(), get()) }

factory<EnrollInCourseInteractor> { CourseInteractor(get()) }
}
4 changes: 1 addition & 3 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,11 @@ val screenModule = module {
get(),
get(),
get(),
get(),
get(),
courseId,
)
}
viewModel { (courseId: String?) ->
SignUpViewModel(get(), get(), get(), get(), get(), courseId)
SignUpViewModel(get(), get(), get(), get(), get(), get(), get(), courseId)
}
viewModel { RestorePasswordViewModel(get(), get(), get(), get()) }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.openedx.auth.domain.model

import org.openedx.auth.data.model.AuthType

data class SocialAuthResponse(
var accessToken: String = "",
var name: String = "",
var email: String = "",
var authType: AuthType = AuthType.PASSWORD,
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.fragment.app.Fragment
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import org.openedx.auth.data.model.AuthType
import org.openedx.auth.presentation.AuthRouter
import org.openedx.auth.presentation.signin.compose.LoginScreen
import org.openedx.core.AppUpdateState
Expand Down Expand Up @@ -51,14 +52,10 @@ class SignInFragment : Fragment() {
onEvent = { event ->
when (event) {
is AuthEvent.SignIn -> viewModel.login(event.login, event.password)
AuthEvent.SignInGoogle -> viewModel.signInGoogle(requireActivity())
AuthEvent.SignInFacebook -> {
viewModel.signInFacebook(this@SignInFragment)
}

AuthEvent.SignInMicrosoft -> {
viewModel.signInMicrosoft(requireActivity())
}
is AuthEvent.SocialSignIn -> viewModel.socialAuth(
this@SignInFragment,
event.authType
)

AuthEvent.ForgotPasswordClick -> {
viewModel.forgotPasswordClickedEvent()
Expand Down Expand Up @@ -114,9 +111,7 @@ class SignInFragment : Fragment() {

internal sealed interface AuthEvent {
data class SignIn(val login: String, val password: String) : AuthEvent
object SignInGoogle : AuthEvent
object SignInFacebook : AuthEvent
object SignInMicrosoft : AuthEvent
data class SocialSignIn(val authType: AuthType) : AuthEvent
object RegisterClick : AuthEvent
object ForgotPasswordClick : AuthEvent
object BackClick : AuthEvent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.openedx.auth.presentation.signin

import android.app.Activity
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
Expand All @@ -14,10 +13,9 @@ import kotlinx.coroutines.withContext
import org.openedx.auth.R
import org.openedx.auth.data.model.AuthType
import org.openedx.auth.domain.interactor.AuthInteractor
import org.openedx.auth.domain.model.SocialAuthResponse
import org.openedx.auth.presentation.AuthAnalytics
import org.openedx.auth.presentation.sso.FacebookAuthHelper
import org.openedx.auth.presentation.sso.GoogleAuthHelper
import org.openedx.auth.presentation.sso.MicrosoftAuthHelper
import org.openedx.auth.presentation.sso.OAuthHelper
import org.openedx.core.BaseViewModel
import org.openedx.core.SingleEventLiveData
import org.openedx.core.UIMessage
Expand All @@ -39,10 +37,8 @@ class SignInViewModel(
private val validator: Validator,
private val appUpgradeNotifier: AppUpgradeNotifier,
private val analytics: AuthAnalytics,
private val facebookAuthHelper: FacebookAuthHelper,
private val googleAuthHelper: GoogleAuthHelper,
private val microsoftAuthHelper: MicrosoftAuthHelper,
val config: Config,
private val oAuthHelper: OAuthHelper,
config: Config,
val courseId: String?,
) : BaseViewModel() {

Expand Down Expand Up @@ -114,44 +110,16 @@ class SignInViewModel(
}
}

fun signInGoogle(activityContext: Activity) {
fun socialAuth(fragment: Fragment, authType: AuthType) {
_uiState.update { it.copy(showProgress = true) }
viewModelScope.launch {
withContext(Dispatchers.IO) {
runCatching {
googleAuthHelper.signIn(activityContext)
oAuthHelper.socialAuth(fragment, authType)
}
}
.getOrNull()
.checkToken(AuthType.GOOGLE)
}
}

fun signInFacebook(fragment: Fragment) {
_uiState.update { it.copy(showProgress = true) }
viewModelScope.launch {
runCatching {
facebookAuthHelper.signIn(fragment)
}.onFailure {
logger.e { "Facebook auth error: $it" }
}
.getOrNull()
.checkToken(AuthType.FACEBOOK)
}
}

fun signInMicrosoft(activityContext: Activity) {
_uiState.update { it.copy(showProgress = true) }
viewModelScope.launch {
withContext(Dispatchers.IO) {
runCatching {
microsoftAuthHelper.signIn(activityContext)
}
}.onFailure {
logger.e { "Microsoft auth error: $it" }
}
.getOrNull()
.checkToken(AuthType.MICROSOFT)
.checkToken()
}
}

Expand All @@ -165,7 +133,7 @@ class SignInViewModel(

override fun onCleared() {
super.onCleared()
facebookAuthHelper.clear()
oAuthHelper.clear()
}

private suspend fun exchangeToken(token: String, authType: AuthType) {
Expand Down Expand Up @@ -199,8 +167,8 @@ class SignInViewModel(
}
}

private suspend fun String?.checkToken(authType: AuthType) {
this?.let { token ->
private suspend fun SocialAuthResponse?.checkToken() {
this?.accessToken?.let { token ->
if (token.isNotEmpty()) {
exchangeToken(token, authType)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ 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.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold
Expand Down Expand Up @@ -58,11 +57,11 @@ 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.SocialAuthView
import org.openedx.core.UIMessage
import org.openedx.core.ui.BackBtn
import org.openedx.core.ui.HandleUIMessage
import org.openedx.core.ui.OpenEdXButton
import org.openedx.core.ui.OpenEdXOutlinedButton
import org.openedx.core.ui.WindowSize
import org.openedx.core.ui.WindowType
import org.openedx.core.ui.displayCutoutForLandscape
Expand Down Expand Up @@ -266,95 +265,14 @@ private fun AuthForm(
)
}
if (state.isSocialAuthEnabled) {
SocialLoginView(state = state, buttonWidth = buttonWidth, onEvent = onEvent)
}
}
}

@Composable
private fun SocialLoginView(
buttonWidth: Modifier,
state: SignInUIState,
onEvent: (AuthEvent) -> Unit,
) {
if (state.isGoogleAuthEnabled) {
OpenEdXOutlinedButton(
modifier = buttonWidth
.testTag("btn_google_auth")
.padding(top = 24.dp),
backgroundColor = MaterialTheme.appColors.background,
borderColor = MaterialTheme.appColors.primary,
textColor = Color.Unspecified,
onClick = {
onEvent(AuthEvent.SignInGoogle)
}
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(id = R.drawable.ic_auth_google),
contentDescription = null,
tint = Color.Unspecified,
)
Text(
modifier = Modifier
.testTag("txt_google_auth")
.padding(start = 10.dp),
text = stringResource(id = R.string.auth_google)
)
}
}
}
if (state.isFacebookAuthEnabled) {
OpenEdXButton(
width = buttonWidth
.testTag("btn_facebook_auth")
.padding(top = 12.dp),
text = stringResource(id = R.string.auth_facebook),
backgroundColor = MaterialTheme.appColors.authFacebookButtonBackground,
onClick = {
onEvent(AuthEvent.SignInFacebook)
}
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(id = R.drawable.ic_auth_facebook),
contentDescription = null,
tint = MaterialTheme.appColors.buttonText,
)
Text(
modifier = Modifier
.testTag("txt_facebook_auth")
.padding(start = 10.dp),
color = MaterialTheme.appColors.buttonText,
text = stringResource(id = R.string.auth_facebook)
)
}
}
}
if (state.isMicrosoftAuthEnabled) {
OpenEdXButton(
width = buttonWidth
.testTag("btn_microsoft_auth")
.padding(top = 12.dp),
text = stringResource(id = R.string.auth_microsoft),
backgroundColor = MaterialTheme.appColors.authMicrosoftButtonBackground,
onClick = {
onEvent(AuthEvent.SignInMicrosoft)
}
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(id = R.drawable.ic_auth_microsoft),
contentDescription = null,
tint = Color.Unspecified,
)
Text(
modifier = Modifier
.testTag("txt_microsoft_auth")
.padding(start = 10.dp),
color = MaterialTheme.appColors.buttonText,
text = stringResource(id = R.string.auth_microsoft)
)
SocialAuthView(
modifier = buttonWidth,
isGoogleAuthEnabled = state.isGoogleAuthEnabled,
isFacebookAuthEnabled = state.isFacebookAuthEnabled,
isMicrosoftAuthEnabled = state.isMicrosoftAuthEnabled,
isSignIn = true,
) {
onEvent(AuthEvent.SocialSignIn(it))
}
}
}
Expand Down
Loading

0 comments on commit e6876be

Please sign in to comment.