mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2460 Multiplayer | Fix | Fix share limit counter (#1156)
This commit is contained in:
parent
4629fa6be0
commit
b833601f81
5 changed files with 114 additions and 22 deletions
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.domain.multiplayer
|
|||
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVFilterCondition
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
|
@ -43,6 +44,12 @@ interface UserPermissionProvider {
|
|||
* @return [SpaceMemberPermissions] for [space] or null if user permission could not be defined.
|
||||
*/
|
||||
fun observe(space: SpaceId) : Flow<SpaceMemberPermissions?>
|
||||
|
||||
/**
|
||||
* Provide permissions of the current user in all available spaces.
|
||||
* Maps space to permissions.
|
||||
*/
|
||||
fun all() : Flow<Map<Id, SpaceMemberPermissions>>
|
||||
}
|
||||
|
||||
class DefaultUserPermissionProvider @Inject constructor(
|
||||
|
@ -107,6 +114,18 @@ class DefaultUserPermissionProvider @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun all(): Flow<Map<Id, SpaceMemberPermissions>> {
|
||||
return members.map { all ->
|
||||
all.filter { member ->
|
||||
!member.spaceId.isNullOrEmpty()
|
||||
}.associate { member ->
|
||||
val space = requireNotNull(member.spaceId)
|
||||
val permissions = member.permissions ?: SpaceMemberPermissions.NO_PERMISSIONS
|
||||
space to permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
clear()
|
||||
scope.launch(dispatchers.io) {
|
||||
|
|
|
@ -4,10 +4,14 @@ import com.anytypeio.anytype.core_models.DVFilter
|
|||
import com.anytypeio.anytype.core_models.DVFilterCondition
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVSortType
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType.SHARED
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions.OWNER
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.restrictions.SpaceStatus
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
|
@ -139,10 +143,16 @@ interface SpaceViewSubscriptionContainer {
|
|||
}
|
||||
}
|
||||
|
||||
fun SpaceViewSubscriptionContainer.isSharingLimitReached() : Flow<Boolean> {
|
||||
val sharedSpacesCount = observe().map { spaceViews ->
|
||||
fun SpaceViewSubscriptionContainer.isSharingLimitReached(
|
||||
spaceToUserPermissions: Flow<Map<Id, SpaceMemberPermissions>>
|
||||
) : Flow<Boolean> {
|
||||
val sharedSpacesCount = combine(
|
||||
observe(),
|
||||
spaceToUserPermissions
|
||||
) { spaceViews, permissions ->
|
||||
spaceViews.count { spaceView ->
|
||||
spaceView.spaceAccessType == SpaceAccessType.SHARED
|
||||
val permission = permissions[spaceView.targetSpaceId]
|
||||
spaceView.spaceAccessType == SHARED && permission == OWNER
|
||||
}
|
||||
}
|
||||
val sharedSpaceLimit = observe().map { spaceViews ->
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.domain.multiplayer
|
|||
import app.cash.turbine.test
|
||||
import com.anytypeio.anytype.core_models.StubSpaceView
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
|
||||
import kotlin.test.assertEquals
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
@ -37,6 +38,11 @@ class SpaceViewSubscriptionContainerTest {
|
|||
spaceAccessType = SpaceAccessType.PRIVATE
|
||||
)
|
||||
|
||||
val permissions = mapOf(
|
||||
defaultSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER,
|
||||
privateSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER
|
||||
)
|
||||
|
||||
container.stub {
|
||||
on {
|
||||
observe()
|
||||
|
@ -45,7 +51,7 @@ class SpaceViewSubscriptionContainerTest {
|
|||
)
|
||||
}
|
||||
|
||||
container.isSharingLimitReached().test {
|
||||
container.isSharingLimitReached(flowOf(permissions)).test {
|
||||
val result = awaitItem()
|
||||
assertEquals(
|
||||
expected = true,
|
||||
|
@ -68,6 +74,11 @@ class SpaceViewSubscriptionContainerTest {
|
|||
spaceAccessType = SpaceAccessType.PRIVATE
|
||||
)
|
||||
|
||||
val permissions = mapOf(
|
||||
defaultSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER,
|
||||
privateSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER
|
||||
)
|
||||
|
||||
container.stub {
|
||||
on {
|
||||
observe()
|
||||
|
@ -76,7 +87,7 @@ class SpaceViewSubscriptionContainerTest {
|
|||
)
|
||||
}
|
||||
|
||||
container.isSharingLimitReached().test {
|
||||
container.isSharingLimitReached(flowOf(permissions)).test {
|
||||
val result = awaitItem()
|
||||
assertEquals(
|
||||
expected = false,
|
||||
|
@ -87,27 +98,32 @@ class SpaceViewSubscriptionContainerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should reach limit if limit is 1 and there is one shared space already`() = runTest {
|
||||
fun `should reach limit if limit is 1 and there is one shared space already where user is owner`() = runTest {
|
||||
|
||||
val defaultSpaceView = StubSpaceView(
|
||||
sharedSpaceLimit = 1,
|
||||
spaceAccessType = SpaceAccessType.DEFAULT
|
||||
)
|
||||
|
||||
val privateSpaceView = StubSpaceView(
|
||||
val sharedSpaceView = StubSpaceView(
|
||||
sharedSpaceLimit = 0,
|
||||
spaceAccessType = SpaceAccessType.SHARED
|
||||
)
|
||||
|
||||
val permissions = mapOf(
|
||||
defaultSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER,
|
||||
sharedSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER
|
||||
)
|
||||
|
||||
container.stub {
|
||||
on {
|
||||
observe()
|
||||
} doReturn flowOf(
|
||||
listOf(defaultSpaceView, privateSpaceView)
|
||||
listOf(defaultSpaceView, sharedSpaceView)
|
||||
)
|
||||
}
|
||||
|
||||
container.isSharingLimitReached().test {
|
||||
container.isSharingLimitReached(flowOf(permissions)).test {
|
||||
val result = awaitItem()
|
||||
assertEquals(
|
||||
expected = true,
|
||||
|
@ -118,7 +134,43 @@ class SpaceViewSubscriptionContainerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should not reach limit if limit is 2 and there is one shared space already`() = runTest {
|
||||
fun `should not reach limit if limit is 1 and there is one shared space already where user is owner`() = runTest {
|
||||
|
||||
val defaultSpaceView = StubSpaceView(
|
||||
sharedSpaceLimit = 1,
|
||||
spaceAccessType = SpaceAccessType.DEFAULT
|
||||
)
|
||||
|
||||
val sharedSpaceView = StubSpaceView(
|
||||
sharedSpaceLimit = 0,
|
||||
spaceAccessType = SpaceAccessType.SHARED
|
||||
)
|
||||
|
||||
val permissions = mapOf(
|
||||
defaultSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER,
|
||||
sharedSpaceView.targetSpaceId!! to SpaceMemberPermissions.READER
|
||||
)
|
||||
|
||||
container.stub {
|
||||
on {
|
||||
observe()
|
||||
} doReturn flowOf(
|
||||
listOf(defaultSpaceView, sharedSpaceView)
|
||||
)
|
||||
}
|
||||
|
||||
container.isSharingLimitReached(flowOf(permissions)).test {
|
||||
val result = awaitItem()
|
||||
assertEquals(
|
||||
expected = false,
|
||||
actual = result
|
||||
)
|
||||
awaitComplete()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should not reach limit if limit is 2 and there is one shared space already where user is owner`() = runTest {
|
||||
|
||||
val defaultSpaceView = StubSpaceView(
|
||||
sharedSpaceLimit = 2,
|
||||
|
@ -130,6 +182,11 @@ class SpaceViewSubscriptionContainerTest {
|
|||
spaceAccessType = SpaceAccessType.SHARED
|
||||
)
|
||||
|
||||
val permissions = mapOf(
|
||||
defaultSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER,
|
||||
privateSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER
|
||||
)
|
||||
|
||||
container.stub {
|
||||
on {
|
||||
observe()
|
||||
|
@ -138,7 +195,7 @@ class SpaceViewSubscriptionContainerTest {
|
|||
)
|
||||
}
|
||||
|
||||
container.isSharingLimitReached().test {
|
||||
container.isSharingLimitReached(flowOf(permissions)).test {
|
||||
val result = awaitItem()
|
||||
assertEquals(
|
||||
expected = false,
|
||||
|
@ -161,6 +218,11 @@ class SpaceViewSubscriptionContainerTest {
|
|||
spaceAccessType = SpaceAccessType.PRIVATE
|
||||
)
|
||||
|
||||
val permissions = mapOf(
|
||||
defaultSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER,
|
||||
privateSpaceView.targetSpaceId!! to SpaceMemberPermissions.OWNER
|
||||
)
|
||||
|
||||
container.stub {
|
||||
on {
|
||||
observe()
|
||||
|
@ -169,7 +231,7 @@ class SpaceViewSubscriptionContainerTest {
|
|||
)
|
||||
}
|
||||
|
||||
container.isSharingLimitReached().test {
|
||||
container.isSharingLimitReached(flowOf(permissions)).test {
|
||||
val result = awaitItem()
|
||||
assertEquals(
|
||||
expected = true,
|
||||
|
|
|
@ -75,7 +75,7 @@ class SpaceSettingsViewModel(
|
|||
combine(
|
||||
spaceViewContainer.observe(params.space),
|
||||
userPermissionProvider.observe(params.space),
|
||||
spaceViewContainer.isSharingLimitReached()
|
||||
spaceViewContainer.isSharingLimitReached(userPermissionProvider.all())
|
||||
) { spaceView, permission, shareLimitReached ->
|
||||
SpaceData(
|
||||
name = spaceView.name.orEmpty(),
|
||||
|
|
|
@ -363,20 +363,21 @@ fun PrivateSpaceSharing(
|
|||
.padding(start = 20.dp)
|
||||
.align(Alignment.CenterStart),
|
||||
text = stringResource(id = R.string.space_type_private_space),
|
||||
color = colorResource(id = R.color.text_primary),
|
||||
color = if (shareLimitReached)
|
||||
colorResource(id = R.color.text_secondary)
|
||||
else
|
||||
colorResource(id = R.color.text_primary),
|
||||
style = BodyRegular
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.align(Alignment.CenterEnd)
|
||||
) {
|
||||
if (!shareLimitReached) {
|
||||
Text(
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
text = stringResource(id = R.string.multiplayer_share),
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
style = BodyRegular
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
text = stringResource(id = R.string.multiplayer_share),
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
style = BodyRegular
|
||||
)
|
||||
Spacer(Modifier.width(10.dp))
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ic_arrow_forward),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue