1
0
Fork 0
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:
Evgenii Kozlov 2025-04-28 15:22:56 +02:00
parent fd10386b90
commit bcbb8368e7
17 changed files with 219 additions and 57 deletions

View file

@ -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()
}
}

View file

@ -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()
}

View file

@ -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
}
}