mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3554 Use cases | Enhancement | Automatically open a specific object when a new space is created or account is created (#2363)
This commit is contained in:
parent
fd10386b90
commit
bcbb8368e7
17 changed files with 219 additions and 57 deletions
|
@ -30,6 +30,7 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
|
@ -48,6 +49,7 @@ import androidx.compose.ui.platform.LocalDensity
|
|||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.os.bundleOf
|
||||
|
@ -58,17 +60,21 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.navArgument
|
||||
import androidx.navigation.navOptions
|
||||
import com.anytypeio.anytype.BuildConfig.USE_EDGE_TO_EDGE
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.NO_VALUE
|
||||
import com.anytypeio.anytype.core_ui.BuildConfig.LIBRARY_PACKAGE_NAME
|
||||
import com.anytypeio.anytype.core_ui.MNEMONIC_WORD_COUNT
|
||||
import com.anytypeio.anytype.core_ui.MnemonicPhrasePaletteColors
|
||||
import com.anytypeio.anytype.core_ui.foundation.GenericAlert
|
||||
import com.anytypeio.anytype.core_ui.views.BaseAlertDialog
|
||||
import com.anytypeio.anytype.core_utils.ext.argOrNull
|
||||
import com.anytypeio.anytype.core_utils.ext.shareFirstFileFromPath
|
||||
|
@ -83,6 +89,8 @@ import com.anytypeio.anytype.presentation.onboarding.OnboardingViewModel
|
|||
import com.anytypeio.anytype.presentation.onboarding.login.OnboardingMnemonicLoginViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingMnemonicViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingSetProfileNameViewModel
|
||||
import com.anytypeio.anytype.ui.editor.EditorFragment
|
||||
import com.anytypeio.anytype.ui.home.HomeScreenFragment
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.AuthScreenWrapper
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.signin.RecoveryScreenWrapper
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.signup.MnemonicPhraseScreenWrapper
|
||||
|
@ -285,7 +293,15 @@ class OnboardingFragment : Fragment() {
|
|||
Recovery(navController)
|
||||
}
|
||||
composable(
|
||||
route = OnboardingNavigation.mnemonic,
|
||||
route = "${OnboardingNavigation.mnemonic}?$ONBOARDING_SPACE_PARAM={$ONBOARDING_SPACE_PARAM}&$ONBOARDING_STARTING_OBJECT_PARAM={$ONBOARDING_STARTING_OBJECT_PARAM}",
|
||||
arguments = listOf(
|
||||
navArgument(ONBOARDING_SPACE_PARAM) { type = NavType.StringType },
|
||||
navArgument(ONBOARDING_STARTING_OBJECT_PARAM) {
|
||||
type = NavType.StringType
|
||||
nullable = true
|
||||
defaultValue = null
|
||||
}
|
||||
),
|
||||
enterTransition = {
|
||||
when (initialState.destination.route) {
|
||||
OnboardingNavigation.setProfileName -> {
|
||||
|
@ -311,9 +327,25 @@ class OnboardingFragment : Fragment() {
|
|||
backButtonCallback.value = {
|
||||
// Do nothing
|
||||
}
|
||||
Mnemonic(
|
||||
mnemonicColorPalette = mnemonicColorPalette
|
||||
)
|
||||
val spaceId = it.arguments?.getString(ONBOARDING_SPACE_PARAM)
|
||||
val startingObjectId = it.arguments?.getString(ONBOARDING_STARTING_OBJECT_PARAM)
|
||||
if (!spaceId.isNullOrEmpty()) {
|
||||
Mnemonic(
|
||||
mnemonicColorPalette = mnemonicColorPalette,
|
||||
space = spaceId,
|
||||
startingObject = startingObjectId
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_error_while_creating_account_space_is_missing),
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
BackHandler {
|
||||
toast("You're just one step away from finishing this registration.")
|
||||
}
|
||||
|
@ -511,8 +543,13 @@ class OnboardingFragment : Fragment() {
|
|||
focusManager.clearFocus(force = true)
|
||||
delay(KEYBOARD_HIDE_DELAY)
|
||||
}
|
||||
val space = command.space
|
||||
val startingObject = command.startingObject
|
||||
navController.navigate(
|
||||
route = OnboardingNavigation.mnemonic
|
||||
route = buildString {
|
||||
append("${OnboardingNavigation.mnemonic}?$ONBOARDING_SPACE_PARAM=${space.id}")
|
||||
startingObject?.let { append("&$ONBOARDING_STARTING_OBJECT_PARAM=${it}") }
|
||||
}
|
||||
)
|
||||
}
|
||||
is OnboardingSetProfileNameViewModel.Navigation.GoBack -> {
|
||||
|
@ -533,11 +570,15 @@ class OnboardingFragment : Fragment() {
|
|||
|
||||
@Composable
|
||||
private fun Mnemonic(
|
||||
mnemonicColorPalette: List<Color>
|
||||
mnemonicColorPalette: List<Color>,
|
||||
space: Id,
|
||||
startingObject: Id?
|
||||
) {
|
||||
val component = componentManager().onboardingMnemonicComponent
|
||||
val vm = daggerViewModel { component.get().getViewModel() }
|
||||
MnemonicPhraseScreenWrapper(
|
||||
space = space,
|
||||
startingObject = startingObject,
|
||||
viewModel = vm,
|
||||
copyMnemonicToClipboard = ::copyMnemonicToClipboard,
|
||||
vm = vm,
|
||||
|
@ -559,6 +600,30 @@ class OnboardingFragment : Fragment() {
|
|||
Timber.e(it, "Error while navigation to vault")
|
||||
}
|
||||
}
|
||||
is OnboardingMnemonicViewModel.Command.OpenStartingObject -> {
|
||||
runCatching {
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenVault,
|
||||
VaultFragment.args(deepLink)
|
||||
)
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = command.space.id,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
findNavController().navigate(
|
||||
R.id.objectNavigation,
|
||||
EditorFragment.args(
|
||||
ctx = command.startingObject,
|
||||
space = command.space.id,
|
||||
)
|
||||
)
|
||||
}.onFailure {
|
||||
Timber.e(it, "Error while navigation to vault")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -704,6 +769,9 @@ class OnboardingFragment : Fragment() {
|
|||
ONBOARDING_DEEP_LINK_KEY to deepLink
|
||||
)
|
||||
private const val ONBOARDING_DEEP_LINK_KEY = "arg.onboarding.deep-link-key"
|
||||
|
||||
private const val ONBOARDING_SPACE_PARAM = "space"
|
||||
private const val ONBOARDING_STARTING_OBJECT_PARAM = "startingObject"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ 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_models.Id
|
||||
import com.anytypeio.anytype.core_ui.ColorBackgroundField
|
||||
import com.anytypeio.anytype.core_ui.ColorButtonRegular
|
||||
import com.anytypeio.anytype.core_ui.OnBoardingTextPrimaryColor
|
||||
|
@ -52,6 +53,8 @@ import com.anytypeio.anytype.ui.onboarding.MnemonicStub
|
|||
|
||||
@Composable
|
||||
fun MnemonicPhraseScreenWrapper(
|
||||
space: Id,
|
||||
startingObject: Id?,
|
||||
viewModel: OnboardingMnemonicViewModel,
|
||||
copyMnemonicToClipboard: (String) -> Unit,
|
||||
vm: OnboardingMnemonicViewModel,
|
||||
|
@ -61,10 +64,20 @@ fun MnemonicPhraseScreenWrapper(
|
|||
MnemonicPhraseScreen(
|
||||
state = state,
|
||||
reviewMnemonic = { viewModel.openMnemonic() },
|
||||
onCheckLaterClicked = vm::onCheckLaterClicked,
|
||||
onCheckLaterClicked = {
|
||||
vm.onCheckLaterClicked(
|
||||
space = space,
|
||||
startingObject = startingObject
|
||||
)
|
||||
},
|
||||
copyMnemonicToClipboard = copyMnemonicToClipboard,
|
||||
mnemonicColorPalette = mnemonicColorPalette,
|
||||
onGoToAppClicked = vm::onGoToTheAppClicked
|
||||
onGoToAppClicked = {
|
||||
vm.onGoToTheAppClicked(
|
||||
space = space,
|
||||
startingObject = startingObject
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.anytypeio.anytype.core_utils.ext.toast
|
|||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
import com.anytypeio.anytype.presentation.spaces.CreateSpaceViewModel
|
||||
import com.anytypeio.anytype.ui.editor.EditorFragment
|
||||
import com.anytypeio.anytype.ui.home.HomeScreenFragment
|
||||
import com.anytypeio.anytype.ui.settings.typography
|
||||
import javax.inject.Inject
|
||||
|
@ -63,6 +64,17 @@ class CreateSpaceFragment : BaseBottomSheetComposeFragment() {
|
|||
deeplink = null
|
||||
)
|
||||
)
|
||||
command.startingObject
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.let { startingObject ->
|
||||
findNavController().navigate(
|
||||
R.id.objectNavigation,
|
||||
EditorFragment.args(
|
||||
ctx = startingObject,
|
||||
space = command.space.id
|
||||
)
|
||||
)
|
||||
}
|
||||
}.onFailure {
|
||||
Timber.e(it, "Error while exiting to vault or opening created space")
|
||||
}
|
||||
|
|
|
@ -482,6 +482,7 @@
|
|||
app:enterAnim="@anim/fade_in"
|
||||
app:popUpTo="@id/authStartScreen"
|
||||
app:popUpToInclusive="true" />
|
||||
|
||||
</navigation>
|
||||
|
||||
<fragment
|
||||
|
|
|
@ -478,7 +478,18 @@ sealed class Command {
|
|||
val details: Struct,
|
||||
val withChat: Boolean,
|
||||
val shouldApplyEmptyUseCase: Boolean
|
||||
)
|
||||
) {
|
||||
data class Result(
|
||||
val space: SpaceId,
|
||||
val startingObject: Id? = null
|
||||
)
|
||||
}
|
||||
|
||||
data object ImportUseCase {
|
||||
data class Result(
|
||||
val startingObject: Id? = null
|
||||
)
|
||||
}
|
||||
|
||||
data class CreateObjectType(
|
||||
val details: Struct,
|
||||
|
|
|
@ -244,7 +244,7 @@ class BlockDataRepository(
|
|||
Undo.Result.Exhausted
|
||||
}
|
||||
|
||||
override suspend fun importGetStartedUseCase(space: Id) = remote.importGetStartedUseCase(space = space)
|
||||
override suspend fun importGetStartedUseCase(space: Id): Command.ImportUseCase.Result = remote.importGetStartedUseCase(space = space)
|
||||
|
||||
override suspend fun redo(
|
||||
command: Command.Redo
|
||||
|
@ -761,7 +761,7 @@ class BlockDataRepository(
|
|||
remote.deleteSpace(space)
|
||||
}
|
||||
|
||||
override suspend fun createWorkspace(command: Command.CreateSpace): Id = remote.createWorkspace(
|
||||
override suspend fun createWorkspace(command: Command.CreateSpace): Command.CreateSpace.Result = remote.createWorkspace(
|
||||
command = command
|
||||
)
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ interface BlockRemote {
|
|||
suspend fun createBookmarkObject(space: Id, url: Url, details: Struct): Id
|
||||
suspend fun fetchBookmarkObject(ctx: Id, url: Url)
|
||||
suspend fun undo(command: Command.Undo): Payload
|
||||
suspend fun importGetStartedUseCase(space: Id)
|
||||
suspend fun importGetStartedUseCase(space: Id) : Command.ImportUseCase.Result
|
||||
suspend fun redo(command: Command.Redo): Payload
|
||||
suspend fun turnIntoDocument(command: Command.TurnIntoDocument): List<Id>
|
||||
suspend fun paste(command: Command.Paste): Response.Clipboard.Paste
|
||||
|
@ -340,7 +340,7 @@ interface BlockRemote {
|
|||
suspend fun setSpaceDetails(space: SpaceId, details: Struct)
|
||||
|
||||
suspend fun deleteSpace(space: SpaceId)
|
||||
suspend fun createWorkspace(command: Command.CreateSpace): Id
|
||||
suspend fun createWorkspace(command: Command.CreateSpace): Command.CreateSpace.Result
|
||||
|
||||
suspend fun getSpaceConfig(space: Id): Config
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ interface BlockRepository {
|
|||
|
||||
suspend fun undo(command: Command.Undo): Undo.Result
|
||||
|
||||
suspend fun importGetStartedUseCase(space: Id)
|
||||
suspend fun importGetStartedUseCase(space: Id): Command.ImportUseCase.Result
|
||||
|
||||
suspend fun redo(command: Command.Redo): Redo.Result
|
||||
|
||||
|
@ -392,7 +392,7 @@ interface BlockRepository {
|
|||
): Payload
|
||||
|
||||
suspend fun deleteSpace(space: SpaceId)
|
||||
suspend fun createWorkspace(command: Command.CreateSpace): Id
|
||||
suspend fun createWorkspace(command: Command.CreateSpace): Command.CreateSpace.Result
|
||||
suspend fun getSpaceConfig(space: Id): Config
|
||||
suspend fun addObjectListToSpace(objects: List<Id>, space: Id) : List<Id>
|
||||
suspend fun addObjectToSpace(command: Command.AddObjectToSpace) : Pair<Id, Struct?>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.domain.`object`
|
||||
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
|
@ -8,10 +9,10 @@ import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
|||
class ImportGetStartedUseCase(
|
||||
private val repo: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
): ResultInteractor<ImportGetStartedUseCase.Params, Unit>(dispatchers.io) {
|
||||
): ResultInteractor<ImportGetStartedUseCase.Params, Command.ImportUseCase.Result>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Params) {
|
||||
repo.importGetStartedUseCase(params.space)
|
||||
override suspend fun doWork(params: Params): Command.ImportUseCase.Result {
|
||||
return repo.importGetStartedUseCase(params.space)
|
||||
}
|
||||
|
||||
data class Params(val space: Id)
|
||||
|
|
|
@ -11,9 +11,9 @@ import javax.inject.Inject
|
|||
class CreateSpace @Inject constructor(
|
||||
private val repo: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<CreateSpace.Params, Id>(dispatchers.io) {
|
||||
) : ResultInteractor<CreateSpace.Params, Command.CreateSpace.Result>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Params): Id = repo.createWorkspace(
|
||||
override suspend fun doWork(params: Params) = repo.createWorkspace(
|
||||
command = Command.CreateSpace(
|
||||
details = params.details,
|
||||
withChat = params.withChat,
|
||||
|
|
|
@ -28,13 +28,11 @@ import com.anytypeio.anytype.gallery_experience.models.GalleryInstallationNaviga
|
|||
import com.anytypeio.anytype.gallery_experience.models.GalleryInstallationSpacesState
|
||||
import com.anytypeio.anytype.gallery_experience.models.GalleryInstallationState
|
||||
import com.anytypeio.anytype.gallery_experience.models.GallerySpaceView
|
||||
import com.anytypeio.anytype.presentation.spaces.CreateSpaceViewModel.Companion.MAX_SPACE_COUNT_WITH_GET_STARTED_USE_CASE
|
||||
import com.anytypeio.anytype.presentation.spaces.SelectSpaceViewModel
|
||||
import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider
|
||||
import com.anytypeio.anytype.presentation.spaces.spaceIcon
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -132,12 +130,11 @@ class GalleryInstallationViewModel(
|
|||
Relations.NAME to manifestInfo.title,
|
||||
Relations.ICON_OPTION to spaceGradientProvider.randomId().toDouble()
|
||||
),
|
||||
shouldApplyEmptyUseCase = spacesViewState.value.spaces.count { item ->
|
||||
item.obj.isActive
|
||||
} >= MAX_SPACE_COUNT_WITH_GET_STARTED_USE_CASE
|
||||
shouldApplyEmptyUseCase = true
|
||||
)
|
||||
createSpace.async(params).fold(
|
||||
onSuccess = { space ->
|
||||
onSuccess = { result ->
|
||||
val space = result.space.id
|
||||
Timber.d("CreateSpace success, space: $space")
|
||||
analytics.sendEvent(
|
||||
eventName = EventsDictionary.clickGalleryInstallSpace,
|
||||
|
|
|
@ -2042,5 +2042,6 @@ Please provide specific details of your needs here.</string>
|
|||
<string name="space_properties_screen_section_my_types">My Properties</string>
|
||||
<string name="space_properties_screen_section_system_types">System Properties</string>
|
||||
<string name="space_properties_screen_menu_move_to_bin">Move to bin</string>
|
||||
<string name="onboarding_error_while_creating_account_space_is_missing">Error while creating account: space is missing</string>
|
||||
|
||||
</resources>
|
|
@ -214,7 +214,7 @@ class BlockMiddleware(
|
|||
|
||||
override suspend fun importGetStartedUseCase(
|
||||
space: Id
|
||||
) = middleware.objectImportUseCaseGetStarted(
|
||||
): Command.ImportUseCase.Result = middleware.objectImportUseCaseGetStarted(
|
||||
space = space
|
||||
)
|
||||
|
||||
|
@ -728,7 +728,7 @@ class BlockMiddleware(
|
|||
middleware.spaceDelete(space)
|
||||
}
|
||||
|
||||
override suspend fun createWorkspace(command: Command.CreateSpace): Id = middleware.workspaceCreate(
|
||||
override suspend fun createWorkspace(command: Command.CreateSpace): Command.CreateSpace.Result = middleware.workspaceCreate(
|
||||
command = command
|
||||
)
|
||||
|
||||
|
|
|
@ -1598,14 +1598,17 @@ class Middleware @Inject constructor(
|
|||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun objectImportUseCaseGetStarted(space: Id) {
|
||||
fun objectImportUseCaseGetStarted(space: Id) : Command.ImportUseCase.Result {
|
||||
val request = Rpc.Object.ImportUseCase.Request(
|
||||
spaceId = space,
|
||||
useCase = Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED
|
||||
useCase = Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED_MOBILE
|
||||
)
|
||||
logRequestIfDebug(request)
|
||||
val (response, time) = measureTimedValue { service.objectImportUseCase(request) }
|
||||
logResponseIfDebug(response, time)
|
||||
return Command.ImportUseCase.Result(
|
||||
startingObject = response.startingObjectId.ifEmpty { null }
|
||||
)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
|
@ -1960,19 +1963,22 @@ class Middleware @Inject constructor(
|
|||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun workspaceCreate(command: Command.CreateSpace): Id {
|
||||
fun workspaceCreate(command: Command.CreateSpace): Command.CreateSpace.Result {
|
||||
val request = Rpc.Workspace.Create.Request(
|
||||
details = command.details,
|
||||
useCase = if (command.shouldApplyEmptyUseCase)
|
||||
Rpc.Object.ImportUseCase.Request.UseCase.EMPTY
|
||||
Rpc.Object.ImportUseCase.Request.UseCase.EMPTY_MOBILE
|
||||
else
|
||||
Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED,
|
||||
Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED_MOBILE,
|
||||
withChat = command.withChat
|
||||
)
|
||||
logRequestIfDebug(request)
|
||||
val (response, time) = measureTimedValue { service.workspaceCreate(request) }
|
||||
logResponseIfDebug(response, time)
|
||||
return response.spaceId
|
||||
return Command.CreateSpace.Result(
|
||||
space = SpaceId(response.spaceId),
|
||||
startingObject = response.startingObjectId.ifEmpty { null }
|
||||
)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
|
|
|
@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetMnemonic
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsOnboardingClickEvent
|
||||
|
@ -46,7 +48,10 @@ class OnboardingMnemonicViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
fun onCheckLaterClicked() {
|
||||
fun onCheckLaterClicked(
|
||||
space: Id,
|
||||
startingObject: Id?,
|
||||
) {
|
||||
viewModelScope.sendAnalyticsOnboardingClickEvent(
|
||||
analytics = analytics,
|
||||
type = EventsDictionary.ClickOnboardingButton.CHECK_LATER,
|
||||
|
@ -61,11 +66,23 @@ class OnboardingMnemonicViewModel @Inject constructor(
|
|||
} else {
|
||||
Timber.w("config was missing before the end of onboarding")
|
||||
}
|
||||
commands.emit(Command.OpenVault)
|
||||
if (!startingObject.isNullOrEmpty()) {
|
||||
commands.emit(
|
||||
Command.OpenStartingObject(
|
||||
space = SpaceId(space),
|
||||
startingObject = startingObject
|
||||
)
|
||||
)
|
||||
} else {
|
||||
commands.emit(Command.OpenVault)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onGoToTheAppClicked() {
|
||||
fun onGoToTheAppClicked(
|
||||
space: Id,
|
||||
startingObject: Id?,
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
val config = configStorage.getOrNull()
|
||||
if (config != null) {
|
||||
|
@ -75,7 +92,16 @@ class OnboardingMnemonicViewModel @Inject constructor(
|
|||
} else {
|
||||
Timber.w("config was missing before the end of onboarding")
|
||||
}
|
||||
commands.emit(Command.OpenVault)
|
||||
if (!startingObject.isNullOrEmpty()) {
|
||||
commands.emit(
|
||||
Command.OpenStartingObject(
|
||||
space = SpaceId(space),
|
||||
startingObject = startingObject
|
||||
)
|
||||
)
|
||||
} else {
|
||||
commands.emit(Command.OpenVault)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,5 +141,9 @@ class OnboardingMnemonicViewModel @Inject constructor(
|
|||
|
||||
sealed class Command {
|
||||
data object OpenVault : Command()
|
||||
data class OpenStartingObject(
|
||||
val space: SpaceId,
|
||||
val startingObject: Id
|
||||
) : Command()
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ import com.anytypeio.anytype.domain.`object`.ImportGetStartedUseCase
|
|||
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
|
||||
import com.anytypeio.anytype.domain.spaces.SetSpaceDetails
|
||||
import com.anytypeio.anytype.domain.subscriptions.GlobalSubscriptionManager
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.extension.proceedWithAccountEvent
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsOnboardingScreenEvent
|
||||
|
@ -44,7 +45,8 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
private val spaceGradientProvider: SpaceGradientProvider,
|
||||
private val crashReporter: CrashReporter,
|
||||
private val localeProvider: LocaleProvider,
|
||||
private val globalSubscriptionManager: GlobalSubscriptionManager
|
||||
private val globalSubscriptionManager: GlobalSubscriptionManager,
|
||||
private val spaceManager: SpaceManager
|
||||
) : BaseViewModel() {
|
||||
|
||||
init {
|
||||
|
@ -133,6 +135,9 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
val config = configStorage.getOrNull()
|
||||
if (config != null) {
|
||||
crashReporter.setUser(config.analytics)
|
||||
spaceManager.set(config.space).onFailure {
|
||||
Timber.e(it, "Error while setting current space during sign-up onboarding")
|
||||
}
|
||||
setupGlobalSubscriptions()
|
||||
proceedWithSettingUpMobileUseCase(
|
||||
space = config.space,
|
||||
|
@ -153,7 +158,8 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
|
||||
private fun proceedWithSettingAccountName(
|
||||
name: String,
|
||||
spaceName: String
|
||||
spaceName: String,
|
||||
startingObjectId: Id?
|
||||
) {
|
||||
val config = configStorage.getOrNull()
|
||||
if (config != null) {
|
||||
|
@ -176,13 +182,23 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
).fold(
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while setting profile name details")
|
||||
navigation.emit(Navigation.NavigateToMnemonic)
|
||||
navigation.emit(
|
||||
Navigation.NavigateToMnemonic(
|
||||
space = SpaceId(config.space),
|
||||
startingObject = startingObjectId
|
||||
)
|
||||
)
|
||||
// Workaround for leaving screen in loading state to wait screen transition
|
||||
delay(LOADING_AFTER_SUCCESS_DELAY)
|
||||
state.value = ScreenState.Success
|
||||
},
|
||||
onSuccess = {
|
||||
navigation.emit(Navigation.NavigateToMnemonic)
|
||||
navigation.emit(
|
||||
Navigation.NavigateToMnemonic(
|
||||
space = SpaceId(config.space),
|
||||
startingObject = startingObjectId
|
||||
)
|
||||
)
|
||||
// Workaround for leaving screen in loading state to wait screen transition
|
||||
delay(LOADING_AFTER_SUCCESS_DELAY)
|
||||
state.value = ScreenState.Success
|
||||
|
@ -217,13 +233,15 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
onFailure = {
|
||||
proceedWithSettingAccountName(
|
||||
name = name,
|
||||
spaceName = spaceName
|
||||
spaceName = spaceName,
|
||||
startingObjectId = null
|
||||
)
|
||||
},
|
||||
onSuccess = {
|
||||
onSuccess = { result ->
|
||||
proceedWithSettingAccountName(
|
||||
name = name,
|
||||
spaceName = spaceName
|
||||
spaceName = spaceName,
|
||||
startingObjectId = result.startingObject
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -242,7 +260,8 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
private val importGetStartedUseCase: ImportGetStartedUseCase,
|
||||
private val crashReporter: CrashReporter,
|
||||
private val localeProvider: LocaleProvider,
|
||||
private val globalSubscriptionManager: GlobalSubscriptionManager
|
||||
private val globalSubscriptionManager: GlobalSubscriptionManager,
|
||||
private val spaceManager: SpaceManager
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
|
@ -258,7 +277,8 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
spaceGradientProvider = spaceGradientProvider,
|
||||
crashReporter = crashReporter,
|
||||
localeProvider = localeProvider,
|
||||
globalSubscriptionManager = globalSubscriptionManager
|
||||
globalSubscriptionManager = globalSubscriptionManager,
|
||||
spaceManager = spaceManager
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +291,7 @@ class OnboardingSetProfileNameViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
sealed class Navigation {
|
||||
data object NavigateToMnemonic: Navigation()
|
||||
data class NavigateToMnemonic(val space: SpaceId, val startingObject: Id?): Navigation()
|
||||
data object GoBack: Navigation()
|
||||
}
|
||||
|
||||
|
|
|
@ -67,13 +67,14 @@ class CreateSpaceViewModel(
|
|||
Relations.NAME to name,
|
||||
Relations.ICON_OPTION to spaceIconView.value.color.index.toDouble()
|
||||
),
|
||||
shouldApplyEmptyUseCase = numberOfActiveSpaces >= MAX_SPACE_COUNT_WITH_GET_STARTED_USE_CASE,
|
||||
shouldApplyEmptyUseCase = true,
|
||||
withChat = BuildConfig.DEBUG && isSpaceLevelChatSwitchChecked
|
||||
)
|
||||
).collect { result ->
|
||||
result.fold(
|
||||
onLoading = { isInProgress.value = true },
|
||||
onSuccess = { space: Id ->
|
||||
onSuccess = { response ->
|
||||
val space = response.space.id
|
||||
analytics.sendEvent(
|
||||
eventName = EventsDictionary.createSpace,
|
||||
props = Props(
|
||||
|
@ -83,7 +84,12 @@ class CreateSpaceViewModel(
|
|||
setNewSpaceAsCurrentSpace(space)
|
||||
Timber.d("Successfully created space: $space").also {
|
||||
isInProgress.value = false
|
||||
commands.emit(Command.SwitchSpace(space = Space(space)))
|
||||
commands.emit(
|
||||
Command.SwitchSpace(
|
||||
space = Space(space),
|
||||
startingObject = response.startingObject
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
|
@ -130,12 +136,8 @@ class CreateSpaceViewModel(
|
|||
|
||||
sealed class Command {
|
||||
data class SwitchSpace(
|
||||
val space: Space
|
||||
val space: Space,
|
||||
val startingObject: Id?
|
||||
): Command()
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Always applying "empty" use-case when creating new space
|
||||
const val MAX_SPACE_COUNT_WITH_GET_STARTED_USE_CASE = 0
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue