1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-2731 Vault | Enhancement | Restoring either last opened space or vault (#1528)

This commit is contained in:
Evgenii Kozlov 2024-09-02 15:04:14 +02:00 committed by GitHub
parent fda05fa782
commit 22d78b0727
Signed by: github
GPG key ID: B5690EEEBB952194
15 changed files with 110 additions and 30 deletions

View file

@ -18,7 +18,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.NavOptions
import androidx.navigation.fragment.findNavController
import com.anytypeio.anytype.BuildConfig
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.extensions.throttledClick
@ -103,15 +102,7 @@ class HomeScreenFragment : BaseComposeFragment() {
onClick = { vm.onCreateNewObjectLongClicked() }
),
onProfileClicked = throttledClick(
onClick = {
runCatching {
if (BuildConfig.DEBUG) {
findNavController().navigate(R.id.action_open_vault)
} else {
findNavController().navigate(R.id.action_open_spaces)
}
}
}
onClick = vm::onVaultClicked
),
onSpaceWidgetClicked = throttledClick(
onClick = vm::onSpaceSettingsClicked
@ -329,6 +320,13 @@ class HomeScreenFragment : BaseComposeFragment() {
Timber.e(it, "Error while opening global search screen")
}
}
is Command.OpenVault -> {
runCatching {
findNavController().navigate(R.id.action_open_vault)
}.onFailure {
Timber.e(it, "Error while opening vault from home screen")
}
}
}
}

View file

@ -84,7 +84,7 @@ class SplashFragment : BaseFragment<FragmentSplashBinding>(R.layout.fragment_spl
is SplashViewModel.Command.NavigateToDashboard -> {
try {
findNavController().navigate(
R.id.action_splashScreen_to_vaultScreen,
R.id.action_splashScreen_to_homeScreen,
args = HomeScreenFragment.args(command.deeplink)
)
} catch (e: Exception) {
@ -92,14 +92,15 @@ class SplashFragment : BaseFragment<FragmentSplashBinding>(R.layout.fragment_spl
toast("Error while navigating to desktop: ${e.message}")
}
}
is SplashViewModel.Command.NavigateToWidgets -> {
is SplashViewModel.Command.NavigateToVault -> {
try {
findNavController().navigate(
R.id.action_splashScreen_to_widgets
R.id.action_splashScreen_to_vaultScreen,
args = HomeScreenFragment.args(command.deeplink)
)
} catch (e: Exception) {
Timber.e(e, "Error while opening widgets from splash screen")
toast("Error while navigating to widgets: ${e.message}")
Timber.e(e, "Error while opening dashboard from splash screen")
toast("Error while navigating to desktop: ${e.message}")
}
}
is SplashViewModel.Command.NavigateToObject -> {

View file

@ -202,8 +202,7 @@
android:name="com.anytypeio.anytype.ui.vault.VaultFragment">
<action
android:id="@+id/openSpace"
app:destination="@id/homeScreen"
app:enterAnim="@anim/slide_in_right" />
app:destination="@id/homeScreen" />
</fragment>
<dialog

View file

@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.Flow
interface UserSettingsCache {
suspend fun setCurrentSpace(space: SpaceId)
suspend fun getCurrentSpace(): SpaceId?
suspend fun clearCurrentSpace()
suspend fun setDefaultObjectType(space: SpaceId, type: TypeId)
suspend fun getDefaultObjectType(space: SpaceId): TypeId?

View file

@ -62,6 +62,8 @@ class UserSettingsDataRepository(private val cache: UserSettingsCache) : UserSet
override suspend fun getCurrentSpace(): SpaceId? = cache.getCurrentSpace()
override suspend fun clearCurrentSpace() = cache.clearCurrentSpace()
override suspend fun setLastOpenedObject(id: Id, space: SpaceId) {
cache.setLastOpenedObject(id, space)
}

View file

@ -1,6 +1,5 @@
package com.anytypeio.anytype.domain.auth.interactor
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVFilterCondition
import com.anytypeio.anytype.core_models.Id
@ -50,7 +49,7 @@ class GetLastOpenedObject(
/**
* There was no information about the last opened object.
*/
object Empty : Response()
data object Empty : Response()
/**
* The last opened object could not be found. It might have been deleted.

View file

@ -12,6 +12,7 @@ interface UserSettingsRepository {
suspend fun setCurrentSpace(space: SpaceId)
suspend fun getCurrentSpace(): SpaceId?
suspend fun clearCurrentSpace()
suspend fun setWallpaper(space: Id, wallpaper: Wallpaper)
suspend fun getWallpaper(space: Id): Wallpaper

View file

@ -0,0 +1,16 @@
package com.anytypeio.anytype.domain.spaces
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.config.UserSettingsRepository
import javax.inject.Inject
class ClearLastOpenedSpace @Inject constructor(
private val repo: UserSettingsRepository,
dispatchers: AppCoroutineDispatchers
): ResultInteractor<Unit, Unit>(dispatchers.io) {
override suspend fun doWork(params: Unit) {
return repo.clearCurrentSpace()
}
}

View file

@ -0,0 +1,17 @@
package com.anytypeio.anytype.domain.spaces
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.config.UserSettingsRepository
import javax.inject.Inject
class GetLastOpenedSpace @Inject constructor(
private val repo: UserSettingsRepository,
dispatchers: AppCoroutineDispatchers
): ResultInteractor<Unit, SpaceId?>(dispatchers.io) {
override suspend fun doWork(params: Unit): SpaceId? {
return repo.getCurrentSpace()
}
}

View file

@ -51,6 +51,12 @@ class DefaultUserSettingsCache(
SpaceId(value)
}
override suspend fun clearCurrentSpace() {
prefs.edit()
.putString(CURRENT_SPACE_KEY, "")
.apply()
}
override suspend fun setDefaultObjectType(space: SpaceId, type: TypeId) {
val curr = prefs
.getString(DEFAULT_OBJECT_TYPES_KEY, NO_VALUE)

View file

@ -60,6 +60,7 @@ import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
import com.anytypeio.anytype.domain.search.SearchObjects
import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace
import com.anytypeio.anytype.domain.spaces.GetSpaceView
import com.anytypeio.anytype.domain.types.GetPinnedObjectTypes
import com.anytypeio.anytype.domain.widgets.CreateWidget
@ -196,7 +197,8 @@ class HomeScreenViewModel(
private val createBlock: CreateBlock,
private val dateProvider: DateProvider,
private val addObjectToCollection: AddObjectToCollection,
private val getLastSearchQuery: GetLastSearchQuery
private val getLastSearchQuery: GetLastSearchQuery,
private val clearLastOpenedSpace: ClearLastOpenedSpace
) : NavigationViewModel<HomeScreenViewModel.Navigation>(),
Reducer<ObjectView, Payload>,
WidgetActiveViewStateHolder by widgetActiveViewStateHolder,
@ -1639,6 +1641,20 @@ class HomeScreenViewModel(
}
}
fun onVaultClicked() {
viewModelScope.launch {
clearLastOpenedSpace.async(Unit).fold(
onSuccess = {
Timber.d("Cleared last opened space before opening vault")
},
onFailure = {
Timber.e(it, "Error while clearing last opened space before opening vault")
}
)
commands.emit(Command.OpenVault)
}
}
override fun onCleared() {
super.onCleared()
Timber.d("onCleared")
@ -2072,7 +2088,8 @@ class HomeScreenViewModel(
private val dateProvider: DateProvider,
private val coverImageHashProvider: CoverImageHashProvider,
private val addObjectToCollection: AddObjectToCollection,
private val getLastSearchQuery: GetLastSearchQuery
private val getLastSearchQuery: GetLastSearchQuery,
private val clearLastOpenedSpace: ClearLastOpenedSpace
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T = HomeScreenViewModel(
@ -2120,7 +2137,8 @@ class HomeScreenViewModel(
createBlock = createBlock,
dateProvider = dateProvider,
addObjectToCollection = addObjectToCollection,
getLastSearchQuery = getLastSearchQuery
getLastSearchQuery = getLastSearchQuery,
clearLastOpenedSpace = clearLastOpenedSpace
) as T
}
@ -2165,6 +2183,8 @@ sealed class Command {
data class OpenGlobalSearchScreen(val initialQuery: String, val space: Id) : Command()
data object OpenVault: Command()
data class SelectWidgetType(
val ctx: Id,
val source: Id,

View file

@ -29,6 +29,7 @@ import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.misc.LocaleProvider
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.spaces.GetLastOpenedSpace
import com.anytypeio.anytype.domain.subscriptions.GlobalSubscriptionManager
import com.anytypeio.anytype.domain.workspace.SpaceManager
import com.anytypeio.anytype.presentation.BuildConfig
@ -56,7 +57,8 @@ class SplashViewModel(
private val localeProvider: LocaleProvider,
private val spaceManager: SpaceManager,
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
private val globalSubscriptionManager: GlobalSubscriptionManager
private val globalSubscriptionManager: GlobalSubscriptionManager,
private val getLastOpenedSpace: GetLastOpenedSpace
) : ViewModel(), AnalyticSpaceHelperDelegate by analyticSpaceHelperDelegate {
val state = MutableStateFlow<ViewState<Any>>(ViewState.Init)
@ -246,7 +248,12 @@ class SplashViewModel(
}
private suspend fun proceedWithDashboardNavigation(deeplink: String? = null) {
commands.emit(Command.NavigateToDashboard(deeplink))
val space = getLastOpenedSpace.async(Unit).getOrNull()
if (space != null) {
commands.emit(Command.NavigateToDashboard(deeplink))
} else {
commands.emit(Command.NavigateToVault(deeplink))
}
}
private fun updateUserProps(id: String) {
@ -275,7 +282,7 @@ class SplashViewModel(
sealed class Command {
data class NavigateToDashboard(val deeplink: String? = null) : Command()
data object NavigateToWidgets : Command()
data class NavigateToVault(val deeplink: String? = null) : Command()
data object NavigateToAuthStart : Command()
data object NavigateToMigration: Command()
data object CheckAppStartIntent : Command()

View file

@ -10,6 +10,7 @@ import com.anytypeio.anytype.domain.auth.interactor.LaunchAccount
import com.anytypeio.anytype.domain.auth.interactor.LaunchWallet
import com.anytypeio.anytype.domain.misc.LocaleProvider
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.spaces.GetLastOpenedSpace
import com.anytypeio.anytype.domain.subscriptions.GlobalSubscriptionManager
import com.anytypeio.anytype.domain.workspace.SpaceManager
import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
@ -31,7 +32,8 @@ class SplashViewModelFactory @Inject constructor(
private val localeProvider: LocaleProvider,
private val spaceManager: SpaceManager,
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
private val globalSubscriptionManager: GlobalSubscriptionManager
private val globalSubscriptionManager: GlobalSubscriptionManager,
private val getLastOpenedSpace: GetLastOpenedSpace
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
@ -47,6 +49,7 @@ class SplashViewModelFactory @Inject constructor(
localeProvider = localeProvider,
spaceManager = spaceManager,
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
globalSubscriptionManager = globalSubscriptionManager
globalSubscriptionManager = globalSubscriptionManager,
getLastOpenedSpace = getLastOpenedSpace
) as T
}

View file

@ -58,6 +58,7 @@ import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
import com.anytypeio.anytype.domain.search.SearchObjects
import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace
import com.anytypeio.anytype.domain.spaces.GetSpaceView
import com.anytypeio.anytype.domain.types.GetPinnedObjectTypes
import com.anytypeio.anytype.domain.widgets.CreateWidget
@ -247,6 +248,9 @@ class HomeScreenViewModelTest {
@Mock
lateinit var getLastSearchQuery: GetLastSearchQuery
@Mock
lateinit var clearLastOpenedSpace: ClearLastOpenedSpace
lateinit var userPermissionProvider: UserPermissionProvider
private val objectPayloadDispatcher = Dispatcher.Default<Payload>()
@ -2944,7 +2948,8 @@ class HomeScreenViewModelTest {
createDataViewObject = createDataViewObject,
dateProvider = dateProvider,
addObjectToCollection = addObjectToCollection,
getLastSearchQuery = getLastSearchQuery
getLastSearchQuery = getLastSearchQuery,
clearLastOpenedSpace = clearLastOpenedSpace
)
companion object {

View file

@ -17,6 +17,7 @@ import com.anytypeio.anytype.domain.config.UserSettingsRepository
import com.anytypeio.anytype.domain.misc.LocaleProvider
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.spaces.GetLastOpenedSpace
import com.anytypeio.anytype.domain.subscriptions.GlobalSubscriptionManager
import com.anytypeio.anytype.domain.workspace.SpaceManager
import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
@ -87,9 +88,12 @@ class SplashViewModelTest {
@Mock
lateinit var analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate
@Mock
lateinit var getLastOpenedSpace: GetLastOpenedSpace
lateinit var vm: SplashViewModel
val defaultSpaceConfig = StubConfig()
private val defaultSpaceConfig = StubConfig()
@Before
fun setup() {
@ -114,7 +118,8 @@ class SplashViewModelTest {
localeProvider = localeProvider,
spaceManager = spaceManager,
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
globalSubscriptionManager = globalSubscriptionManager
globalSubscriptionManager = globalSubscriptionManager,
getLastOpenedSpace = getLastOpenedSpace
)
}