mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2731 Vault | Tech | Basic behavior (space creation, space switching) (#1516)
This commit is contained in:
parent
b0fc366d7f
commit
6bb9ef1716
13 changed files with 325 additions and 30 deletions
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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<VaultSpaceView>,
|
||||
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 = {}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -158,6 +158,9 @@
|
|||
<action
|
||||
android:id="@+id/action_open_spaces"
|
||||
app:destination="@id/selectSpaceScreen" />
|
||||
<action
|
||||
android:id="@+id/action_open_vault"
|
||||
app:destination="@id/vaultScreen" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -191,6 +194,10 @@
|
|||
app:enterAnim="@anim/anim_switch_space_enter" />
|
||||
</dialog>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/vaultScreen"
|
||||
android:name="com.anytypeio.anytype.ui.vault.VaultFragment"/>
|
||||
|
||||
<dialog
|
||||
android:id="@+id/createSpaceScreen"
|
||||
android:name="com.anytypeio.anytype.ui.spaces.CreateSpaceFragment">
|
||||
|
|
|
@ -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()
|
||||
|
|
10
core-ui/src/main/res/drawable/ic_vault_settings.xml
Normal file
10
core-ui/src/main/res/drawable/ic_vault_settings.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="22dp"
|
||||
android:height="22dp"
|
||||
android:viewportWidth="22"
|
||||
android:viewportHeight="22">
|
||||
<path
|
||||
android:pathData="M10.25,0.75C10.25,0.336 10.586,0 11,0C11.414,0 11.75,0.336 11.75,0.75V2.533C12.755,2.621 13.711,2.883 14.585,3.291L15.476,1.748C15.683,1.39 16.141,1.267 16.5,1.474C16.796,1.645 16.932,1.988 16.853,2.304C16.837,2.371 16.81,2.436 16.774,2.499L15.883,4.042C16.689,4.608 17.392,5.311 17.958,6.117L19.502,5.225C19.861,5.018 20.319,5.141 20.526,5.5C20.733,5.859 20.611,6.317 20.252,6.524L18.709,7.415C19.117,8.289 19.379,9.245 19.467,10.25H21.25C21.664,10.25 22,10.586 22,11C22,11.414 21.664,11.75 21.25,11.75H19.467C19.379,12.755 19.117,13.711 18.709,14.585L20.252,15.476C20.611,15.683 20.733,16.141 20.526,16.5C20.319,16.859 19.861,16.982 19.502,16.775L17.958,15.883C17.392,16.689 16.689,17.392 15.883,17.958L16.774,19.502C16.852,19.636 16.883,19.785 16.873,19.929C16.86,20.115 16.778,20.293 16.637,20.425C16.596,20.463 16.551,20.497 16.5,20.526C16.141,20.733 15.683,20.61 15.476,20.252L14.585,18.709C13.711,19.117 12.755,19.379 11.75,19.467V21.25C11.75,21.664 11.414,22 11,22C10.586,22 10.25,21.664 10.25,21.25V19.467C9.245,19.379 8.289,19.117 7.415,18.709L6.524,20.252C6.317,20.611 5.859,20.733 5.5,20.526C5.141,20.319 5.018,19.861 5.225,19.502L6.117,17.958C5.311,17.392 4.608,16.689 4.042,15.883L2.498,16.774C2.139,16.982 1.681,16.859 1.474,16.5C1.267,16.141 1.389,15.682 1.748,15.475L3.291,14.585C2.883,13.71 2.621,12.755 2.533,11.75H0.75C0.724,11.75 0.699,11.749 0.673,11.746C0.295,11.708 0,11.388 0,11C0,10.586 0.336,10.25 0.75,10.25H2.533C2.621,9.245 2.883,8.29 3.291,7.415L1.748,6.525C1.389,6.318 1.267,5.859 1.474,5.5C1.681,5.141 2.139,5.018 2.498,5.226L4.042,6.117C4.608,5.311 5.311,4.608 6.117,4.042L5.225,2.498C5.018,2.139 5.141,1.681 5.5,1.474C5.859,1.267 6.317,1.389 6.524,1.748L7.415,3.291C8.289,2.883 9.245,2.621 10.25,2.533V0.75ZM4.04,11.75C4.414,15.263 7.387,18 11,18C12.008,18 12.966,17.787 13.831,17.404L10.567,11.75H4.04ZM10.567,10.25H4.04C4.414,6.737 7.387,4 11,4C12.008,4 12.966,4.213 13.831,4.596L10.567,10.25ZM15.13,16.653L11.866,11L15.13,5.347C16.87,6.621 18,8.678 18,11C18,13.322 16.87,15.379 15.13,16.653Z"
|
||||
android:fillColor="@color/glyph_active"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -23,6 +23,7 @@ interface UserSettingsCache {
|
|||
|
||||
suspend fun setWallpaper(space: Id, wallpaper: Wallpaper)
|
||||
suspend fun getWallpaper(space: Id) : Wallpaper
|
||||
suspend fun getWallpapers(): Map<Id, Wallpaper>
|
||||
suspend fun setThemeMode(mode: ThemeMode)
|
||||
suspend fun getThemeMode(): ThemeMode
|
||||
suspend fun getWidgetSession() : WidgetSession
|
||||
|
|
|
@ -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<Id, Wallpaper> {
|
||||
return cache.getWallpapers()
|
||||
}
|
||||
|
||||
override suspend fun setDefaultObjectType(
|
||||
space: SpaceId,
|
||||
type: TypeId
|
||||
|
|
|
@ -15,6 +15,7 @@ interface UserSettingsRepository {
|
|||
|
||||
suspend fun setWallpaper(space: Id, wallpaper: Wallpaper)
|
||||
suspend fun getWallpaper(space: Id): Wallpaper
|
||||
suspend fun getWallpapers(): Map<Id, Wallpaper>
|
||||
|
||||
suspend fun setDefaultObjectType(space: SpaceId, type: TypeId)
|
||||
suspend fun getDefaultObjectType(space: SpaceId): TypeId?
|
||||
|
|
|
@ -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<Unit, Map<Id, Wallpaper>>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Unit): Map<Id, Wallpaper> {
|
||||
return repo.getWallpapers()
|
||||
}
|
||||
}
|
|
@ -137,6 +137,18 @@ class DefaultUserSettingsCache(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getWallpapers(): Map<Id, Wallpaper> {
|
||||
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()
|
||||
|
|
|
@ -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<List<VaultSpaceView>>(emptyList())
|
||||
val commands = MutableSharedFlow<Command>(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 <T : ViewModel> create(
|
||||
modelClass: Class<T>
|
||||
) = 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()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue