mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 13:57:10 +09:00
DROID-1484 Onboarding | Enhancement | Start sign-up from the void screen and not from the start screen (#144)
This commit is contained in:
parent
c9882c083f
commit
cc48dbf020
10 changed files with 281 additions and 127 deletions
|
@ -63,12 +63,13 @@ import com.anytypeio.anytype.di.feature.auth.DaggerDeletedAccountComponent
|
|||
import com.anytypeio.anytype.di.feature.cover.UnsplashModule
|
||||
import com.anytypeio.anytype.di.feature.home.DaggerHomeScreenComponent
|
||||
import com.anytypeio.anytype.di.feature.library.DaggerLibraryComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingAuthComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingLoginSetupComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingMnemonicComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingMnemonicLoginComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingSoulCreationAnimComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingSoulCreationComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingStartComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.signup.DaggerOnboardingVoidComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.DaggerRelationCreateFromLibraryComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.DaggerRelationEditComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.LimitObjectTypeModule
|
||||
|
@ -903,8 +904,14 @@ class ComponentManager(
|
|||
.create(findComponentDependencies())
|
||||
}
|
||||
|
||||
val onboardingAuthComponent = Component {
|
||||
DaggerOnboardingAuthComponent
|
||||
val onboardingStartComponent = Component {
|
||||
DaggerOnboardingStartComponent
|
||||
.factory()
|
||||
.create(findComponentDependencies())
|
||||
}
|
||||
|
||||
val onboardingNewVoidComponent = Component {
|
||||
DaggerOnboardingVoidComponent
|
||||
.factory()
|
||||
.create(findComponentDependencies())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package com.anytypeio.anytype.di.feature.onboarding
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingStartViewModel
|
||||
import dagger.Binds
|
||||
import dagger.Component
|
||||
import dagger.Module
|
||||
import javax.inject.Scope
|
||||
|
||||
@Component(
|
||||
dependencies = [OnboardingStartDependencies::class],
|
||||
modules = [
|
||||
OnboardingStartModule::class,
|
||||
OnboardingStartModule.Declarations::class
|
||||
]
|
||||
)
|
||||
@AuthScreenScope
|
||||
interface OnboardingStartComponent {
|
||||
@Component.Factory
|
||||
interface Builder {
|
||||
fun create(dependencies: OnboardingStartDependencies): OnboardingStartComponent
|
||||
}
|
||||
|
||||
fun getViewModel(): OnboardingStartViewModel
|
||||
}
|
||||
|
||||
@Module
|
||||
object OnboardingStartModule {
|
||||
@Module
|
||||
interface Declarations {
|
||||
@Binds
|
||||
@AuthScreenScope
|
||||
fun bindViewModelFactory(factory: OnboardingStartViewModel.Factory): ViewModelProvider.Factory
|
||||
}
|
||||
}
|
||||
|
||||
interface OnboardingStartDependencies : ComponentDependencies {
|
||||
fun analytics(): Analytics
|
||||
}
|
||||
|
||||
@Scope
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class AuthScreenScope
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.di.feature.onboarding
|
||||
package com.anytypeio.anytype.di.feature.onboarding.signup
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.auth.interactor.CreateAccount
|
||||
import com.anytypeio.anytype.domain.auth.interactor.SetupWallet
|
||||
|
@ -14,43 +15,42 @@ import com.anytypeio.anytype.domain.platform.MetricsProvider
|
|||
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
|
||||
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
|
||||
import com.anytypeio.anytype.domain.workspace.WorkspaceManager
|
||||
import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingVoidViewModel
|
||||
import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingAuthViewModel
|
||||
import dagger.Binds
|
||||
import dagger.Component
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Scope
|
||||
|
||||
@Component(
|
||||
dependencies = [OnboardingAuthDependencies::class],
|
||||
dependencies = [OnboardingVoidDependencies::class],
|
||||
modules = [
|
||||
OnboardingAuthModule::class,
|
||||
OnboardingAuthModule.Declarations::class
|
||||
OnboardingVoidModule::class,
|
||||
OnboardingVoidModule.Declarations::class
|
||||
]
|
||||
)
|
||||
@AuthScreenScope
|
||||
interface OnboardingAuthComponent {
|
||||
@PerScreen
|
||||
interface OnboardingVoidComponent {
|
||||
|
||||
@Component.Factory
|
||||
interface Builder {
|
||||
fun create(dependencies: OnboardingAuthDependencies): OnboardingAuthComponent
|
||||
fun create(dependencies: OnboardingVoidDependencies): OnboardingVoidComponent
|
||||
}
|
||||
|
||||
fun getViewModel(): OnboardingAuthViewModel
|
||||
fun getViewModel(): OnboardingVoidViewModel
|
||||
}
|
||||
|
||||
@Module
|
||||
object OnboardingAuthModule {
|
||||
object OnboardingVoidModule {
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@AuthScreenScope
|
||||
@PerScreen
|
||||
fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@AuthScreenScope
|
||||
@PerScreen
|
||||
fun provideCreateAccountUseCase(
|
||||
authRepository: AuthRepository,
|
||||
configStorage: ConfigStorage,
|
||||
|
@ -65,7 +65,7 @@ object OnboardingAuthModule {
|
|||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@AuthScreenScope
|
||||
@PerScreen
|
||||
fun provideSetupWalletUseCase(
|
||||
authRepository: AuthRepository
|
||||
): SetupWallet = SetupWallet(
|
||||
|
@ -74,7 +74,7 @@ object OnboardingAuthModule {
|
|||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@AuthScreenScope
|
||||
@PerScreen
|
||||
fun provideSetupSkipUseCase(
|
||||
repository: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
|
@ -85,15 +85,13 @@ object OnboardingAuthModule {
|
|||
|
||||
@Module
|
||||
interface Declarations {
|
||||
|
||||
@Binds
|
||||
@AuthScreenScope
|
||||
fun bindViewModelFactory(factory: OnboardingAuthViewModel.Factory): ViewModelProvider.Factory
|
||||
|
||||
@PerScreen
|
||||
fun bindViewModelFactory(factory: OnboardingVoidViewModel.Factory): ViewModelProvider.Factory
|
||||
}
|
||||
}
|
||||
|
||||
interface OnboardingAuthDependencies : ComponentDependencies {
|
||||
interface OnboardingVoidDependencies : ComponentDependencies {
|
||||
fun authRepository(): AuthRepository
|
||||
fun blockRepository(): BlockRepository
|
||||
fun configStorage(): ConfigStorage
|
||||
|
@ -103,8 +101,4 @@ interface OnboardingAuthDependencies : ComponentDependencies {
|
|||
fun pathProvider(): PathProvider
|
||||
fun metricsProvider(): MetricsProvider
|
||||
fun dispatchers(): AppCoroutineDispatchers
|
||||
}
|
||||
|
||||
@Scope
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class AuthScreenScope
|
||||
}
|
|
@ -21,12 +21,13 @@ import com.anytypeio.anytype.di.feature.SplashDependencies
|
|||
import com.anytypeio.anytype.di.feature.auth.DeletedAccountDependencies
|
||||
import com.anytypeio.anytype.di.feature.home.HomeScreenDependencies
|
||||
import com.anytypeio.anytype.di.feature.library.LibraryDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingAuthDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingLoginSetupDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingMnemonicDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingMnemonicLoginDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingSoulCreationAnimDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingSoulCreationDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingStartDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.signup.OnboardingVoidDependencies
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromLibraryDependencies
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationEditDependencies
|
||||
import com.anytypeio.anytype.di.feature.settings.AboutAppDependencies
|
||||
|
@ -83,7 +84,8 @@ interface MainComponent :
|
|||
MigrationErrorDependencies,
|
||||
BacklinkOrAddToObjectDependencies,
|
||||
FilesStorageDependencies,
|
||||
OnboardingAuthDependencies,
|
||||
OnboardingStartDependencies,
|
||||
OnboardingVoidDependencies,
|
||||
OnboardingMnemonicDependencies,
|
||||
OnboardingMnemonicLoginDependencies,
|
||||
OnboardingSoulCreationDependencies,
|
||||
|
@ -198,8 +200,13 @@ private abstract class ComponentDependenciesModule private constructor() {
|
|||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ComponentDependenciesKey(OnboardingAuthDependencies::class)
|
||||
abstract fun provideOnboardingAuthDependencies(component: MainComponent): ComponentDependencies
|
||||
@ComponentDependenciesKey(OnboardingStartDependencies::class)
|
||||
abstract fun provideOnboardingStartDependencies(component: MainComponent): ComponentDependencies
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ComponentDependenciesKey(OnboardingVoidDependencies::class)
|
||||
abstract fun provideOnboardingVoidDependencies(component: MainComponent): ComponentDependencies
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
|
@ -231,4 +238,5 @@ private abstract class ComponentDependenciesModule private constructor() {
|
|||
@ComponentDependenciesKey(OnboardingSoulCreationAnimDependencies::class)
|
||||
abstract fun provideOnboardingSoulCreationAnimDependencies(component: MainComponent): ComponentDependencies
|
||||
|
||||
|
||||
}
|
|
@ -59,11 +59,12 @@ import com.anytypeio.anytype.core_utils.insets.RootViewDeferringInsetsCallback
|
|||
import com.anytypeio.anytype.di.common.ComponentManager
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
import com.anytypeio.anytype.ext.daggerViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingAuthViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingAuthViewModel.SideEffect
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingStartViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingStartViewModel.SideEffect
|
||||
import com.anytypeio.anytype.presentation.onboarding.login.OnboardingLoginSetupViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.login.OnboardingMnemonicLoginViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingSoulCreationViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingVoidViewModel
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.AuthScreenWrapper
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.signin.EnteringTheVoidScreen
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.signin.RecoveryScreenWrapper
|
||||
|
@ -112,9 +113,7 @@ class OnboardingFragment : Fragment() {
|
|||
PagerIndicator(
|
||||
pageCount = OnboardingPage.values().filter { it.visible }.size,
|
||||
page = currentPage,
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
}
|
||||
onBackClick = { navController.popBackStack() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -189,13 +188,34 @@ class OnboardingFragment : Fragment() {
|
|||
}
|
||||
) {
|
||||
currentPage.value = OnboardingPage.VOID
|
||||
val component = componentManager().onboardingNewVoidComponent.ReleaseOn(
|
||||
viewLifecycleOwner = viewLifecycleOwner,
|
||||
state = Lifecycle.State.DESTROYED
|
||||
)
|
||||
val vm = daggerViewModel { component.get().getViewModel() }
|
||||
VoidScreenWrapper(
|
||||
contentPaddingTop = ContentPaddingTop(),
|
||||
onNextClicked = {
|
||||
navController.navigate(OnboardingNavigation.mnemonic)
|
||||
}
|
||||
onNextClicked = vm::onNextClicked,
|
||||
screenState = vm.state.collectAsState().value
|
||||
)
|
||||
|
||||
BackHandler {
|
||||
vm.onSystemBackPressed()
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
vm.navigation.collect { navigation ->
|
||||
when(navigation) {
|
||||
OnboardingVoidViewModel.Navigation.GoBack -> {
|
||||
navController.popBackStack()
|
||||
}
|
||||
OnboardingVoidViewModel.Navigation.NavigateToMnemonic -> {
|
||||
navController.navigate(OnboardingNavigation.mnemonic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
vm.toasts.collect { toast(it) }
|
||||
}
|
||||
}
|
||||
composable(
|
||||
route = OnboardingNavigation.mnemonic,
|
||||
|
@ -447,31 +467,15 @@ class OnboardingFragment : Fragment() {
|
|||
|
||||
@Composable
|
||||
private fun Auth(navController: NavHostController) {
|
||||
val component = componentManager().onboardingAuthComponent.ReleaseOn(
|
||||
val component = componentManager().onboardingStartComponent.ReleaseOn(
|
||||
viewLifecycleOwner = viewLifecycleOwner,
|
||||
state = Lifecycle.State.DESTROYED
|
||||
)
|
||||
val vm = daggerViewModel { component.get().getViewModel() }
|
||||
AuthScreenWrapper(vm = vm)
|
||||
val navigationCommands = vm.navigationFlow.collectAsState(
|
||||
initial = OnboardingAuthViewModel.AuthNavigation.Idle
|
||||
)
|
||||
LaunchedEffect(key1 = navigationCommands.value) {
|
||||
when (navigationCommands.value) {
|
||||
is OnboardingAuthViewModel.AuthNavigation.ProceedWithSignUp -> {
|
||||
navController.navigate(OnboardingNavigation.void)
|
||||
}
|
||||
is OnboardingAuthViewModel.AuthNavigation.ProceedWithSignIn -> {
|
||||
navController.navigate(OnboardingNavigation.recovery)
|
||||
}
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
vm.sideEffects.collect { effect ->
|
||||
when(effect) {
|
||||
when (effect) {
|
||||
SideEffect.OpenPrivacyPolicy -> {
|
||||
try {
|
||||
val intent = Intent(
|
||||
|
@ -483,6 +487,7 @@ class OnboardingFragment : Fragment() {
|
|||
Timber.e(e, "Error while opening privacy policy")
|
||||
}
|
||||
}
|
||||
|
||||
SideEffect.OpenTermsOfUse -> {
|
||||
try {
|
||||
val intent = Intent(
|
||||
|
@ -497,6 +502,19 @@ class OnboardingFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
vm.navigation.collect { navigation ->
|
||||
when (navigation) {
|
||||
is OnboardingStartViewModel.AuthNavigation.ProceedWithSignUp -> {
|
||||
navController.navigate(OnboardingNavigation.void)
|
||||
}
|
||||
|
||||
is OnboardingStartViewModel.AuthNavigation.ProceedWithSignIn -> {
|
||||
navController.navigate(OnboardingNavigation.recovery)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
@ -21,7 +21,6 @@ import androidx.compose.ui.text.style.TextDecoration
|
|||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_ui.OnBoardingTextPrimaryColor
|
||||
import com.anytypeio.anytype.core_ui.OnBoardingTextSecondaryColor
|
||||
|
@ -31,8 +30,7 @@ import com.anytypeio.anytype.core_ui.views.HeadlineOnBoardingTitle
|
|||
import com.anytypeio.anytype.core_ui.views.OnBoardingButtonPrimary
|
||||
import com.anytypeio.anytype.core_ui.views.OnBoardingButtonSecondary
|
||||
import com.anytypeio.anytype.core_ui.views.TextOnBoardingDescription
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingAuthViewModel
|
||||
|
||||
import com.anytypeio.anytype.presentation.onboarding.OnboardingStartViewModel
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
|
@ -41,21 +39,19 @@ fun AuthScreenPreview() {
|
|||
onLoginClicked = {},
|
||||
onJoinClicked = {},
|
||||
onPrivacyPolicyClicked = {},
|
||||
onTermsOfUseClicked = {},
|
||||
joinState = OnboardingAuthViewModel.JoinFlowState.Active
|
||||
onTermsOfUseClicked = {}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AuthScreenWrapper(
|
||||
vm: OnboardingAuthViewModel
|
||||
vm: OnboardingStartViewModel
|
||||
) {
|
||||
AuthScreen(
|
||||
onJoinClicked = vm::onJoinClicked,
|
||||
onLoginClicked = vm::onLoginClicked,
|
||||
onPrivacyPolicyClicked = vm::onPrivacyPolicyClicked,
|
||||
onTermsOfUseClicked = vm::onTermsOfUseClicked,
|
||||
joinState = vm.joinFlowState.collectAsStateWithLifecycle().value
|
||||
onTermsOfUseClicked = vm::onTermsOfUseClicked
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -64,8 +60,7 @@ fun AuthScreen(
|
|||
onJoinClicked: () -> Unit,
|
||||
onLoginClicked: () -> Unit,
|
||||
onPrivacyPolicyClicked: () -> Unit,
|
||||
onTermsOfUseClicked: () -> Unit,
|
||||
joinState: OnboardingAuthViewModel.JoinFlowState
|
||||
onTermsOfUseClicked: () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
|
@ -80,8 +75,7 @@ fun AuthScreen(
|
|||
) {
|
||||
SignButtons(
|
||||
onJoinClicked = onJoinClicked,
|
||||
onLoginClicked = onLoginClicked,
|
||||
joinFlowState = joinState
|
||||
onLoginClicked = onLoginClicked
|
||||
)
|
||||
TermsAndPolicy(
|
||||
modifier = Modifier,
|
||||
|
@ -129,13 +123,12 @@ fun Description(modifier: Modifier = Modifier) {
|
|||
fun SignButtons(
|
||||
onJoinClicked: () -> Unit,
|
||||
onLoginClicked: () -> Unit,
|
||||
joinFlowState: OnboardingAuthViewModel.JoinFlowState
|
||||
) {
|
||||
Row {
|
||||
OnBoardingButtonPrimary(
|
||||
text = stringResource(id = R.string.onboarding_join),
|
||||
onClick = onJoinClicked,
|
||||
enabled = joinFlowState is OnboardingAuthViewModel.JoinFlowState.Active,
|
||||
enabled = true,
|
||||
size = ButtonSize.Large,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
|
|
|
@ -7,11 +7,14 @@ 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.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
@ -22,13 +25,17 @@ import com.anytypeio.anytype.core_ui.views.ButtonSize
|
|||
import com.anytypeio.anytype.core_ui.views.HeadlineOnBoardingDescription
|
||||
import com.anytypeio.anytype.core_ui.views.OnBoardingButtonPrimary
|
||||
import com.anytypeio.anytype.core_ui.views.Title1
|
||||
import com.anytypeio.anytype.presentation.common.ScreenState
|
||||
|
||||
|
||||
@Composable
|
||||
fun VoidScreenWrapper(
|
||||
screenState: ScreenState,
|
||||
contentPaddingTop: Int,
|
||||
onNextClicked: () -> Unit
|
||||
) {
|
||||
VoidScreen(
|
||||
screenState = screenState,
|
||||
onNextClicked = onNextClicked,
|
||||
contentPaddingTop = contentPaddingTop
|
||||
)
|
||||
|
@ -36,6 +43,7 @@ fun VoidScreenWrapper(
|
|||
|
||||
@Composable
|
||||
fun VoidScreen(
|
||||
screenState: ScreenState,
|
||||
onNextClicked: () -> Unit,
|
||||
contentPaddingTop: Int
|
||||
) {
|
||||
|
@ -50,15 +58,29 @@ fun VoidScreen(
|
|||
Spacer(modifier = Modifier.height(12.dp))
|
||||
VoidDescription()
|
||||
}
|
||||
OnBoardingButtonPrimary(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 24.dp)
|
||||
.align(Alignment.BottomCenter),
|
||||
text = stringResource(id = R.string.next),
|
||||
onClick = { onNextClicked() },
|
||||
size = ButtonSize.Large
|
||||
)
|
||||
.align(Alignment.BottomCenter)
|
||||
) {
|
||||
OnBoardingButtonPrimary(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.next),
|
||||
onClick = { onNextClicked() },
|
||||
size = ButtonSize.Large
|
||||
)
|
||||
if (screenState is ScreenState.Loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterEnd)
|
||||
.padding(end = 20.dp)
|
||||
.size(18.dp),
|
||||
color = colorResource(R.color.shape_secondary),
|
||||
strokeWidth = 1.5.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.anytypeio.anytype.presentation.common
|
||||
|
||||
sealed class ScreenState {
|
||||
object Idle: ScreenState()
|
||||
object Loading: ScreenState()
|
||||
object Success: ScreenState()
|
||||
data class Failure(val msg: String): ScreenState()
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.anytypeio.anytype.presentation.onboarding
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class OnboardingStartViewModel @Inject constructor(
|
||||
private val analytics: Analytics
|
||||
) : ViewModel() {
|
||||
|
||||
// TODO send analytics.
|
||||
|
||||
val sideEffects = MutableSharedFlow<SideEffect>()
|
||||
val navigation: MutableSharedFlow<AuthNavigation> = MutableSharedFlow()
|
||||
|
||||
fun onJoinClicked() {
|
||||
navigateTo(AuthNavigation.ProceedWithSignUp)
|
||||
}
|
||||
|
||||
fun onLoginClicked() {
|
||||
navigateTo(AuthNavigation.ProceedWithSignIn)
|
||||
}
|
||||
|
||||
fun onPrivacyPolicyClicked() {
|
||||
viewModelScope.launch { sideEffects.emit(SideEffect.OpenPrivacyPolicy) }
|
||||
}
|
||||
|
||||
fun onTermsOfUseClicked() {
|
||||
viewModelScope.launch { sideEffects.emit(SideEffect.OpenTermsOfUse) }
|
||||
}
|
||||
|
||||
private fun navigateTo(destination: AuthNavigation) {
|
||||
viewModelScope.launch {
|
||||
navigation.emit(destination)
|
||||
}
|
||||
}
|
||||
|
||||
interface AuthNavigation {
|
||||
object ProceedWithSignUp : AuthNavigation
|
||||
object ProceedWithSignIn : AuthNavigation
|
||||
}
|
||||
|
||||
sealed class SideEffect {
|
||||
object OpenPrivacyPolicy : SideEffect()
|
||||
object OpenTermsOfUse : SideEffect()
|
||||
}
|
||||
|
||||
class Factory @Inject constructor(
|
||||
private val analytics: Analytics
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return OnboardingStartViewModel(
|
||||
analytics = analytics
|
||||
) as T
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.anytypeio.anytype.presentation.onboarding
|
||||
package com.anytypeio.anytype.presentation.onboarding.signup
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
@ -10,15 +10,16 @@ import com.anytypeio.anytype.domain.device.PathProvider
|
|||
import com.anytypeio.anytype.domain.`object`.SetupMobileUseCaseSkip
|
||||
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
|
||||
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.common.ScreenState
|
||||
import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
class OnboardingAuthViewModel @Inject constructor(
|
||||
class OnboardingVoidViewModel @Inject constructor(
|
||||
private val createAccount: CreateAccount,
|
||||
private val setupWallet: SetupWallet,
|
||||
private val setupMobileUseCaseSkip: SetupMobileUseCaseSkip,
|
||||
|
@ -26,33 +27,21 @@ class OnboardingAuthViewModel @Inject constructor(
|
|||
private val spaceGradientProvider: SpaceGradientProvider,
|
||||
private val relationsSubscriptionManager: RelationsSubscriptionManager,
|
||||
private val objectTypesSubscriptionManager: ObjectTypesSubscriptionManager
|
||||
) : ViewModel() {
|
||||
): BaseViewModel() {
|
||||
|
||||
val sideEffects = MutableSharedFlow<SideEffect>()
|
||||
val state = MutableStateFlow<ScreenState>(ScreenState.Idle)
|
||||
val navigation = MutableSharedFlow<Navigation>()
|
||||
|
||||
private val _navigationFlow = MutableSharedFlow<AuthNavigation>()
|
||||
val navigationFlow: SharedFlow<AuthNavigation> = _navigationFlow
|
||||
|
||||
val joinFlowState = MutableStateFlow<JoinFlowState>(JoinFlowState.Active)
|
||||
|
||||
fun onJoinClicked() {
|
||||
joinFlowState.value = JoinFlowState.Loading
|
||||
proceedWithCreatingWallet()
|
||||
}
|
||||
|
||||
fun onLoginClicked() {
|
||||
navigateTo(AuthNavigation.ProceedWithSignIn)
|
||||
}
|
||||
|
||||
fun onPrivacyPolicyClicked() {
|
||||
viewModelScope.launch { sideEffects.emit(SideEffect.OpenPrivacyPolicy) }
|
||||
}
|
||||
|
||||
fun onTermsOfUseClicked() {
|
||||
viewModelScope.launch { sideEffects.emit(SideEffect.OpenTermsOfUse) }
|
||||
fun onNextClicked() {
|
||||
if (state.value !is ScreenState.Loading) {
|
||||
proceedWithCreatingWallet()
|
||||
} else {
|
||||
sendToast(LOADING_MSG)
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithCreatingWallet() {
|
||||
state.value = ScreenState.Loading
|
||||
setupWallet.invoke(
|
||||
scope = viewModelScope,
|
||||
params = SetupWallet.Params(
|
||||
|
@ -88,47 +77,51 @@ class OnboardingAuthViewModel @Inject constructor(
|
|||
// sendAuthEvent(startTime)
|
||||
relationsSubscriptionManager.onStart()
|
||||
objectTypesSubscriptionManager.onStart()
|
||||
joinFlowState.value = JoinFlowState.Active
|
||||
setupUseCase()
|
||||
proceedWithSettingUpMobileUseCase()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupUseCase() {
|
||||
private fun proceedWithSettingUpMobileUseCase() {
|
||||
viewModelScope.launch {
|
||||
setupMobileUseCaseSkip.execute(Unit).fold(
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while importing use case")
|
||||
navigateTo(AuthNavigation.ProceedWithSignUp)
|
||||
state.value = ScreenState.Success
|
||||
navigation.emit(Navigation.NavigateToMnemonic)
|
||||
},
|
||||
onSuccess = {
|
||||
navigateTo(AuthNavigation.ProceedWithSignUp)
|
||||
state.value = ScreenState.Success
|
||||
navigation.emit(Navigation.NavigateToMnemonic)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateTo(destination: AuthNavigation) {
|
||||
viewModelScope.launch {
|
||||
_navigationFlow.emit(destination)
|
||||
fun onSystemBackPressed() {
|
||||
resolveBackNavigation()
|
||||
}
|
||||
|
||||
fun onBackPressed() {
|
||||
resolveBackNavigation()
|
||||
}
|
||||
|
||||
private fun resolveBackNavigation() {
|
||||
if (state.value !is ScreenState.Loading) {
|
||||
viewModelScope.launch {
|
||||
navigation.emit(
|
||||
Navigation.GoBack
|
||||
)
|
||||
}
|
||||
} else {
|
||||
sendToast(LOADING_MSG)
|
||||
}
|
||||
}
|
||||
|
||||
interface AuthNavigation {
|
||||
object Idle : AuthNavigation
|
||||
object ProceedWithSignUp : AuthNavigation
|
||||
object ProceedWithSignIn : AuthNavigation
|
||||
}
|
||||
|
||||
sealed class SideEffect {
|
||||
object OpenPrivacyPolicy : SideEffect()
|
||||
object OpenTermsOfUse : SideEffect()
|
||||
}
|
||||
|
||||
interface JoinFlowState {
|
||||
object Active : JoinFlowState
|
||||
object Loading : JoinFlowState
|
||||
sealed class Navigation {
|
||||
object NavigateToMnemonic: Navigation()
|
||||
object GoBack: Navigation()
|
||||
}
|
||||
|
||||
class Factory @Inject constructor(
|
||||
|
@ -142,7 +135,7 @@ class OnboardingAuthViewModel @Inject constructor(
|
|||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return OnboardingAuthViewModel(
|
||||
return OnboardingVoidViewModel(
|
||||
createAccount = createAccount,
|
||||
setupWallet = setupWallet,
|
||||
setupMobileUseCaseSkip = setupMobileUseCaseSkip,
|
||||
|
@ -153,4 +146,8 @@ class OnboardingAuthViewModel @Inject constructor(
|
|||
) as T
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LOADING_MSG = "Loading, please wait."
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue