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 55a7c218ff..c73a5befc8 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 @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModelProvider import com.anytypeio.anytype.analytics.base.Analytics import com.anytypeio.anytype.core_utils.di.scope.PerScreen import com.anytypeio.anytype.di.common.ComponentDependencies +import com.anytypeio.anytype.domain.auth.repo.AuthRepository import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers import com.anytypeio.anytype.domain.block.repo.BlockRepository import com.anytypeio.anytype.domain.config.UserSettingsRepository @@ -54,4 +55,5 @@ interface VaultComponentDependencies : ComponentDependencies { fun spaceViewSubscriptionContainer(): SpaceViewSubscriptionContainer fun userSettingsRepository(): UserSettingsRepository fun spaceManager(): SpaceManager + fun auth(): AuthRepository } \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultFragment.kt new file mode 100644 index 0000000000..9b254f617e --- /dev/null +++ b/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultFragment.kt @@ -0,0 +1,39 @@ +package com.anytypeio.anytype.ui.vault + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.material.MaterialTheme +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.ViewCompositionStrategy +import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment +import com.anytypeio.anytype.ui.settings.typography + +class IntroduceVaultFragment : BaseBottomSheetComposeFragment() { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return ComposeView(requireContext()).apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + setContent { + MaterialTheme(typography = typography) { + IntroduceVaultScreen( + onDoneClicked = { + dismiss() + } + ) + } + } + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + skipCollapsed() + expand() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultScreen.kt index c6b5a161d4..9e4aad602d 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/vault/IntroduceVaultScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row 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.pager.HorizontalPager @@ -63,7 +64,7 @@ fun IntroduceVaultScreen( ) { val coroutineScope = rememberCoroutineScope() - val (title, first, second, third, pager, dots, btn) = createRefs() + val (title, first, pager, dots, btn) = createRefs() val pagerState = rememberPagerState(pageCount = { 2 }) @@ -89,39 +90,35 @@ fun IntroduceVaultScreen( HorizontalPager( state = pagerState, modifier = Modifier - .padding(bottom = 16.dp, top = 38.dp) + .padding(bottom = 16.dp, top = 42.dp) + .height(452.dp) + .fillMaxWidth() .constrainAs(pager) { top.linkTo(title.bottom) - bottom.linkTo(dots.top) height = Dimension.fillToConstraints } .fillMaxSize() ) { page -> when(page) { 0 -> { - Box(modifier = Modifier.fillMaxSize()) { + Box( + modifier = Modifier.fillMaxWidth() + ) { Image( painter = painterResource(id = R.drawable.img_introduce_vault_1), contentDescription = "Screenshot 1", - modifier = Modifier.align(Alignment.BottomCenter) + modifier = Modifier.align(Alignment.TopCenter) ) } } 1 -> { - Box(modifier = Modifier.fillMaxSize()) { + Box( + modifier = Modifier.fillMaxWidth() + ) { Image( - painter = painterResource(id = R.drawable.img_introduce_vault_1), + painter = painterResource(id = R.drawable.img_introduce_vault_2), contentDescription = "Screenshot 2", - modifier = Modifier.align(Alignment.BottomCenter) - ) - } - } - 2 -> { - Box(modifier = Modifier.fillMaxSize()) { - Image( - painter = painterResource(id = R.drawable.ic_sharing_step_third), - contentDescription = "Screenshot 3", - modifier = Modifier.align(Alignment.BottomCenter) + modifier = Modifier.align(Alignment.TopCenter) ) } } @@ -131,9 +128,9 @@ fun IntroduceVaultScreen( Row( modifier = Modifier .fillMaxWidth() - .padding(bottom = 46.dp) + .padding(top = 4.dp) .constrainAs(dots) { - bottom.linkTo(first.top) + bottom.linkTo(pager.bottom) }, horizontalArrangement = Arrangement.Center ) { @@ -164,10 +161,11 @@ fun IntroduceVaultScreen( style = BodyRegular, color = colorResource(id = R.color.text_primary), modifier = Modifier - .padding(bottom = 8.dp, start = 24.dp, end = 24.dp) + .padding(bottom = 30.dp, start = 24.dp, end = 24.dp) .constrainAs(first) { bottom.linkTo(btn.top) - } + }, + textAlign = TextAlign.Center ) ButtonSecondary( 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 08ce919f19..1d3c81e0a8 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 @@ -82,6 +82,13 @@ class VaultFragment : BaseComposeFragment() { Timber.e(it, "Error while opening profile settings from vault") } } + is Command.ShowIntroduceVault -> { + runCatching { + findNavController().navigate(R.id.actionShowIntroduceVaultScreen) + }.onFailure { + Timber.e(it, "Error while opening introduce-vault-screen from vault") + } + } } } @@ -89,6 +96,11 @@ class VaultFragment : BaseComposeFragment() { // TODO Do nothing ? } + override fun onResume() { + super.onResume() + vm.onResume() + } + override fun injectDependencies() { componentManager().vaultComponent.get().inject(this) } diff --git a/app/src/main/res/layout/fragment_object_set.xml b/app/src/main/res/layout/fragment_object_set.xml index 6470e5d3c2..e25740334a 100644 --- a/app/src/main/res/layout/fragment_object_set.xml +++ b/app/src/main/res/layout/fragment_object_set.xml @@ -46,7 +46,7 @@ android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="@+id/galleryView" - app:layout_constraintBottom_toTopOf="@id/bottomToolbar" + app:layout_constraintBottom_toTopOf="@id/bottomToolbarДontainer" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/controlDivider2" /> @@ -89,7 +89,7 @@ android:id="@+id/paginatorToolbar" android:layout_width="0dp" android:layout_height="@dimen/default_toolbar_height" - app:layout_constraintBottom_toTopOf="@id/bottomToolbar" + app:layout_constraintBottom_toTopOf="@id/bottomToolbarДontainer" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> diff --git a/app/src/main/res/navigation/graph.xml b/app/src/main/res/navigation/graph.xml index a57ba0dd64..ce0e083046 100644 --- a/app/src/main/res/navigation/graph.xml +++ b/app/src/main/res/navigation/graph.xml @@ -214,6 +214,9 @@ + + + = emptyList() ) \ No newline at end of file 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 a655835d3f..fa9155cdf4 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 @@ -16,6 +16,7 @@ interface UserSettingsCache { suspend fun getVaultSettings(account: Account): VaultSettings suspend fun observeVaultSettings(account: Account): Flow suspend fun setVaultSpaceOrder(account: Account, order: List) + suspend fun setVaultSettings(account: Account, settings: VaultSettings) suspend fun setCurrentSpace(space: SpaceId) suspend fun getCurrentSpace(): SpaceId? 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 4ef16141ca..d649081707 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 @@ -95,6 +95,10 @@ class UserSettingsDataRepository(private val cache: UserSettingsCache) : UserSet return cache.getVaultSettings(account) } + override suspend fun setVaultSettings(account: Account, settings: VaultSettings) { + cache.setVaultSettings(account, settings) + } + override suspend fun observeVaultSettings(account: Account): Flow { return cache.observeVaultSettings(account) } 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 dc83d7545f..cea8576d30 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 @@ -16,6 +16,7 @@ interface UserSettingsRepository { suspend fun getVaultSettings(account: Account): VaultSettings suspend fun observeVaultSettings(account: Account): Flow suspend fun setVaultSpaceOrder(account: Account, order: List) + suspend fun setVaultSettings(account: Account, settings: VaultSettings) suspend fun setCurrentSpace(space: SpaceId) suspend fun getCurrentSpace(): SpaceId? diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/vault/GetVaultSettings.kt b/domain/src/main/java/com/anytypeio/anytype/domain/vault/GetVaultSettings.kt new file mode 100644 index 0000000000..a3b6d123c4 --- /dev/null +++ b/domain/src/main/java/com/anytypeio/anytype/domain/vault/GetVaultSettings.kt @@ -0,0 +1,20 @@ +package com.anytypeio.anytype.domain.vault + +import com.anytypeio.anytype.core_models.settings.VaultSettings +import com.anytypeio.anytype.domain.auth.repo.AuthRepository +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 GetVaultSettings @Inject constructor( + private val settings: UserSettingsRepository, + private val auth: AuthRepository, + dispatchers: AppCoroutineDispatchers +): ResultInteractor(dispatchers.io) { + + override suspend fun doWork(params: Unit): VaultSettings { + val acc = auth.getCurrentAccount() + return settings.getVaultSettings(acc) + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/vault/SetVaultSettings.kt b/domain/src/main/java/com/anytypeio/anytype/domain/vault/SetVaultSettings.kt new file mode 100644 index 0000000000..63b38df3ae --- /dev/null +++ b/domain/src/main/java/com/anytypeio/anytype/domain/vault/SetVaultSettings.kt @@ -0,0 +1,20 @@ +package com.anytypeio.anytype.domain.vault + +import com.anytypeio.anytype.core_models.settings.VaultSettings +import com.anytypeio.anytype.domain.auth.repo.AuthRepository +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 SetVaultSettings @Inject constructor( + private val settings: UserSettingsRepository, + private val auth: AuthRepository, + dispatchers: AppCoroutineDispatchers +): ResultInteractor(dispatchers.io) { + + override suspend fun doWork(params: VaultSettings): Unit { + val acc = auth.getCurrentAccount() + return settings.setVaultSettings(acc, params) + } +} \ 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 861cb44538..e1db495060 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 @@ -396,11 +396,15 @@ class DefaultUserSettingsCache( return context.vaultPrefsStore .data .map { prefs -> + val curr = prefs.preferences.getOrDefault( + key = account.id, + defaultValue = VaultPreference( + showIntroduceVault = true + ) + ) VaultSettings( - orderOfSpaces = prefs.preferences.getOrDefault( - key = account.id, - defaultValue = VaultPreference() - ).orderOfSpaces + orderOfSpaces = curr.orderOfSpaces, + showIntroduceVault = curr.showIntroduceVault ) } .first() @@ -410,11 +414,15 @@ class DefaultUserSettingsCache( return context.vaultPrefsStore .data .map { prefs -> + val curr = prefs.preferences.getOrDefault( + key = account.id, + defaultValue = VaultPreference( + showIntroduceVault = true + ) + ) VaultSettings( - orderOfSpaces = prefs.preferences.getOrDefault( - key = account.id, - defaultValue = VaultPreference() - ).orderOfSpaces + orderOfSpaces = curr.orderOfSpaces, + showIntroduceVault = curr.showIntroduceVault ) } } @@ -423,7 +431,9 @@ class DefaultUserSettingsCache( context.vaultPrefsStore.updateData { existingPreferences -> val curr = existingPreferences.preferences.getOrDefault( key = account.id, - defaultValue = VaultPreference() + defaultValue = VaultPreference( + showIntroduceVault = true + ) ) existingPreferences.copy( preferences = existingPreferences.preferences + mapOf( @@ -435,6 +445,19 @@ class DefaultUserSettingsCache( } } + override suspend fun setVaultSettings(account: Account, settings: VaultSettings) { + context.vaultPrefsStore.updateData { existingPreferences -> + existingPreferences.copy( + preferences = existingPreferences.preferences + mapOf( + account.id to VaultPreference( + orderOfSpaces = settings.orderOfSpaces, + showIntroduceVault = settings.showIntroduceVault + ) + ) + ) + } + } + override suspend fun getAllContentSort(space: SpaceId): Id { return context.spacePrefsStore .data diff --git a/persistence/src/main/proto/preferences.proto b/persistence/src/main/proto/preferences.proto index 3522e898a6..8e2dd7fc5c 100644 --- a/persistence/src/main/proto/preferences.proto +++ b/persistence/src/main/proto/preferences.proto @@ -15,6 +15,7 @@ message VaultPreferences { message VaultPreference { repeated string orderOfSpaces = 1; + bool showIntroduceVault = 2; } message SpacePreference { 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 9aa9e739ff..330777bbb7 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 @@ -9,9 +9,12 @@ 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.base.onSuccess 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.vault.GetVaultSettings +import com.anytypeio.anytype.domain.vault.SetVaultSettings import com.anytypeio.anytype.domain.wallpaper.GetSpaceWallpapers import com.anytypeio.anytype.domain.workspace.SpaceManager import com.anytypeio.anytype.presentation.common.BaseViewModel @@ -31,6 +34,8 @@ class VaultViewModel( private val getSpaceWallpapers: GetSpaceWallpapers, private val spaceManager: SpaceManager, private val saveCurrentSpace: SaveCurrentSpace, + private val getVaultSettings: GetVaultSettings, + private val setVaultSettings: SetVaultSettings ) : BaseViewModel() { val spaces = MutableStateFlow>(emptyList()) @@ -109,6 +114,21 @@ class VaultViewModel( } } + fun onResume() { + viewModelScope.launch { + getVaultSettings.async(Unit).onSuccess { settings -> + if (settings.showIntroduceVault) { + commands.emit(Command.ShowIntroduceVault) + setVaultSettings.async( + params = settings.copy( + showIntroduceVault = false + ) + ) + } + } + } + } + private suspend fun proceedWithSavingCurrentSpace(targetSpace: String) { saveCurrentSpace.async( SaveCurrentSpace.Params(SpaceId(targetSpace)) @@ -128,6 +148,8 @@ class VaultViewModel( private val urlBuilder: UrlBuilder, private val spaceManager: SpaceManager, private val saveCurrentSpace: SaveCurrentSpace, + private val getVaultSettings: GetVaultSettings, + private val setVaultSettings: SetVaultSettings ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create( @@ -137,7 +159,9 @@ class VaultViewModel( getSpaceWallpapers = getSpaceWallpapers, urlBuilder = urlBuilder, spaceManager = spaceManager, - saveCurrentSpace = saveCurrentSpace + saveCurrentSpace = saveCurrentSpace, + getVaultSettings = getVaultSettings, + setVaultSettings = setVaultSettings ) as T } @@ -151,5 +175,6 @@ class VaultViewModel( data object EnterSpaceHomeScreen: Command() data object CreateNewSpace: Command() data class OpenProfileSettings(val space: SpaceId): Command() + data object ShowIntroduceVault : Command() } } \ No newline at end of file