From 6bb9ef1716d90c6949e4e39825c0d37b54f49be7 Mon Sep 17 00:00:00 2001 From: Evgenii Kozlov Date: Thu, 29 Aug 2024 12:38:23 +0200 Subject: [PATCH] DROID-2731 Vault | Tech | Basic behavior (space creation, space switching) (#1516) --- .../anytype/di/feature/vault/VaultDI.kt | 6 + .../anytype/ui/home/HomeScreenFragment.kt | 7 +- .../anytype/ui/vault/VaultFragment.kt | 57 ++++++-- .../anytypeio/anytype/ui/vault/VaultScreen.kt | 100 +++++++++++--- app/src/main/res/navigation/graph.xml | 7 + .../anytype/core_models/Wallpaper.kt | 2 +- .../main/res/drawable/ic_vault_settings.xml | 10 ++ .../data/auth/repo/UserSettingsCache.kt | 1 + .../auth/repo/UserSettingsDataRepository.kt | 4 + .../domain/config/UserSettingsRepository.kt | 1 + .../domain/wallpaper/GetSpaceWallpapers.kt | 18 +++ .../repo/DefaultUserSettingsCache.kt | 12 ++ .../presentation/vault/VaultViewModel.kt | 130 +++++++++++++++++- 13 files changed, 325 insertions(+), 30 deletions(-) create mode 100644 core-ui/src/main/res/drawable/ic_vault_settings.xml create mode 100644 domain/src/main/java/com/anytypeio/anytype/domain/wallpaper/GetSpaceWallpapers.kt diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/vault/VaultDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/vault/VaultDI.kt index 88894df491..55a7c218ff 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/vault/VaultDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/vault/VaultDI.kt @@ -6,7 +6,10 @@ import com.anytypeio.anytype.core_utils.di.scope.PerScreen import com.anytypeio.anytype.di.common.ComponentDependencies import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers import com.anytypeio.anytype.domain.block.repo.BlockRepository +import com.anytypeio.anytype.domain.config.UserSettingsRepository import com.anytypeio.anytype.domain.misc.UrlBuilder +import com.anytypeio.anytype.domain.multiplayer.SpaceViewSubscriptionContainer +import com.anytypeio.anytype.domain.workspace.SpaceManager import com.anytypeio.anytype.presentation.vault.VaultViewModel import com.anytypeio.anytype.ui.vault.VaultFragment import dagger.Binds @@ -48,4 +51,7 @@ interface VaultComponentDependencies : ComponentDependencies { fun appCoroutineDispatchers(): AppCoroutineDispatchers fun analytics(): Analytics fun urlBuilder(): UrlBuilder + fun spaceViewSubscriptionContainer(): SpaceViewSubscriptionContainer + fun userSettingsRepository(): UserSettingsRepository + fun spaceManager(): SpaceManager } \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/ui/home/HomeScreenFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/home/HomeScreenFragment.kt index 16a8502686..2489b10364 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/home/HomeScreenFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/home/HomeScreenFragment.kt @@ -18,6 +18,7 @@ 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 @@ -107,7 +108,11 @@ class HomeScreenFragment : BaseComposeFragment() { onProfileClicked = throttledClick( onClick = { runCatching { - findNavController().navigate(R.id.action_open_spaces) + if (BuildConfig.DEBUG) { + findNavController().navigate(R.id.action_open_vault) + } else { + findNavController().navigate(R.id.action_open_spaces) + } } } ), diff --git a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt index e58122fd00..f98c43f438 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt @@ -4,13 +4,21 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.core.os.bundleOf import androidx.fragment.app.viewModels import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.fragment.findNavController +import com.anytypeio.anytype.R import com.anytypeio.anytype.core_utils.ui.BaseComposeFragment import com.anytypeio.anytype.di.common.componentManager import com.anytypeio.anytype.presentation.vault.VaultViewModel +import com.anytypeio.anytype.presentation.vault.VaultViewModel.Command +import com.anytypeio.anytype.ui.settings.ProfileSettingsFragment +import com.anytypeio.anytype.ui.settings.typography import javax.inject.Inject class VaultFragment : BaseComposeFragment() { @@ -27,18 +35,51 @@ class VaultFragment : BaseComposeFragment() { ): View = ComposeView(requireContext()).apply { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { - VaultScreen( - spaces = vm.spaces.collectAsStateWithLifecycle().value, - onSpaceClicked = { - // TODO - }, - onCreateSpaceClicked = { - // TODO + MaterialTheme(typography = typography) { + VaultScreen( + spaces = vm.spaces.collectAsStateWithLifecycle().value, + onSpaceClicked = vm::onSpaceClicked, + onCreateSpaceClicked = vm::onCreateSpaceClicked, + onSettingsClicked = vm::onSettingsClicked + ) + } + LaunchedEffect(Unit) { + vm.commands.collect { command -> + proceedWithCommand(command) } - ) + } } } + private fun proceedWithCommand(command: Command) { + when (command) { + is Command.EnterSpaceHomeScreen -> { + runCatching { + findNavController().popBackStack() + } + } + is Command.CreateNewSpace -> { + runCatching { + findNavController().navigate( + R.id.createSpaceScreen + ) + } + } + is Command.OpenProfileSettings -> { + runCatching { + findNavController().navigate( + R.id.profileScreen, + bundleOf(ProfileSettingsFragment.SPACE_ID_KEY to command.space.id) + ) + } + } + } + } + + override fun onApplyWindowRootInsets(view: View) { + // TODO Do nothing ? + } + override fun injectDependencies() { componentManager().vaultComponent.get().inject(this) } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt index 0d658f2c41..9c957e3054 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt @@ -1,17 +1,22 @@ package com.anytypeio.anytype.ui.vault import android.content.res.Configuration +import android.os.Build.VERSION.SDK_INT import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets 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.systemBars +import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape @@ -20,6 +25,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource @@ -27,37 +34,56 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.anytypeio.anytype.BuildConfig.USE_EDGE_TO_EDGE import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Relations +import com.anytypeio.anytype.core_models.Wallpaper import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType import com.anytypeio.anytype.core_ui.foundation.noRippleClickable import com.anytypeio.anytype.core_ui.views.BodyBold import com.anytypeio.anytype.core_ui.views.Relations3 import com.anytypeio.anytype.core_ui.views.Title1 +import com.anytypeio.anytype.core_utils.insets.EDGE_TO_EDGE_MIN_SDK +import com.anytypeio.anytype.presentation.editor.cover.CoverGradient import com.anytypeio.anytype.presentation.spaces.SpaceIconView import com.anytypeio.anytype.presentation.vault.VaultViewModel.VaultSpaceView +import com.anytypeio.anytype.presentation.wallpaper.WallpaperColor +import com.anytypeio.anytype.ui.widgets.types.gradient @Composable fun VaultScreen( spaces: List, onSpaceClicked: (VaultSpaceView) -> Unit, - onCreateSpaceClicked: () -> Unit + onCreateSpaceClicked: () -> Unit, + onSettingsClicked: () -> Unit ) { Box( - Modifier.fillMaxSize() + Modifier + .fillMaxSize() + .background( + color = colorResource(id = R.color.background_primary) + ) + .then( + if (USE_EDGE_TO_EDGE && SDK_INT >= EDGE_TO_EDGE_MIN_SDK) + Modifier.windowInsetsPadding(WindowInsets.systemBars) + else + Modifier + ) ) { VaultScreenToolbar( - onPlusClicked = onCreateSpaceClicked + onPlusClicked = onCreateSpaceClicked, + onSettingsClicked = onSettingsClicked ) LazyColumn( - Modifier + modifier = Modifier .fillMaxSize() .padding( top = 48.dp - ) + ), + verticalArrangement = Arrangement.spacedBy(8.dp) ) { items( items = spaces, @@ -73,9 +99,8 @@ fun VaultScreen( SpaceAccessType.SHARED -> stringResource(id = R.string.space_type_shared_space) else -> EMPTY_STRING_VALUE }, - onCardClicked = { - onSpaceClicked(item) - } + wallpaper = item.wallpaper, + onCardClicked = { onSpaceClicked(item) } ) } } @@ -85,7 +110,8 @@ fun VaultScreen( @Composable fun VaultScreenToolbar( - onPlusClicked: () -> Unit + onPlusClicked: () -> Unit, + onSettingsClicked: () -> Unit ) { Box( modifier = Modifier @@ -99,11 +125,14 @@ fun VaultScreenToolbar( modifier = Modifier.align(Alignment.Center) ) Image( - painter = painterResource(id = R.drawable.ic_space_settings), + painter = painterResource(id = R.drawable.ic_vault_settings), contentDescription = "Settings icon", modifier = Modifier .align(Alignment.CenterStart) .padding(start = 16.dp) + .noRippleClickable { + onSettingsClicked() + } ) Image( // TODO change icon @@ -123,13 +152,49 @@ fun VaultScreenToolbar( fun VaultSpaceCard( title: String, subtitle: String, - onCardClicked: () -> Unit + onCardClicked: () -> Unit, + wallpaper: Wallpaper ) { Box( modifier = Modifier .fillMaxWidth() .height(96.dp) .padding(horizontal = 8.dp) + .clip(RoundedCornerShape(20.dp)) + .then( + when(wallpaper) { + is Wallpaper.Color -> { + val color = WallpaperColor.entries.find { + it.code == wallpaper.code + } + if (color != null) { + Modifier.background( + color = Color(Integer.decode(color.hex)), + shape = RoundedCornerShape(20.dp) + ) + } else { + Modifier + } + } + is Wallpaper.Gradient -> { + Modifier.background( + brush = Brush.horizontalGradient( + colors = gradient(wallpaper.code) + ), + shape = RoundedCornerShape(20.dp) + ) + } + is Wallpaper.Default -> { + Modifier.background( + brush = Brush.horizontalGradient( + colors = gradient(CoverGradient.SKY) + ), + shape = RoundedCornerShape(20.dp) + ) + } + else -> Modifier + } + ) .clickable { onCardClicked() } @@ -137,13 +202,13 @@ fun VaultSpaceCard( // TODO render space icon Box( modifier = Modifier + .padding(start = 16.dp) .size(64.dp) .background( - color = Color.Red, + color = Color.White, shape = RoundedCornerShape(8.dp) ) .align(Alignment.CenterStart) - .padding(start = 16.dp) ) Column( modifier = Modifier @@ -177,7 +242,8 @@ fun VaultSpaceCard( @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO, name = "Dark Mode") fun VaultScreenToolbarPreview() { VaultScreenToolbar( - onPlusClicked = {} + onPlusClicked = {}, + onSettingsClicked = {} ) } @@ -188,7 +254,8 @@ fun VaultSpaceCardPreview() { VaultSpaceCard( title = "B&O Museum", subtitle = "Private space", - onCardClicked = {} + onCardClicked = {}, + wallpaper = Wallpaper.Default ) } @@ -211,6 +278,7 @@ fun VaultScreenPreview() { ) }, onSpaceClicked = {}, - onCreateSpaceClicked = {} + onCreateSpaceClicked = {}, + onSettingsClicked = {} ) } diff --git a/app/src/main/res/navigation/graph.xml b/app/src/main/res/navigation/graph.xml index 0948b6d2f2..a2e7c8ad0a 100644 --- a/app/src/main/res/navigation/graph.xml +++ b/app/src/main/res/navigation/graph.xml @@ -158,6 +158,9 @@ + + + diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/Wallpaper.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/Wallpaper.kt index efd5c303d4..35ae0ea9ad 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/Wallpaper.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/Wallpaper.kt @@ -1,7 +1,7 @@ package com.anytypeio.anytype.core_models sealed class Wallpaper { - object Default: Wallpaper() + data object Default: Wallpaper() data class Color(val code: Id) : Wallpaper() data class Gradient(val code: Id) : Wallpaper() data class Image(val hash: Hash) : Wallpaper() diff --git a/core-ui/src/main/res/drawable/ic_vault_settings.xml b/core-ui/src/main/res/drawable/ic_vault_settings.xml new file mode 100644 index 0000000000..7d45437ac6 --- /dev/null +++ b/core-ui/src/main/res/drawable/ic_vault_settings.xml @@ -0,0 +1,10 @@ + + + diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt index 549a9005e3..0d0f089f7f 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt @@ -23,6 +23,7 @@ interface UserSettingsCache { suspend fun setWallpaper(space: Id, wallpaper: Wallpaper) suspend fun getWallpaper(space: Id) : Wallpaper + suspend fun getWallpapers(): Map suspend fun setThemeMode(mode: ThemeMode) suspend fun getThemeMode(): ThemeMode suspend fun getWidgetSession() : WidgetSession diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt index 7c3decff34..013479aadb 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt @@ -17,6 +17,10 @@ class UserSettingsDataRepository(private val cache: UserSettingsCache) : UserSet override suspend fun getWallpaper(space: Id): Wallpaper = cache.getWallpaper(space) + override suspend fun getWallpapers(): Map { + return cache.getWallpapers() + } + override suspend fun setDefaultObjectType( space: SpaceId, type: TypeId diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt b/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt index 2b12287ed1..106eff20c7 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt @@ -15,6 +15,7 @@ interface UserSettingsRepository { suspend fun setWallpaper(space: Id, wallpaper: Wallpaper) suspend fun getWallpaper(space: Id): Wallpaper + suspend fun getWallpapers(): Map suspend fun setDefaultObjectType(space: SpaceId, type: TypeId) suspend fun getDefaultObjectType(space: SpaceId): TypeId? diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/wallpaper/GetSpaceWallpapers.kt b/domain/src/main/java/com/anytypeio/anytype/domain/wallpaper/GetSpaceWallpapers.kt new file mode 100644 index 0000000000..58a85e7d2e --- /dev/null +++ b/domain/src/main/java/com/anytypeio/anytype/domain/wallpaper/GetSpaceWallpapers.kt @@ -0,0 +1,18 @@ +package com.anytypeio.anytype.domain.wallpaper + +import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.Wallpaper +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 GetSpaceWallpapers @Inject constructor( + private val repo: UserSettingsRepository, + private val dispatchers: AppCoroutineDispatchers +) : ResultInteractor>(dispatchers.io) { + + override suspend fun doWork(params: Unit): Map { + return repo.getWallpapers() + } +} \ No newline at end of file diff --git a/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt b/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt index 6fb12743ee..8e1c02b12d 100644 --- a/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt +++ b/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt @@ -137,6 +137,18 @@ class DefaultUserSettingsCache( } } + override suspend fun getWallpapers(): Map { + val rawSettings = prefs.getString(WALLPAPER_SETTINGS_KEY, "") + return if (rawSettings.isNullOrEmpty()) { + emptyMap() + } else { + val deserialized = rawSettings.deserializeWallpaperSettings() + return deserialized.mapValues { setting -> + setting.value.asWallpaper() + } + } + } + override suspend fun setThemeMode(mode: ThemeMode) { prefs .edit() diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt index 2e1da3487f..9aa9e739ff 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt @@ -2,32 +2,154 @@ package com.anytypeio.anytype.presentation.vault import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope import com.anytypeio.anytype.core_models.ObjectWrapper +import com.anytypeio.anytype.core_models.Wallpaper +import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType +import com.anytypeio.anytype.core_models.primitives.SpaceId +import com.anytypeio.anytype.core_models.restrictions.SpaceStatus +import com.anytypeio.anytype.domain.base.fold +import com.anytypeio.anytype.domain.misc.UrlBuilder +import com.anytypeio.anytype.domain.multiplayer.SpaceViewSubscriptionContainer +import com.anytypeio.anytype.domain.spaces.SaveCurrentSpace +import com.anytypeio.anytype.domain.wallpaper.GetSpaceWallpapers +import com.anytypeio.anytype.domain.workspace.SpaceManager import com.anytypeio.anytype.presentation.common.BaseViewModel +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import com.anytypeio.anytype.presentation.spaces.SpaceIconView +import com.anytypeio.anytype.presentation.spaces.spaceIcon import javax.inject.Inject +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import timber.log.Timber -class VaultViewModel() : BaseViewModel() { +class VaultViewModel( + private val spaceViewSubscriptionContainer: SpaceViewSubscriptionContainer, + private val urlBuilder: UrlBuilder, + private val getSpaceWallpapers: GetSpaceWallpapers, + private val spaceManager: SpaceManager, + private val saveCurrentSpace: SaveCurrentSpace, +) : BaseViewModel() { val spaces = MutableStateFlow>(emptyList()) + val commands = MutableSharedFlow(replay = 0) init { Timber.i("VaultViewModel, init") + viewModelScope.launch { + val wallpapers = getSpaceWallpapers.async(Unit).getOrNull() ?: emptyMap() + spaceViewSubscriptionContainer + .observe() + .map { spaces -> + spaces + .filter { space -> + space.spaceLocalStatus == SpaceStatus.OK + && !space.spaceAccountStatus.isDeletedOrRemoving() + } + .map { space -> + VaultSpaceView( + space = space, + icon = space.spaceIcon( + builder = urlBuilder, + spaceGradientProvider = SpaceGradientProvider.Default + ), + wallpaper = wallpapers.getOrDefault( + key = space.targetSpaceId, + defaultValue = Wallpaper.Default + ) + ) + } + }.collect { + spaces.value = it + } + } + } + + fun onSpaceClicked(view: VaultSpaceView) { + Timber.i("onSpaceClicked") + viewModelScope.launch { + val targetSpace = view.space.targetSpaceId + if (targetSpace != null) { + spaceManager.set(targetSpace).fold( + onFailure = { + Timber.e(it, "Could not select space") + }, + onSuccess = { + proceedWithSavingCurrentSpace(targetSpace) + } + ) + } else { + Timber.e("Missing target space") + } + } + } + + fun onSettingsClicked() { + viewModelScope.launch { + val entrySpaceView = spaces.value.find { space -> + space.space.spaceAccessType == SpaceAccessType.DEFAULT + } + if (entrySpaceView != null && entrySpaceView.space.targetSpaceId != null) { + commands.emit( + Command.OpenProfileSettings( + space = SpaceId(requireNotNull(entrySpaceView.space.targetSpaceId)) + ) + ) + } else { + Timber.w("Entry space not found") + } + } + } + + fun onCreateSpaceClicked() { + viewModelScope.launch { + commands.emit(Command.CreateNewSpace) + } + } + + private suspend fun proceedWithSavingCurrentSpace(targetSpace: String) { + saveCurrentSpace.async( + SaveCurrentSpace.Params(SpaceId(targetSpace)) + ).fold( + onFailure = { + Timber.e(it, "Error while saving current space on vault screen") + }, + onSuccess = { + commands.emit(Command.EnterSpaceHomeScreen) + } + ) } class Factory @Inject constructor( + private val spaceViewSubscriptionContainer: SpaceViewSubscriptionContainer, + private val getSpaceWallpapers: GetSpaceWallpapers, + private val urlBuilder: UrlBuilder, + private val spaceManager: SpaceManager, + private val saveCurrentSpace: SaveCurrentSpace, ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create( modelClass: Class - ) = VaultViewModel() as T + ) = VaultViewModel( + spaceViewSubscriptionContainer = spaceViewSubscriptionContainer, + getSpaceWallpapers = getSpaceWallpapers, + urlBuilder = urlBuilder, + spaceManager = spaceManager, + saveCurrentSpace = saveCurrentSpace + ) as T } - data class VaultSpaceView( val space: ObjectWrapper.SpaceView, - val icon: SpaceIconView + val icon: SpaceIconView, + val wallpaper: Wallpaper = Wallpaper.Default ) + + sealed class Command { + data object EnterSpaceHomeScreen: Command() + data object CreateNewSpace: Command() + data class OpenProfileSettings(val space: SpaceId): Command() + } } \ No newline at end of file