Skip to content

Commit

Permalink
Major refactoring of architecture #4
Browse files Browse the repository at this point in the history
  • Loading branch information
AmadeyKuspakov committed Jul 10, 2023
1 parent ec602e9 commit ba7566a
Show file tree
Hide file tree
Showing 32 changed files with 374 additions and 263 deletions.
17 changes: 14 additions & 3 deletions oauth/src/main/java/jp/co/soramitsu/oauth/base/CardActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
Expand All @@ -35,6 +36,8 @@ import jp.co.soramitsu.oauth.core.engines.activityresult.api.ActivityResult
import jp.co.soramitsu.oauth.core.engines.router.api.ComposeRouter
import jp.co.soramitsu.oauth.core.engines.router.api.SoraCardDestinations
import jp.co.soramitsu.oauth.theme.AuthSdkTheme
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject

Expand All @@ -60,8 +63,16 @@ class CardActivity : AppCompatActivity(R.layout.card_activity) {
super.onCreate(savedInstanceState)
setContent {
AuthSdkTheme {
val startDestination = composeRouter.startDestination.collectAsState()

LaunchedEffect(Unit) {
composeRouter.startDestination.onEach {
println("This is checkpoint: composeRouter.startDestination - $it")
}.launchIn(this)
}

Box(modifier = Modifier.fillMaxSize()) {
val isLoading = remember(composeRouter.startDestination.value) {
val isLoading = remember(startDestination.value) {
derivedStateOf {
composeRouter.startDestination.value === SoraCardDestinations.Loading
}
Expand All @@ -77,7 +88,7 @@ class CardActivity : AppCompatActivity(R.layout.card_activity) {

SoraCardNavGraph(
navHostController = composeRouter.navController,
startDestination = composeRouter.startDestination.value,
startDestination = startDestination.value,
)
}
}
Expand Down
149 changes: 40 additions & 109 deletions oauth/src/main/java/jp/co/soramitsu/oauth/base/SoraCardNavGraph.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import jp.co.soramitsu.oauth.base.navigation.animatedComposable
import jp.co.soramitsu.oauth.base.navigation.path
import jp.co.soramitsu.oauth.base.navigation.requireArguments
import jp.co.soramitsu.oauth.base.navigation.requireString
import jp.co.soramitsu.oauth.common.navigation.flow.login.api.LoginDestination
import jp.co.soramitsu.oauth.common.navigation.flow.registration.api.RegistrationDestination
import jp.co.soramitsu.oauth.common.navigation.flow.verification.api.VerificationDestination
import jp.co.soramitsu.oauth.core.engines.router.api.SoraCardDestinations
import jp.co.soramitsu.oauth.feature.login.terms.TermsAndConditionsScreen
import jp.co.soramitsu.oauth.feature.login.web.WebPageScreen
Expand All @@ -39,111 +42,60 @@ internal fun SoraCardNavGraph(
navHostController: NavHostController,
startDestination: SoraCardDestinations,
) {
val isGraphVisible = remember {
println("This is checkpoint: SoraCardNavGraph recompose - ${startDestination.route}")

val isGraphVisible = remember(startDestination) {
startDestination !== SoraCardDestinations.Loading
}

val navGraph = remember {
val navGraph = remember(startDestination) {
println("This is checkpoint: navGraph remember recompose - ${startDestination.route}")

movableContentOf {
println("This is checkpoint: navGraph movableContentOf recompose - ${startDestination.route}")

AnimatedNavHost(
navController = navHostController,
startDestination = startDestination.route
startDestination = SoraCardDestinations.Loading.route
) {
animatedComposable(
route = SoraCardDestinations.TermsAndConditions.route
route = LoginDestination.TermsAndConditions.route
) {
TermsAndConditionsScreen()
}

animatedComposable(
route = SoraCardDestinations.EnterPhone.route
route = LoginDestination.EnterPhone.route
) {
EnterPhoneNumberScreen()
}

animatedComposable(
route = SoraCardDestinations.EnterOtp.template,
arguments = listOf(
navArgument(
Argument.PHONE_NUMBER.arg
) {
type = NavType.StringType
defaultValue = "+1234567890"
},
navArgument(
name = "/{otpLength}"
) {
type = NavType.IntType
defaultValue = 6
}
)
) { backStackEntry ->
VerifyPhoneNumberScreen(
phoneNumber = backStackEntry.arguments
?.getString("/{phoneNumber}"),
otpLength = backStackEntry.arguments
?.getInt("/{otpLength}"),
)
route = LoginDestination.EnterOtp.route
) {
VerifyPhoneNumberScreen()
}

animatedComposable(
route = SoraCardDestinations.EnterFirstAndLastName.route
route = RegistrationDestination.EnterFirstAndLastName.route
) {
RegisterUserScreen()
}

animatedComposable(
route = SoraCardDestinations.EnterEmail.template,
arguments = listOf(
navArgument(
name = "/{firstName}"
) {
type = NavType.StringType
defaultValue = "John"
},
navArgument(
name = "/{lastName}"
) {
type = NavType.StringType
defaultValue = "Doe"
}
)
) { backStackEntry ->
EnterEmailScreen(
firstName = backStackEntry.requireArguments()
.getString("/{firstName}"),
lastName = backStackEntry.requireArguments()
.getString("/{lastName}")
)
route = RegistrationDestination.EnterEmail.route,
) {
EnterEmailScreen()
}

animatedComposable(
route = SoraCardDestinations.SendVerificationEmail.template,
arguments = listOf(
navArgument(
name = "/{email}"
) {
type = NavType.StringType
defaultValue = "johndoe@email.com"
},
navArgument(
name = "/{autoEmailBeenSent}"
) {
type = NavType.BoolType
defaultValue = false
},
)
) { backStackEntry ->
VerifyEmailScreen(
email = backStackEntry.requireArguments()
.requireString("/{email}"),
autoEmailSent = backStackEntry.requireArguments()
.getBoolean("/{autoEmailBeenSent}")
)
route = RegistrationDestination.EmailConfirmation.route
) {
VerifyEmailScreen()
}

animatedComposable(
route = SoraCardDestinations.GetPrepared.route
route = VerificationDestination.GetPrepared.route
) {
GetPreparedScreen()
}
Expand All @@ -162,69 +114,48 @@ internal fun SoraCardNavGraph(
// }

animatedComposable(
route = SoraCardDestinations.VerificationFailed.template,
arguments = listOf(
navArgument(
name = "/{additionalInfo}"
) {
type = NavType.StringType
defaultValue = ""
},
)
) {backStackEntry ->
VerificationFailedScreen(
additionalDescription = backStackEntry.requireArguments()
.getString("/{additionalInfo}")
)
route = VerificationDestination.VerificationFailed.route
) {
VerificationFailedScreen()
}

animatedComposable(
route = SoraCardDestinations.VerificationRejected.template,
arguments = listOf(
navArgument(
name = "additionalInfo"
) {
type = NavType.StringType
defaultValue = ""
},
)
) {backStackEntry ->
VerificationRejectedScreen(
additionalDescription = backStackEntry.requireArguments()
.getString("/{additionalInfo}")
)
route = VerificationDestination.VerificationRejected.route
) {
VerificationRejectedScreen()
}

animatedComposable(
route = SoraCardDestinations.VerificationInProgress.route
route = VerificationDestination.VerificationInProgress.route
) {
VerificationInProgressScreen()
}

animatedComposable(
route = SoraCardDestinations.VerificationSuccessful.route
route = VerificationDestination.VerificationSuccessful.route
) {
VerificationSuccessfulScreen()
}

animatedComposable(
route = SoraCardDestinations.NotEnoughXor.route
route = VerificationDestination.NotEnoughXor.route
) {
CardIssuanceScreen()
}

dialog(
route = SoraCardDestinations.GetMoreXor.route
route = VerificationDestination.GetMoreXor.route
) {
ChooseXorPurchaseMethodDialog()
}
}


println("This is checkpoint: navHostController.graph - ${navHostController.graph.nodes}")
}
}

if (isGraphVisible) {
navGraph.invoke()
}
navGraph.invoke()
}

@Preview
Expand All @@ -233,7 +164,7 @@ internal fun SoraCardNavGraph(
private fun PreviewSoraCardNavGraph() {
SoraCardNavGraph(
navHostController = rememberAnimatedNavController(),
startDestination = SoraCardDestinations.TermsAndConditions
startDestination = LoginDestination.TermsAndConditions
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ interface AccountInteractor {

suspend fun requestOtpCode(phoneNumber: String)

suspend fun resendOtpCode()

suspend fun verifyOtpCode(otpCode: String)

suspend fun registerUser(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ class AccountInteractorImpl @Inject constructor(
}
}

override suspend fun resendOtpCode() {
requestOtpCode(
phoneNumber = cache[PHONE_NUMBER] as String
)
}

override suspend fun verifyOtpCode(otpCode: String) {
payWingsRepository.verifyPhoneNumberWithOtp(otpCode)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package jp.co.soramitsu.oauth.common.navigation.coordinator.impl

import jp.co.soramitsu.oauth.base.sdk.InMemoryRepo
import jp.co.soramitsu.oauth.core.datasources.tachi.api.models.KycStatus
import jp.co.soramitsu.oauth.common.navigation.flow.login.api.LoginDestination
import jp.co.soramitsu.oauth.common.navigation.coordinator.api.NavigationCoordinator
Expand All @@ -22,6 +23,7 @@ import javax.inject.Inject
class NavigationCoordinatorImpl @Inject constructor(
payWingsRepository: PayWingsRepository,
userSessionRepository: UserSessionRepository,
inMemoryRepo: InMemoryRepo,
private val loginFlow: LoginFlow,
private val registrationFlow: RegistrationFlow,
private val verificationFlow: VerificationFlow,
Expand All @@ -35,9 +37,11 @@ class NavigationCoordinatorImpl @Inject constructor(
/* DO NOTHING */
}
KycStatus.Started -> {
verificationFlow.onStart(
destination = VerificationDestination.Start
)
val destination = if (inMemoryRepo.userAvailableXorAmount < 100)
VerificationDestination.NotEnoughXor else
VerificationDestination.GetPrepared

verificationFlow.onStart(destination = destination)
}
KycStatus.Failed -> {
verificationFlow.onStart(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
package jp.co.soramitsu.oauth.common.navigation.flow.login.api

sealed interface LoginDestination {
import jp.co.soramitsu.oauth.core.engines.router.api.SoraCardDestinations

object TermsAndConditions: LoginDestination
sealed interface LoginDestination: SoraCardDestinations {

object EnterPhone: LoginDestination
object TermsAndConditions: LoginDestination {
override val route: String = "TERMS_AND_CONDITIONS"
}

@JvmInline
value class EnterOtp(
object EnterPhone: LoginDestination {
override val route: String = "ENTER_PHONE"
}

class EnterOtp(
val otpLength: Int
): LoginDestination
): LoginDestination {
override val route: String = "ENTER_OTP"

companion object: SoraCardDestinations {
override val route: String = "ENTER_OTP"

const val OTP_LENGTH_KEY = "OTP_LENGTH"
}
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package jp.co.soramitsu.oauth.common.navigation.flow.login.api

import android.os.Bundle

interface LoginFlow {

val args: Map<String, Bundle>

fun onStart(destination: LoginDestination)

fun onBack()
Expand Down
Loading

0 comments on commit ba7566a

Please sign in to comment.