Skip to content

Commit

Permalink
Major refactoring of architecture #6
Browse files Browse the repository at this point in the history
  • Loading branch information
AmadeyKuspakov committed Jul 10, 2023
1 parent 0e5bab9 commit 2edbec7
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 89 deletions.
4 changes: 2 additions & 2 deletions app/src/main/java/jp/co/soramitsu/card/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class MainActivity : ComponentActivity() {
)
},
client = buildClient(),
userAvailableXorAmount = 1.9
userAvailableXorAmount = 120.0
)
)
}
Expand All @@ -89,7 +89,7 @@ class MainActivity : ComponentActivity() {
soraCardInfo = null,
kycCredentials = SoraCardKycCredentials("", "", ""),
client = buildClient(),
userAvailableXorAmount = 1.9
userAvailableXorAmount = 120.0
)
)
}
Expand Down
18 changes: 6 additions & 12 deletions oauth/src/main/java/jp/co/soramitsu/oauth/base/SoraCardNavGraph.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ 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.enterphone.EnterPhoneNumberScreen
import jp.co.soramitsu.oauth.feature.login.enterotp.VerifyPhoneNumberScreen
import jp.co.soramitsu.oauth.feature.login.web.WebPageScreen
import jp.co.soramitsu.oauth.feature.registration.enternames.RegisterUserScreen
import jp.co.soramitsu.oauth.feature.registration.enteremail.EnterEmailScreen
import jp.co.soramitsu.oauth.feature.registration.sendverificationemail.VerifyEmailScreen
Expand Down Expand Up @@ -87,18 +88,11 @@ internal fun SoraCardNavGraph(
GetPreparedScreen()
}

// animatedComposable(
// route = Destination.WEB_PAGE.route
// .plus(Argument.TITLE.path())
// .plus(Argument.URL.path())
// ) { backStackEntry ->
// WebPageScreen(
// title = backStackEntry.requireArguments()
// .requireString(Argument.TITLE.arg),
// webUrl = backStackEntry.requireArguments()
// .requireString(Argument.URL.arg)
// )
// }
animatedComposable(
route = LoginDestination.WebPage.route
) {
WebPageScreen()
}

