Skip to content

Instantly share code, notes, and snippets.

@sajjadyousefnia
Created March 10, 2025 01:04
Show Gist options
  • Save sajjadyousefnia/d7bb08741211f559b80f219aa369fab8 to your computer and use it in GitHub Desktop.
Save sajjadyousefnia/d7bb08741211f559b80f219aa369fab8 to your computer and use it in GitHub Desktop.
package com.divadventure.divadventure.ui
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.divadventure.divadventure.Intent.AuthIntent
import com.divadventure.divadventure.R
import com.divadventure.divadventure.Screen
import com.divadventure.divadventure.ViewModel.AuthViewModel
import com.divadventure.divadventure.ViewModel.NavigationViewModel
import timber.log.Timber
@Composable
fun SignUpScreen(
padding: PaddingValues,
navigationViewModel: NavigationViewModel,
viewModel: AuthViewModel
) {
var showError by remember { mutableStateOf(false) }
val state by viewModel.state.collectAsState()
Timber.d("state: $state")
val email = remember {
mutableStateOf("")
}
val password = remember {
mutableStateOf("")
}
val passwordConfirmation = remember {
mutableStateOf("")
}
var enterButtonColor by remember {
mutableStateOf(
Color(0xffBFBFBF)
)
}
LaunchedEffect(state.error) {
if (state.error != null) {
Timber.e("Error: ${state.error}")
showError = true
} else {
Timber.e("Error: ${state.error}")
showError = false
}
}
if (state.isLogged) {
Timber.d("Navigating to HomeScreen")
navigationViewModel.navigateTo(
Screen.HomeScreen
)
}
when (state.rawDataAccepted) {
(true) -> {
if (enterButtonColor != Color(0xff30D158)) {
enterButtonColor = Color(0xff30D158)
}
}
(false) -> {
if (enterButtonColor != Color(0xffBFBFBF)) {
enterButtonColor = Color(0xffBFBFBF)
}
}
}
Box(
modifier = Modifier.background(Color.White)
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(50.dp, 0.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier
.padding(0.dp, 70.dp)
.weight(0.4f, false)
.fillMaxWidth(),
text = "DivAdventure",
style = TextStyle(
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
fontSize = 32.sp,
color = Color(0xff30D158),
)
)
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(0.dp, 20.dp),
value = email.value,
onValueChange = {
email.value = it
viewModel.sendIntent(
AuthIntent.OnEmailChanged(
email = email.value
)
)
},
textStyle = TextStyle(
color = Color.Black, fontSize = 17.sp
),
placeholder = {
Text(
text = "Your Email", style = TextStyle(
fontSize = 17.sp, color = Color(0xff3C3C4399)
)
)
},
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Black,
unfocusedIndicatorColor = Color(0xff3C3C4399),
focusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent
),
label = {
Row {
Text("Email", color = Color.Black)
Text("*", style = TextStyle(color = Color.Red))
}
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
),
)
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(0.dp, 0.dp),
value = password.value,
onValueChange = {
password.value = it
viewModel.sendIntent(
AuthIntent.OnPasswordChanged(
password = password.value
)
)
},
textStyle = TextStyle(
color = Color.Black, fontSize = 17.sp
),
placeholder = {
Text(
text = "Your Password", style = TextStyle(
fontSize = 17.sp, color = Color(0xff3C3C4399)
)
)
},
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Black,
unfocusedIndicatorColor = Color(0xff3C3C4399),
focusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent
),
label = {
Row {
Text("Password", color = Color.Black)
Text("*", style = TextStyle(color = Color.Red))
}
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password
),
visualTransformation = PasswordVisualTransformation(),
)
TextField(
modifier = Modifier
.height(50.dp)
.height(IntrinsicSize.Min)
.padding(0.dp, 0.dp),
value = passwordConfirmation.value,
onValueChange = {
passwordConfirmation.value = it
viewModel.sendIntent(
AuthIntent.OnPasswordConfirmationChanged(
passwordConfirmation = passwordConfirmation.value
)
)
},
textStyle = TextStyle(
color = Color.Black, fontSize = 17.sp
),
placeholder = {
Text(
modifier = Modifier.height(IntrinsicSize.Min),
text = "Confirm Password",
style = TextStyle(
fontSize = 17.sp, color = Color(0xff3C3C4399)
)
)
},
visualTransformation = PasswordVisualTransformation(),
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Black,
unfocusedIndicatorColor = Color(0xff3C3C4399),
focusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password
),
)
Card(
modifier = Modifier
.clickable {
viewModel.sendIntent(
AuthIntent.SignUp(
email.value,
password.value,
passwordConfirmation.value
)
)
}
.fillMaxWidth()
.padding(0.dp, 20.dp)
.height(50.dp),
colors = CardDefaults.cardColors(
containerColor = enterButtonColor,
disabledContainerColor = enterButtonColor,
contentColor = Color.White,
disabledContentColor = Color.White
),
shape = RoundedCornerShape(4.dp),
) {
Box(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.align(Alignment.Center), style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
), text = "Create Account"
)
}
}
Card(
modifier = Modifier
.clickable {
viewModel.sendIntent(AuthIntent.SignUpWithGoogle)
}
.fillMaxWidth()
.padding(0.dp, 0.dp)
.height(50.dp),
border = BorderStroke(1.dp, Color(0xffBFBFBF)),
colors = CardDefaults.cardColors(
containerColor = Color.White,
disabledContainerColor = Color.White,
contentColor = Color.White,
disabledContentColor = Color.White
),
shape = RoundedCornerShape(4.dp),
) {
Box(modifier = Modifier.fillMaxSize()) {
Row(
modifier = Modifier.align(Alignment.Center),
verticalAlignment = Alignment.CenterVertically
) {
Image(
modifier = Modifier.padding(0.dp, 0.dp, 10.dp, 0.dp),
imageVector = ImageVector.vectorResource(R.drawable.ic_google),
contentDescription = "google",
)
Text(
modifier = Modifier.padding(
10.dp, 0.dp, 0.dp, 0.dp
), style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
color = Color(0x36000000)
), text = "Sign Up with Google"
)
}
}
}
Card(
modifier = Modifier
.clickable {
}
.fillMaxWidth()
.padding(0.dp, 20.dp)
.height(50.dp),
colors = CardDefaults.cardColors(
containerColor = Color(0xff2553B4),
disabledContainerColor = Color(0xff2553B4),
contentColor = Color.White,
disabledContentColor = Color.White
),
shape = RoundedCornerShape(4.dp),
) {
Box(modifier = Modifier.fillMaxSize()) {
Row(
modifier = Modifier.align(Alignment.Center),
verticalAlignment = Alignment.CenterVertically
) {
Image(
modifier = Modifier.padding(0.dp, 0.dp, 10.dp, 0.dp),
imageVector = ImageVector.vectorResource(R.drawable.ic_facebook),
contentDescription = "facebook",
)
Text(
modifier = Modifier.padding(
10.dp, 0.dp, 0.dp, 0.dp
), style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
color = Color.White
), text = "Sign Up with Facebook"
)
}
}
}
}
}
}
// another file
package com.divadventure.divadventure.domain
import com.divadventure.divadventure.ResultWrapper
import com.divadventure.divadventure.data.AuthRepository
import com.divadventure.divadventure.data.Model.SignupRequest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class AuthUseCases @Inject constructor(
// val signInUseCase: SignInUseCase,
val signUpUseCase: SignUpUseCase,
// val forgotPasswordUseCase: ForgotPasswordUseCase,
// val isLoggedInUseCase: IsLoggedInUseCase,
// val verifyEmailUseCase: VerifyEmailUseCase,
// val getCurrentUserUseCase: GetCurrentUserUseCase,
// val logoutUseCase: LogoutUseCase
)
/*
class SignInUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(email: String, password: String): ResultWrapper<User> {
// Validate email and password if needed
if (!isValidEmail(email)) {
return Result.Error(Exception("Invalid email format"))
}
if (password.length < 6) {
return Result.Error(Exception("Password must be at least 6 characters long"))
}
return try {
authRepository.signIn(email, password)
} catch (e: Exception) {
Result.Error(e)
}
}
private fun isValidEmail(email: String): Boolean {
// You can add a better email validation logic if needed
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
*/
class SignUpUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(signupRequest: SignupRequest): Flow<ResultWrapper<SignupRequest>> =
flow {
// Validate email and password if needed
emit(ResultWrapper.Loading)
if (!isValidEmail(signupRequest.email)) {
Timber.d("Invalid email format")
ResultWrapper.Error("Invalid email format")
return@flow
}
if (signupRequest.password.length < 8) {
Timber.d("Password must be at least 6 characters long")
emit(ResultWrapper.Error("Password must be at least 6 characters long"))
return@flow
}
if (signupRequest.password != signupRequest.password_confirmation) {
Timber.d("Passwords do not match")
emit(ResultWrapper.Error(("Passwords do not match")))
return@flow
}
try {
CoroutineScope(
Dispatchers.IO
).launch {
authRepository.signup(signupRequest)
}
// Emit Success state
// emit(ResultWrapper.Success(signupRequest))
} catch (e: Exception) {
ResultWrapper.Error("failed to sign up")
}
}
private fun isValidEmail(email: String): Boolean {
// You can add a better email validation logic if needed
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
/*
class ForgotPasswordUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(email: String): Result<Unit> {
// Validate email if needed
if (!isValidEmail(email)) {
return Result.Error(Exception("Invalid email format"))
}
return try {
authRepository.forgotPassword(email)
Result.Success(Unit)
} catch (e: Exception) {
Result.Error(e)
}
}
private fun isValidEmail(email: String): Boolean {
// You can add a better email validation logic if needed
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
*/
/*
class IsLoggedInUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(): Boolean {
// Check if the user is logged in
return authRepository.isLoggedIn()
}
}*/
/*class VerifyEmailUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(): Result<Unit> {
// Verify the user email
return try {
authRepository.verifyEmail()
Result.Success(Unit)
} catch (e: Exception) {
Result.Error(e)
}
}
}*/
/*
class GetCurrentUserUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(): Result<User?> {
// Get the user
return try {
val user = authRepository.getCurrentUser()
Result.Success(user)
} catch (e:*/
// another file
package com.divadventure.divadventure.domain
import com.divadventure.divadventure.ResultWrapper
import com.divadventure.divadventure.data.AuthRepository
import com.divadventure.divadventure.data.Model.SignupRequest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class AuthUseCases @Inject constructor(
// val signInUseCase: SignInUseCase,
val signUpUseCase: SignUpUseCase,
// val forgotPasswordUseCase: ForgotPasswordUseCase,
// val isLoggedInUseCase: IsLoggedInUseCase,
// val verifyEmailUseCase: VerifyEmailUseCase,
// val getCurrentUserUseCase: GetCurrentUserUseCase,
// val logoutUseCase: LogoutUseCase
)
/*
class SignInUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(email: String, password: String): ResultWrapper<User> {
// Validate email and password if needed
if (!isValidEmail(email)) {
return Result.Error(Exception("Invalid email format"))
}
if (password.length < 6) {
return Result.Error(Exception("Password must be at least 6 characters long"))
}
return try {
authRepository.signIn(email, password)
} catch (e: Exception) {
Result.Error(e)
}
}
private fun isValidEmail(email: String): Boolean {
// You can add a better email validation logic if needed
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
*/
class SignUpUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(signupRequest: SignupRequest): Flow<ResultWrapper<SignupRequest>> =
flow {
// Validate email and password if needed
emit(ResultWrapper.Loading)
if (!isValidEmail(signupRequest.email)) {
Timber.d("Invalid email format")
ResultWrapper.Error("Invalid email format")
return@flow
}
if (signupRequest.password.length < 8) {
Timber.d("Password must be at least 6 characters long")
emit(ResultWrapper.Error("Password must be at least 6 characters long"))
return@flow
}
if (signupRequest.password != signupRequest.password_confirmation) {
Timber.d("Passwords do not match")
emit(ResultWrapper.Error(("Passwords do not match")))
return@flow
}
try {
CoroutineScope(
Dispatchers.IO
).launch {
authRepository.signup(signupRequest)
}
// Emit Success state
// emit(ResultWrapper.Success(signupRequest))
} catch (e: Exception) {
ResultWrapper.Error("failed to sign up")
}
}
private fun isValidEmail(email: String): Boolean {
// You can add a better email validation logic if needed
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
/*
class ForgotPasswordUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(email: String): Result<Unit> {
// Validate email if needed
if (!isValidEmail(email)) {
return Result.Error(Exception("Invalid email format"))
}
return try {
authRepository.forgotPassword(email)
Result.Success(Unit)
} catch (e: Exception) {
Result.Error(e)
}
}
private fun isValidEmail(email: String): Boolean {
// You can add a better email validation logic if needed
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
*/
/*
class IsLoggedInUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(): Boolean {
// Check if the user is logged in
return authRepository.isLoggedIn()
}
}*/
/*class VerifyEmailUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(): Result<Unit> {
// Verify the user email
return try {
authRepository.verifyEmail()
Result.Success(Unit)
} catch (e: Exception) {
Result.Error(e)
}
}
}*/
/*
class GetCurrentUserUseCase @Inject constructor(private val authRepository: AuthRepository) {
suspend operator fun invoke(): Result<User?> {
// Get the user
return try {
val user = authRepository.getCurrentUser()
Result.Success(user)
} catch (e:*/
// another file
package com.divadventure.divadventure.data.Model
import com.google.gson.annotations.SerializedName
data class SignupRequest(
val email: String,
val password: String,
val password_confirmation: String,
val platform: String = "Android" // Default value for the platform
)
data class SignUpResponse(
@SerializedName("data") val data: UserData
)
data class UserData(
@SerializedName("id") val id: String,
@SerializedName("avatar") val avatar: String?,
@SerializedName("first_name") val firstName: String?,
@SerializedName("last_name") val lastName: String?,
@SerializedName("username") val username: String?,
@SerializedName("email") val email: String,
@SerializedName("birthdate") val birthdate: String?,
@SerializedName("bio") val bio: String?,
@SerializedName("location") val location: String?,
@SerializedName("privacy_settings") val privacySettings: PrivacySettings,
@SerializedName("current_access_token") val currentAccessToken: CurrentAccessToken
)
data class PrivacySettings(
@SerializedName("bio") val bio: String,
@SerializedName("birthdate") val birthdate: String,
@SerializedName("adventures") val adventures: String,
@SerializedName("friends") val friends: String,
@SerializedName("location") val location: String
)
data class CurrentAccessToken(
@SerializedName("platform") val platform: String,
@SerializedName("token") val token: String,
@SerializedName("refresh_token") val refreshToken: String,
@SerializedName("expires_at") val expiresAt: String,
@SerializedName("refresh_token_expires_at") val refreshTokenExpiresAt: String
)
// another file
package com.divadventure.divadventure.data
import com.divadventure.divadventure.ResultWrapper
import com.divadventure.divadventure.data.Model.SignUpResponse
import com.divadventure.divadventure.data.Model.SignupRequest
import com.google.gson.Gson
import com.google.gson.JsonParseException
import okio.IOException
import retrofit2.HttpException
import timber.log.Timber
import javax.inject.Inject
class AuthRepository @Inject constructor(
private val authService: AuthService
) {
suspend fun signup(request: SignupRequest): ResultWrapper<SignUpResponse> {
Timber.d("Starting signup request: $request")
return try {
val response = authService.signup(request).execute()
Timber.d("Signup response: $response")
if (response.isSuccessful) {
/*
val responseBody = response.raw().body?.toString()
*/
/*
val authResponse = Gson().fromJson(
responseBody, SignUpResponse::class.java
)
*/
val authResponse = response.body() as SignUpResponse?
// Extract the authResponse from response.body()
Timber.d("Signup successful: $authResponse")
if (authResponse != null) {
ResultWrapper.Success(authResponse)
} else {
Timber.w("Response body is null")
ResultWrapper.Error("Response body is null")
}
} else {
val errorBody = response.errorBody()?.string()
val message = if (errorBody != null) {
try {
val errorJson = Gson().fromJson(errorBody, Map::class.java)
Timber.w("Signup failed with error body: $errorJson")
errorJson["message"].toString() // Extract the message field
} catch (e: JsonParseException) {
Timber.e(e, "Invalid error response")
"Invalid error response: ${e.message}"
}
} else {
Timber.w("Signup failed with code: ${response.code()}")
"Signup failed with code: ${response.code()}"
}
ResultWrapper.Error(message)
}
} catch (httpException: HttpException) {
Timber.e(httpException, "HTTP exception occurred")
// Handle HTTP exceptions (4xx or 5xx status codes)
val message = httpException.message() ?: "HTTP Error"
ResultWrapper.Error("HTTP error: $message")
} catch (ioException: IOException) {
Timber.e(ioException, "Network exception occurred")
// Handle network issues (e.g., no internet connection)
ResultWrapper.Error("Network error: ${ioException.message}")
} catch (jsonParseException: JsonParseException) {
Timber.e(jsonParseException, "JSON parsing exception occurred")
// Handle JSON parsing issues
ResultWrapper.Error("JSON parsing error: ${jsonParseException.message}")
} catch (e: Exception) {
Timber.e(e, "An unexpected exception occurred")
// Handle other unexpected exceptions
ResultWrapper.Error("An unexpected error occurred: ${e.message}")
}
}
// Add other repository methods here...
}
// another file
package com.divadventure.divadventure.data
import com.divadventure.divadventure.data.Model.SignUpResponse
import com.divadventure.divadventure.data.Model.SignupRequest
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST
interface AuthService {
@POST("auth/sign-up")
fun signup(@Body request: SignupRequest): Call<SignUpResponse>
}
// another file
package com.divadventure.divadventure.ViewModel
import androidx.lifecycle.viewModelScope
import com.divadventure.divadventure.BaseViewModel
import com.divadventure.divadventure.Intent.AuthIntent
import com.divadventure.divadventure.ResultWrapper
import com.divadventure.divadventure.State.AuthState
import com.divadventure.divadventure.data.AuthRepository
import com.divadventure.divadventure.data.Model.SignupRequest
import com.divadventure.divadventure.domain.AuthUseCases
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
class AuthViewModel @Inject constructor(
private val authUseCases: AuthUseCases, private val authRepository: AuthRepository
) : BaseViewModel<AuthIntent, AuthState>(AuthState()) {
override suspend fun handleIntent(intent: AuthIntent) {
when (intent) {
is AuthIntent.SignUp -> {
updateState(state.value.copy(isLoading = true))
authUseCases.signUpUseCase(
SignupRequest(
email = intent.email,
password = intent.password,
password_confirmation = intent.password
)
).collectLatest { result ->
when (result) {
is ResultWrapper.Success -> {
viewModelScope.launch {
updateState(
state.value.copy(
isLoading = false,
error = null,
isLogged = true
)
)
Timber.d("Signup successful: ${result.data}")
}
}
is ResultWrapper.Error -> {
viewModelScope.launch {
Timber.d("Error: ${result.message}")
}
}
ResultWrapper.Loading -> {
viewModelScope.launch {
Timber.d("Loading...")
}
}
}
}
}
AuthIntent.CheckIfLoggedIn -> {}
AuthIntent.ClearError -> {}
AuthIntent.ClearNavigation -> {}
is AuthIntent.ForgotPassword -> {}
AuthIntent.GoToForgotPassword -> {}
AuthIntent.GoToLanding -> {}
AuthIntent.GoToSignIn -> {}
AuthIntent.GoToSignUp -> {}
AuthIntent.NavigateToEmailVerification -> {}
AuthIntent.NavigateToForgotPassword -> {}
AuthIntent.NavigateToLandingPage -> {}
AuthIntent.NavigateToMain -> {}
AuthIntent.NavigateToSignIn -> {}
AuthIntent.NavigateToSignUp -> {}
is AuthIntent.SignIn -> {}
AuthIntent.SignUpWithGoogle -> {
updateState(
state.value.copy(
isLogged = true
)
)
Timber.d("Signing up with Google...")
}
is AuthIntent.OnEmailChanged -> {
updateState(
state.value.copy(
email = intent.email
)
)
checkSignupCardColor()
}
is AuthIntent.OnPasswordChanged -> {
updateState(
state.value.copy(
password = intent.password
)
)
checkSignupCardColor()
}
is AuthIntent.OnPasswordConfirmationChanged -> {
updateState(
state.value.copy(
passwordConfirmation = intent.passwordConfirmation
)
)
checkSignupCardColor()
}
}
}
private fun checkSignupCardColor() {
if (state.value.email.isNotEmpty() && state.value.password.isNotEmpty() &&
isEmailValid(state.value.email) && isAtleast8Characters(state.value.password) &&
passwordsMatch(
password = state.value.password,
passwordConfirmation = state.value.passwordConfirmation
)
) {
updateState(
state.value.copy(
rawDataAccepted = true
)
)
} else {
updateState(
state.value.copy(
rawDataAccepted = false
)
)
}
}
private fun passwordsMatch(password: String, passwordConfirmation: String): Boolean {
return password == passwordConfirmation
}
private fun isAtleast8Characters(password: String): Boolean {
return password.length >= 8
}
private fun isEmailValid(email: String): Boolean {
val emailRegex = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$""".toRegex()
return emailRegex.matches(email)
}
}
package com.divadventure.divadventure
sealed class ResultWrapper<out T> {
data class Success<out T>(val data: T) : ResultWrapper<T>()
data class Error(val message: String) : ResultWrapper<Nothing>()
object Loading : ResultWrapper<Nothing>()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment