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

DROID-3375 New settings | Enhancement | Space settings for viewers (read-only spaces) (#2208)

This commit is contained in:
Evgenii Kozlov 2025-03-29 11:24:31 +01:00 committed by GitHub
parent 5e2503d86f
commit 3bf0c305a0
Signed by: github
GPG key ID: B5690EEEBB952194
7 changed files with 281 additions and 49 deletions

View file

@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
@ -43,12 +44,15 @@ import com.anytypeio.anytype.other.DefaultDeepLinkResolver
import com.anytypeio.anytype.presentation.home.Command
import com.anytypeio.anytype.presentation.home.HomeScreenViewModel
import com.anytypeio.anytype.presentation.home.HomeScreenViewModel.Navigation
import com.anytypeio.anytype.presentation.home.HomeScreenViewModel.ViewerSpaceSettingsState
import com.anytypeio.anytype.presentation.spaces.SpaceIconView
import com.anytypeio.anytype.presentation.widgets.DropDownMenuAction
import com.anytypeio.anytype.presentation.widgets.WidgetView
import com.anytypeio.anytype.ui.base.navigation
import com.anytypeio.anytype.ui.gallery.GalleryInstallationFragment
import com.anytypeio.anytype.ui.multiplayer.LeaveSpaceWarning
import com.anytypeio.anytype.ui.multiplayer.RequestJoinSpaceFragment
import com.anytypeio.anytype.ui.multiplayer.ShareQrCodeSpaceInviteFragment
import com.anytypeio.anytype.ui.multiplayer.ShareSpaceFragment
import com.anytypeio.anytype.ui.objects.creation.ObjectTypeSelectionFragment
import com.anytypeio.anytype.ui.objects.creation.WidgetObjectTypeFragment
@ -61,6 +65,7 @@ import com.anytypeio.anytype.ui.settings.space.SpaceSettingsFragment
import com.anytypeio.anytype.ui.settings.typography
import com.anytypeio.anytype.ui.widgets.SelectWidgetSourceFragment
import com.anytypeio.anytype.ui.widgets.SelectWidgetTypeFragment
import com.anytypeio.anytype.ui_settings.space.new_settings.ViewerSpaceSettings
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber
@ -95,6 +100,7 @@ class HomeScreenFragment : BaseComposeFragment(),
): View = ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
MaterialTheme(
typography = typography,
shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(16.dp)),
@ -112,7 +118,7 @@ class HomeScreenFragment : BaseComposeFragment(),
) {
HomeScreenToolbar(
spaceIconView = view?.icon ?: SpaceIconView.Loading,
onSpaceIconClicked = vm::onSpaceWidgetClicked,
onSpaceIconClicked = { vm.onSpaceSettingsClicked(space = SpaceId(space)) },
membersCount = view?.membersCount ?: 0,
name = view?.space?.name.orEmpty(),
onBackButtonClicked = {
@ -120,19 +126,7 @@ class HomeScreenFragment : BaseComposeFragment(),
isSpaceRoot = isSpaceRootScreen()
)
},
onSettingsClicked = {
runCatching {
findNavController()
.navigate(
R.id.spaceSettingsScreen,
SpaceSettingsFragment.args(
space = SpaceId(space)
)
)
}.onFailure {
Timber.e(it, "Error while opening space settings")
}
}
onSettingsClicked = { vm.onSpaceSettingsClicked(space = SpaceId(space)) }
)
PageWithWidgets(
modifier = Modifier.padding(top = 52.dp),
@ -140,6 +134,33 @@ class HomeScreenFragment : BaseComposeFragment(),
)
}
}
val spaceSettingsState = vm.viewerSpaceSettingsState.collectAsStateWithLifecycle().value
if (spaceSettingsState is ViewerSpaceSettingsState.Visible) {
ModalBottomSheet(
shape = RoundedCornerShape(20.dp),
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 32.dp),
containerColor = colorResource(R.color.background_secondary),
onDismissRequest = vm::onDismissViewerSpaceSettings,
dragHandle = null,
content = {
ViewerSpaceSettings(
title = spaceSettingsState.name,
icon = spaceSettingsState.icon,
description = spaceSettingsState.description,
info = spaceSettingsState.techInfo,
uiEvent = {
vm.onViewerSpaceSettingsUiEvent(
space = SpaceId(space),
uiEvent = it
)
}
)
}
)
}
BackHandler {
vm.onBackClicked(
isSpaceRoot = isSpaceRootScreen()
@ -338,6 +359,24 @@ class HomeScreenFragment : BaseComposeFragment(),
Timber.e(it, "Error while opening share screen")
}
}
is Command.ShowInviteLinkQrCode -> {
runCatching {
findNavController().navigate(
R.id.shareSpaceInviteQrCodeScreen,
ShareQrCodeSpaceInviteFragment.args(link = command.link)
)
}.onFailure {
Timber.w(it, "Error while showing invite QR code from space settings in widgets")
}
}
is Command.ShowLeaveSpaceWarning -> {
val dialog = LeaveSpaceWarning.new()
dialog.onLeaveSpaceAccepted = {
dialog.dismiss()
vm.onLeaveSpaceAcceptedClicked(SpaceId(space))
}
dialog.show(childFragmentManager, null)
}
is Command.CreateSourceForNewWidget -> {
val dialog = WidgetSourceTypeFragment.new(
space = command.space.id,
@ -463,6 +502,19 @@ class HomeScreenFragment : BaseComposeFragment(),
Timber.e(e, "Error while opening participant from widgets")
}
}
is Navigation.OpenOwnerOrEditorSpaceSettings -> {
runCatching {
findNavController()
.navigate(
R.id.spaceSettingsScreen,
SpaceSettingsFragment.args(
space = SpaceId(space)
)
)
}.onFailure {
Timber.e(it, "Error while opening space settings")
}
}
}
}

View file

@ -290,6 +290,8 @@ sealed class ObjectWrapper {
val chatId: Id? by default
val creator: Id? by default
val spaceAccountStatus: SpaceStatus
get() {
val code = getValue<Double?>(Relations.SPACE_ACCOUNT_STATUS)

View file

@ -18,6 +18,7 @@ import androidx.compose.material.Text
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -33,6 +34,7 @@ import androidx.compose.ui.unit.dp
import com.anytypeio.anytype.core_models.SystemColor
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
import com.anytypeio.anytype.core_ui.foundation.Divider
import com.anytypeio.anytype.core_ui.foundation.Dragger
import com.anytypeio.anytype.core_ui.views.BodyCalloutRegular
import com.anytypeio.anytype.core_ui.views.HeadlineHeading
@ -51,7 +53,7 @@ fun ViewerSpaceSettings(
uiEvent: (UiEvent) -> Unit,
) {
val isTheeDotsMenuExpanded = remember { mutableStateOf(true) }
val isTheeDotsMenuExpanded = remember { mutableStateOf(false) }
var showTechInfo by remember { mutableStateOf(false) }
Column(
@ -76,6 +78,15 @@ fun ViewerSpaceSettings(
painter = painterResource(R.drawable.ic_more_32),
contentDescription = "Three dots button"
)
ThreeDotsMenu(
isTheeDotsMenuExpanded = isTheeDotsMenuExpanded,
onShowTechInfoClicked = {
showTechInfo = true
},
onLeaveSpaceClicked = {
uiEvent(UiEvent.OnLeaveSpaceClicked)
}
)
}
NewSpaceIcon(
modifier = Modifier.fillMaxWidth(),
@ -98,6 +109,7 @@ fun ViewerSpaceSettings(
modifier = Modifier.padding(horizontal = 16.dp).fillMaxWidth(),
style = BodyCalloutRegular,
color = colorResource(R.color.text_primary),
textAlign = TextAlign.Center
)
}
Spacer(modifier = Modifier.height(12.dp))
@ -109,6 +121,22 @@ fun ViewerSpaceSettings(
Spacer(modifier = Modifier.height(24.dp))
}
if (showTechInfo) {
ModalBottomSheet(
containerColor = colorResource(R.color.background_secondary),
onDismissRequest = { showTechInfo = false },
dragHandle = null,
content = { SpaceInfoScreen(spaceTechInfo = info) }
)
}
}
@Composable
private fun ThreeDotsMenu(
isTheeDotsMenuExpanded: MutableState<Boolean>,
onLeaveSpaceClicked: () -> Unit,
onShowTechInfoClicked: () -> Unit
) {
MaterialTheme(
shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(10.dp))
) {
@ -117,48 +145,43 @@ fun ViewerSpaceSettings(
.background(
shape = RoundedCornerShape(10.dp),
color = colorResource(id = R.color.background_secondary)
),
)
,
expanded = isTheeDotsMenuExpanded.value,
offset = DpOffset(x = 0.dp, y = 6.dp),
offset = DpOffset(x = (-12).dp, y = (-6).dp),
onDismissRequest = {
isTheeDotsMenuExpanded.value = false
}
) {
DropdownMenuItem(
onClick = {
uiEvent(UiEvent.IconMenu.OnRemoveIconClicked)
onShowTechInfoClicked()
isTheeDotsMenuExpanded.value = false
},
) {
Text(
text = stringResource(R.string.tech_info),
style = BodyCalloutRegular,
color = colorResource(id = R.color.text_primary)
color = colorResource(id = R.color.text_primary),
modifier = Modifier.padding(end = 48.dp)
)
}
Divider(paddingEnd = 0.dp, paddingStart = 0.dp)
DropdownMenuItem(
onClick = {
onLeaveSpaceClicked()
isTheeDotsMenuExpanded.value = false
uiEvent(UiEvent.OnLeaveSpaceClicked)
},
) {
Text(
text = stringResource(R.string.multiplayer_leave_space),
style = BodyCalloutRegular,
color = colorResource(id = R.color.palette_system_red)
color = colorResource(id = R.color.palette_system_red),
modifier = Modifier.padding(end = 48.dp)
)
}
}
}
if (showTechInfo) {
ModalBottomSheet(
containerColor = colorResource(R.color.background_secondary),
onDismissRequest = { showTechInfo = false },
dragHandle = null,
content = { SpaceInfoScreen(spaceTechInfo = info) }
)
}
}
@DefaultPreviews

View file

@ -25,6 +25,7 @@ import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.SupportedLayouts
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.WidgetSession
import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE
import com.anytypeio.anytype.core_models.ext.process
import com.anytypeio.anytype.core_models.isDataView
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
@ -54,7 +55,10 @@ import com.anytypeio.anytype.domain.misc.DateProvider
import com.anytypeio.anytype.domain.misc.DeepLinkResolver
import com.anytypeio.anytype.domain.misc.Reducer
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
import com.anytypeio.anytype.domain.multiplayer.GetSpaceInviteLink
import com.anytypeio.anytype.domain.multiplayer.SpaceInviteResolver
import com.anytypeio.anytype.domain.multiplayer.SpaceViewSubscriptionContainer
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
import com.anytypeio.anytype.domain.`object`.GetObject
import com.anytypeio.anytype.domain.`object`.OpenObject
@ -67,6 +71,7 @@ import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.primitives.FieldParser
import com.anytypeio.anytype.domain.search.SearchObjects
import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace
import com.anytypeio.anytype.domain.spaces.DeleteSpace
import com.anytypeio.anytype.domain.spaces.GetSpaceView
import com.anytypeio.anytype.domain.types.GetPinnedObjectTypes
import com.anytypeio.anytype.domain.widgets.CreateWidget
@ -99,6 +104,10 @@ import com.anytypeio.anytype.presentation.sets.resolveSetByRelationPrefilledObje
import com.anytypeio.anytype.presentation.sets.resolveTypeAndActiveViewTemplate
import com.anytypeio.anytype.presentation.sets.state.ObjectState.Companion.VIEW_DEFAULT_OBJECT_TYPE
import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider
import com.anytypeio.anytype.presentation.spaces.SpaceIconView
import com.anytypeio.anytype.presentation.spaces.SpaceTechInfo
import com.anytypeio.anytype.presentation.spaces.UiEvent
import com.anytypeio.anytype.presentation.spaces.spaceIcon
import com.anytypeio.anytype.presentation.util.Dispatcher
import com.anytypeio.anytype.presentation.vault.ExitToVaultDelegate
import com.anytypeio.anytype.presentation.widgets.AllContentWidgetContainer
@ -212,7 +221,11 @@ class HomeScreenViewModel(
private val featureToggles: FeatureToggles,
private val fieldParser: FieldParser,
private val spaceInviteResolver: SpaceInviteResolver,
private val exitToVaultDelegate: ExitToVaultDelegate
private val exitToVaultDelegate: ExitToVaultDelegate,
private val spaceViewSubscriptionContainer: SpaceViewSubscriptionContainer,
private val getSpaceInviteLink: GetSpaceInviteLink,
private val deleteSpace: DeleteSpace,
private val spaceMembers: ActiveSpaceMemberSubscriptionContainer
) : NavigationViewModel<HomeScreenViewModel.Navigation>(),
Reducer<ObjectView, Payload>,
WidgetActiveViewStateHolder by widgetActiveViewStateHolder,
@ -254,6 +267,8 @@ class HomeScreenViewModel(
val navPanelState = MutableStateFlow<NavPanelState>(NavPanelState.Init)
val viewerSpaceSettingsState = MutableStateFlow<ViewerSpaceSettingsState>(ViewerSpaceSettingsState.Init)
private val widgetObjectPipeline = spaceManager
.observe()
.distinctUntilChanged()
@ -1826,6 +1841,10 @@ class HomeScreenViewModel(
}
fun onBackClicked(isSpaceRoot: Boolean) {
proceedWithExiting(isSpaceRoot)
}
private fun proceedWithExiting(isSpaceRoot: Boolean) {
viewModelScope.launch {
if (spaceManager.getState() is SpaceManager.State.Space) {
// Proceed with releasing resources before exiting
@ -2214,6 +2233,103 @@ class HomeScreenViewModel(
)
}
fun onSpaceSettingsClicked(space: SpaceId) {
viewModelScope.launch {
val permission = userPermissions.value
if (permission?.isOwnerOrEditor() == true) {
navigation(Navigation.OpenOwnerOrEditorSpaceSettings(space = space.id))
} else {
val targetSpaceView = spaceViewSubscriptionContainer.get(space)
if (targetSpaceView != null) {
val config = spaceManager.getConfig(space)
val creatorId = targetSpaceView.creator.orEmpty()
val createdByScreenName : String
if (creatorId.isNotEmpty()) {
val store = spaceMembers.get(space)
createdByScreenName = when(store) {
is ActiveSpaceMemberSubscriptionContainer.Store.Data -> {
store.members
.find { m -> m.id == creatorId }
?.let { it.globalName ?: it.identity }
?.ifEmpty { null }
?: creatorId
}
ActiveSpaceMemberSubscriptionContainer.Store.Empty -> {
creatorId
}
}
} else {
Timber.w("Creator ID was empty")
createdByScreenName = EMPTY_STRING_VALUE
}
viewerSpaceSettingsState.value = ViewerSpaceSettingsState.Visible(
name = targetSpaceView.name.orEmpty(),
description = targetSpaceView.description.orEmpty(),
icon = targetSpaceView.spaceIcon(
builder = urlBuilder,
spaceGradientProvider = SpaceGradientProvider.Default
),
techInfo = SpaceTechInfo(
spaceId = space,
networkId = config?.network.orEmpty(),
creationDateInMillis = targetSpaceView
.getValue<Double?>(Relations.CREATED_DATE)
?.let { timeInSeconds -> (timeInSeconds * 1000L).toLong() },
createdBy = createdByScreenName
)
)
}
}
}
}
fun onViewerSpaceSettingsUiEvent(space: SpaceId, uiEvent: UiEvent) {
when(uiEvent) {
UiEvent.OnQrCodeClicked -> {
viewModelScope.launch {
getSpaceInviteLink
.async(space)
.onFailure { commands.emit(Command.ShareSpace(space)) }
.onSuccess { link ->
commands.emit(Command.ShowInviteLinkQrCode(link.scheme))
}
}
}
UiEvent.OnInviteClicked -> {
viewModelScope.launch { commands.emit(Command.ShareSpace(space)) }
}
UiEvent.OnLeaveSpaceClicked -> {
viewModelScope.launch { commands.emit(Command.ShowLeaveSpaceWarning) }
}
else -> {
Timber.w("Unexpected UI event: $uiEvent")
}
}
}
fun onDismissViewerSpaceSettings() {
viewerSpaceSettingsState.value = ViewerSpaceSettingsState.Hidden
}
fun onLeaveSpaceAcceptedClicked(space: SpaceId) {
viewModelScope.launch {
val permission = userPermissionProvider.get(space)
if (permission != null && permission != SpaceMemberPermissions.OWNER) {
deleteSpace
.async(space)
.onFailure { Timber.e(it, "Error while leaving space") }
.onSuccess {
// Forcing return to the vault even if space has chat.
proceedWithExiting(
isSpaceRoot = true
)
}
} else {
Timber.e("Unexpected permission when trying to leave space: $permission")
}
}
}
sealed class Navigation {
data class OpenObject(val ctx: Id, val space: Id) : Navigation()
data class OpenChat(val ctx: Id, val space: Id) : Navigation()
@ -2224,6 +2340,18 @@ class HomeScreenViewModel(
data class OpenDateObject(val ctx: Id, val space: Id) : Navigation()
data class OpenParticipant(val objectId: Id, val space: Id) : Navigation()
data class OpenType(val target: Id, val space: Id) : Navigation()
data class OpenOwnerOrEditorSpaceSettings(val space: Id) : Navigation()
}
sealed class ViewerSpaceSettingsState {
data object Init : ViewerSpaceSettingsState()
data object Hidden: ViewerSpaceSettingsState()
data class Visible(
val name: String,
val description: String,
val icon: SpaceIconView,
val techInfo: SpaceTechInfo
) : ViewerSpaceSettingsState()
}
class Factory @Inject constructor(
@ -2278,6 +2406,10 @@ class HomeScreenViewModel(
private val fieldParser: FieldParser,
private val spaceInviteResolver: SpaceInviteResolver,
private val exitToVaultDelegate: ExitToVaultDelegate,
private val spaceViewSubscriptionContainer: SpaceViewSubscriptionContainer,
private val getSpaceInviteLink: GetSpaceInviteLink,
private val deleteSpace: DeleteSpace,
private val activeSpaceMemberSubscriptionContainer: ActiveSpaceMemberSubscriptionContainer
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T = HomeScreenViewModel(
@ -2330,7 +2462,11 @@ class HomeScreenViewModel(
featureToggles = featureToggles,
fieldParser = fieldParser,
spaceInviteResolver = spaceInviteResolver,
exitToVaultDelegate = exitToVaultDelegate
exitToVaultDelegate = exitToVaultDelegate,
spaceViewSubscriptionContainer = spaceViewSubscriptionContainer,
getSpaceInviteLink = getSpaceInviteLink,
deleteSpace = this@Factory.deleteSpace,
spaceMembers = activeSpaceMemberSubscriptionContainer
) as T
}
@ -2437,6 +2573,10 @@ sealed class Command {
) : Deeplink()
data class MembershipScreen(val tierId: String?) : Deeplink()
}
data class ShowInviteLinkQrCode(val link: String) : Command()
data object ShowLeaveSpaceWarning : Command()
}
/**

View file

@ -38,6 +38,7 @@ fun ObjectWrapper.Basic.spaceIcon(
)
}
// TODO delete provider
fun ObjectWrapper.SpaceView.spaceIcon(
builder: UrlBuilder,
spaceGradientProvider: SpaceGradientProvider,

View file

@ -432,20 +432,20 @@ class SpaceSettingsViewModel(
private fun proceedWithSpaceDeletion() {
viewModelScope.launch {
deleteSpace.async(params = vmParams.space).fold(
onSuccess = {
analytics.sendEvent(
eventName = EventsDictionary.deleteSpace,
props = Props(mapOf(EventsPropertiesKey.type to "Private"))
)
spaceManager.clear()
commands.emit(Command.ExitToVault)
},
onFailure = {
Timber.e(it, "Error while deleting space")
}
)
}
deleteSpace.async(params = vmParams.space).fold(
onSuccess = {
analytics.sendEvent(
eventName = EventsDictionary.deleteSpace,
props = Props(mapOf(EventsPropertiesKey.type to "Private"))
)
spaceManager.clear()
commands.emit(Command.ExitToVault)
},
onFailure = {
Timber.e(it, "Error while deleting space")
}
)
}
}
// What is below is candidate to legacy. Might be deleted soon.

View file

@ -25,7 +25,6 @@ import com.anytypeio.anytype.core_models.StubWidgetBlock
import com.anytypeio.anytype.core_models.UNKNOWN_SPACE_TYPE
import com.anytypeio.anytype.core_models.WidgetSession
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
import com.anytypeio.anytype.core_models.primitives.Space
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_models.primitives.TypeId
import com.anytypeio.anytype.core_models.primitives.TypeKey
@ -49,8 +48,10 @@ import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
import com.anytypeio.anytype.domain.misc.AppActionManager
import com.anytypeio.anytype.domain.misc.DateProvider
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
import com.anytypeio.anytype.domain.multiplayer.GetSpaceInviteLink
import com.anytypeio.anytype.domain.multiplayer.SpaceInviteResolver
import com.anytypeio.anytype.domain.multiplayer.SpaceViewSubscriptionContainer
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
import com.anytypeio.anytype.domain.`object`.GetObject
import com.anytypeio.anytype.domain.`object`.OpenObject
@ -66,6 +67,7 @@ import com.anytypeio.anytype.domain.primitives.FieldParserImpl
import com.anytypeio.anytype.domain.resources.StringResourceProvider
import com.anytypeio.anytype.domain.search.SearchObjects
import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace
import com.anytypeio.anytype.domain.spaces.DeleteSpace
import com.anytypeio.anytype.domain.spaces.GetSpaceView
import com.anytypeio.anytype.domain.types.GetPinnedObjectTypes
import com.anytypeio.anytype.domain.widgets.CreateWidget
@ -82,7 +84,6 @@ import com.anytypeio.anytype.presentation.navigation.DeepLinkToObjectDelegate
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
import com.anytypeio.anytype.presentation.search.Subscriptions
import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider
import com.anytypeio.anytype.presentation.spaces.SpaceIconView
import com.anytypeio.anytype.presentation.util.DefaultCoroutineTestRule
import com.anytypeio.anytype.presentation.util.Dispatcher
@ -218,6 +219,9 @@ class HomeScreenViewModelTest {
@Mock
lateinit var getSpaceView: GetSpaceView
@Mock
lateinit var spaceViewSubscriptionContainer: SpaceViewSubscriptionContainer
@Mock
lateinit var spaceManager: SpaceManager
@ -269,6 +273,12 @@ class HomeScreenViewModelTest {
@Mock
lateinit var exitToVaultDelegate: ExitToVaultDelegate
@Mock
lateinit var activeSpaceMemberSubscriptionContainer: ActiveSpaceMemberSubscriptionContainer
@Mock
lateinit var deleteSpace: DeleteSpace
lateinit var userPermissionProvider: UserPermissionProvider
private val objectPayloadDispatcher = Dispatcher.Default<Payload>()
@ -3061,7 +3071,11 @@ class HomeScreenViewModelTest {
featureToggles = featureToggles,
fieldParser = fieldParser,
spaceInviteResolver = spaceInviteResolver,
exitToVaultDelegate = exitToVaultDelegate
exitToVaultDelegate = exitToVaultDelegate,
getSpaceInviteLink = getSpaceInviteLink,
spaceMembers = activeSpaceMemberSubscriptionContainer,
spaceViewSubscriptionContainer = spaceViewSubscriptionContainer,
deleteSpace = deleteSpace
)
companion object {