animatedComposable(
route = VerificationDestination.VerificationFailed.route
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package jp.co.soramitsu.oauth.base.navigation

import android.os.Bundle
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.scaleIn
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.runtime.Composable
Expand All @@ -31,28 +26,24 @@ fun NavGraphBuilder.animatedComposable(
arguments = arguments,
deepLinks = deepLinks,
enterTransition = {
println("This is checkpoint: enterTransition - ${this.initialState.destination.route} to ${this.targetState.destination.route}")
slideInHorizontally(
initialOffsetX = { it },
animationSpec = tween(TRANSITION_DURATION)
)
},
popEnterTransition = {
println("This is checkpoint: popEnterTransition - ${this.initialState.destination.route} to ${this.targetState.destination.route}")
slideInHorizontally(
initialOffsetX = { -it },
animationSpec = tween(TRANSITION_DURATION)
)
},
exitTransition = {
println("This is checkpoint: exitTransition - ${this.initialState.destination.route} to ${this.targetState.destination.route}")
slideOutHorizontally(
targetOffsetX = { -it },
animationSpec = tween(TRANSITION_DURATION)
)
},
popExitTransition = {
println("This is checkpoint: popExitTransition - ${this.initialState.destination.route} to ${this.targetState.destination.route}")
slideOutHorizontally(
targetOffsetX = { it },
animationSpec = tween(TRANSITION_DURATION)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class InMemoryRepo @Inject constructor() {
var mode: Mode? = null
var environment: SoraCardEnvironmentType = SoraCardEnvironmentType.NOT_DEFINED
var client: String = BuildConfig.LIBRARY_PACKAGE_NAME
var userAvailableXorAmount: Double = 0.toDouble()
var userAvailableXorAmount: Double = 120.toDouble()

val euroLiquidityThreshold = 100
val euroCardIssuancePrice = 20
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@ class AccountInteractorImpl @Inject constructor(

val kycStatusToSave =
tachiRepository.getKycStatus(header, it.accessToken).getOrThrow()
?: KycStatus.NotInitialized
?: KycStatus.Started

userSessionRepository.setKycStatus(kycStatusToSave)
userSessionRepository.apply {
setKycStatus(kycStatusToSave)
setFirstTimeUsage(true)
}
}

AccountOperationResult.Executed
Expand All @@ -83,9 +86,12 @@ class AccountInteractorImpl @Inject constructor(

val kycStatusToSave =
tachiRepository.getKycStatus(header, it.accessToken).getOrThrow()
?: KycStatus.NotInitialized
?: KycStatus.Started

userSessionRepository.setKycStatus(kycStatusToSave)
userSessionRepository.apply {
setKycStatus(kycStatusToSave)
setFirstTimeUsage(true)
}
}

AccountOperationResult.Executed
Expand Down Expand Up @@ -221,7 +227,7 @@ class AccountInteractorImpl @Inject constructor(

val kycStatusToSave =
tachiRepository.getKycStatus(header, accessToken).getOrThrow()
?: KycStatus.NotInitialized
?: KycStatus.Started

userSessionRepository.setKycStatus(kycStatusToSave)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@ import jp.co.soramitsu.oauth.common.navigation.flow.verification.api.Verificatio
import jp.co.soramitsu.oauth.core.datasources.paywings.api.PayWingsRepository
import jp.co.soramitsu.oauth.core.datasources.paywings.api.PayWingsResponse
import jp.co.soramitsu.oauth.core.datasources.session.api.UserSessionRepository
import jp.co.soramitsu.oauth.core.engines.coroutines.api.CoroutinesStorage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

class NavigationCoordinatorImpl @Inject constructor(
payWingsRepository: PayWingsRepository,
userSessionRepository: UserSessionRepository,
inMemoryRepo: InMemoryRepo,
coroutinesStorage: CoroutinesStorage,
private val loginFlow: LoginFlow,
private val registrationFlow: RegistrationFlow,
private val verificationFlow: VerificationFlow,
Expand Down Expand Up @@ -88,9 +92,15 @@ class NavigationCoordinatorImpl @Inject constructor(
is PayWingsResponse.NavigationIncentive -> {
when(payWingsResponse) {
is PayWingsResponse.NavigationIncentive.OnUserSignInRequiredScreen -> {
loginFlow.onStart(
destination = LoginDestination.EnterPhone
)
coroutinesStorage.unsupervisedUiScope.launch {
val isFirstTimeUsage = withContext(coroutinesStorage.dispatcherIo) {
userSessionRepository.isFirstTimeUsage()
}

if (isFirstTimeUsage)
loginFlow.onStart(destination = LoginDestination.TermsAndConditions) else
loginFlow.onStart(destination = LoginDestination.EnterPhone)
}
}
is PayWingsResponse.NavigationIncentive.OnVerificationOtpBeenSent -> {
loginFlow.onStart(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ sealed interface LoginDestination: SoraCardDestinations {
override val route: String = "TERMS_AND_CONDITIONS"
}

object WebPage: LoginDestination {
override val route: String = "WebPage"

const val TITLE_STRING_RES_KEY = "TITLE_STRING_RES_KEY"
const val URL_KEY = "URL_KEY"
}

object EnterPhone: LoginDestination {
override val route: String = "ENTER_PHONE"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package jp.co.soramitsu.oauth.common.navigation.flow.login.impl

import android.os.Bundle
import androidx.core.os.bundleOf
import jp.co.soramitsu.oauth.R
import jp.co.soramitsu.oauth.core.engines.activityresult.api.SoraCardResult
import jp.co.soramitsu.oauth.common.navigation.flow.login.api.LoginDestination
import jp.co.soramitsu.oauth.common.navigation.flow.login.api.LoginFlow
import jp.co.soramitsu.oauth.common.navigation.flow.registration.api.RegistrationDestination
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 javax.inject.Inject

class LoginFlowImpl @Inject constructor(
Expand All @@ -22,10 +21,6 @@ class LoginFlowImpl @Inject constructor(

override fun onStart(destination: LoginDestination) =
when(destination) {
is LoginDestination.TermsAndConditions ->
composeRouter.setNewStartDestination(destination)
is LoginDestination.EnterPhone ->
composeRouter.setNewStartDestination(destination)
is LoginDestination.EnterOtp -> {
_args[destination::class.java.name] = bundleOf().apply {
putInt(
Expand All @@ -35,6 +30,7 @@ class LoginFlowImpl @Inject constructor(
}
composeRouter.setNewStartDestination(destination)
}
else -> composeRouter.setNewStartDestination(destination)
}

override fun onBack() {
Expand All @@ -46,11 +42,25 @@ class LoginFlowImpl @Inject constructor(
}

override fun onGeneralTermsClicked() {
// TODO open WebView
val title = R.string.terms_and_conditions_general_terms
val url = "https://soracard.com/terms/"

_args[LoginDestination.WebPage::class.java.name] = Bundle().apply {
putInt(LoginDestination.WebPage.TITLE_STRING_RES_KEY, title)
putString(LoginDestination.WebPage.URL_KEY, url)
}
composeRouter.navigateTo(LoginDestination.WebPage)
}

override fun onPrivacyPolicyClicked() {
// TODO open WebView
val title = R.string.terms_and_conditions_privacy_policy
val url = "https://soracard.com/privacy/"

_args[LoginDestination.WebPage::class.java.name] = Bundle().apply {
putInt(LoginDestination.WebPage.TITLE_STRING_RES_KEY, title)
putString(LoginDestination.WebPage.URL_KEY, url)
}
composeRouter.navigateTo(LoginDestination.WebPage)
}

override fun onAcceptTermsAndConditions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ interface UserSessionRepository {
status: KycStatus
)

suspend fun setKycFailureDescription(
description: String
)

suspend fun setFirstTimeUsage(
isTrue: Boolean
)

suspend fun getAccessToken(): String

suspend fun getAccessTokenExpirationTime(): Long

suspend fun getRefreshToken(): String

suspend fun isFirstTimeUsage(): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class UserSessionRepositoryImpl @Inject constructor(
const val REFRESH_TOKEN_KEY = "REFRESH_TOKEN_KEY"
const val KYC_STATUS_KEY = "KYC_STATUS_KEY"
const val ADDITIONAL_VERIFICATION_INFO_KEY = "ADDITIONAL_VERIFICATION_INFO_KEY"
const val IS_FIRST_TIME_USAGE_KEY = "IS_FIRST_TIME_USAGE_KEY"
}
override val kycStatusFlow: Flow<KycStatus> =
preferences.dataFlow.map {
Expand All @@ -43,6 +44,13 @@ class UserSessionRepositoryImpl @Inject constructor(
override suspend fun setKycStatus(status: KycStatus) =
preferences.putString(KYC_STATUS_KEY, status.name)

override suspend fun setKycFailureDescription(description: String) =
preferences.putString(ADDITIONAL_VERIFICATION_INFO_KEY, description)

override suspend fun setFirstTimeUsage(isTrue: Boolean) {
preferences.putBoolean(IS_FIRST_TIME_USAGE_KEY, isTrue)
}

override suspend fun getAccessToken(): String =
preferences.getString(ACCESS_TOKEN_KEY)

Expand All @@ -51,4 +59,7 @@ class UserSessionRepositoryImpl @Inject constructor(

override suspend fun getRefreshToken(): String =
preferences.getString(REFRESH_TOKEN_KEY)

override suspend fun isFirstTimeUsage(): Boolean =
preferences.getBoolean(IS_FIRST_TIME_USAGE_KEY, true)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,22 @@ import android.content.Intent
import android.os.Looper
import androidx.activity.result.ActivityResultLauncher
import com.paywings.onboarding.kyc.android.sdk.data.model.KycContractData
import com.paywings.onboarding.kyc.android.sdk.data.model.KycCredentials
import com.paywings.onboarding.kyc.android.sdk.data.model.KycSettings
import com.paywings.onboarding.kyc.android.sdk.data.model.KycUserData
import com.paywings.onboarding.kyc.android.sdk.data.model.UserCredentials
import jp.co.soramitsu.oauth.base.sdk.InMemoryRepo
import jp.co.soramitsu.oauth.base.sdk.SoraCardConstants
import jp.co.soramitsu.oauth.core.engines.activityresult.api.SoraCardResult
import jp.co.soramitsu.oauth.core.engines.activityresult.api.ActivityResult
import java.lang.ref.WeakReference
import java.util.UUID
import javax.inject.Inject

class ActivityResultImpl @Inject constructor(): ActivityResult {

private var kycContractWeakRef: WeakReference<ActivityResultLauncher<KycContractData>>? = null
get() = if (!Looper.getMainLooper().isCurrentThread)
throw IllegalAccessError(NOT_MAIN_THREAD_ACCESS) else
field
private var kycContractRef: ActivityResultLauncher<KycContractData>? = null

override fun setKycContract(launcher: ActivityResultLauncher<KycContractData>) {
if (!Looper.getMainLooper().isCurrentThread)
throw IllegalAccessError(NOT_MAIN_THREAD_ACCESS)

kycContractWeakRef = WeakReference(launcher)
kycContractRef = launcher
}

override fun launchKycContract(kycContractData: KycContractData): Boolean {
kycContractWeakRef?.get()?.launch(kycContractData)
kycContractRef?.launch(kycContractData)
?: return false
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ interface KeyValuePreferences {

suspend fun getString(field: String): String

suspend fun putLong(field: String, value: Long)

suspend fun getLong(field: String, defaultValue: Long): Long

suspend fun putLong(field: String, value: Long)
suspend fun putBoolean(field: String, value: Boolean)

suspend fun getBoolean(field: String, defaultValue: Boolean): Boolean

suspend fun clear(field: String)

Expand Down
Loading

0 comments on commit 2edbec7

Please sign in to comment.