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

DROID-3281 Objects | Enhancement | Always show three-dots menu, but apply space member permissions - part 2 (#2023)

This commit is contained in:
Evgenii Kozlov 2025-01-22 22:38:32 +01:00 committed by Evgenii Kozlov
parent 21393f4ec3
commit 0114a4f968
15 changed files with 64 additions and 30 deletions

View file

@ -247,6 +247,7 @@ import com.anytypeio.anytype.presentation.objects.ObjectTypeView
import com.anytypeio.anytype.core_models.SupportedLayouts
import com.anytypeio.anytype.core_models.TimeInMillis
import com.anytypeio.anytype.core_models.TimeInSeconds
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Event.SAM.*
import com.anytypeio.anytype.presentation.editor.editor.Intent.Clipboard.*
import com.anytypeio.anytype.presentation.editor.editor.ext.isAllowedToShowTypesWidget
@ -1553,6 +1554,9 @@ class EditorViewModel(
sendToast("Space not found")
return
}
val isReadOnly = permission.value == null
|| permission.value == SpaceMemberPermissions.NO_PERMISSIONS
|| permission.value == SpaceMemberPermissions.READER
when {
isTemplate -> {
dispatch(
@ -1562,7 +1566,8 @@ class EditorViewModel(
isArchived = false,
isFavorite = false,
isLocked = false,
isTemplate = true
isTemplate = true,
isReadOnly = isReadOnly
)
)
}
@ -1573,7 +1578,8 @@ class EditorViewModel(
space = space,
isArchived = details[context]?.isArchived ?: false,
isFavorite = details[context]?.isFavorite ?: false,
isLocked = mode == EditorMode.Locked || mode == EditorMode.Read,
isLocked = mode == EditorMode.Locked,
isReadOnly = isReadOnly,
isTemplate = isObjectTemplate()
)
)

View file

@ -67,6 +67,7 @@ sealed class Command {
val isArchived: Boolean,
val isFavorite: Boolean,
val isLocked: Boolean,
val isReadOnly: Boolean,
val isTemplate: Boolean
) : Command()

View file

@ -33,5 +33,5 @@ interface ObjectMenuOptionsProvider {
}
}
fun provide(ctx: Id, isLocked: Boolean): Flow<Options>
fun provide(ctx: Id, isLocked: Boolean, isReadOnly: Boolean): Flow<Options>
}

View file

@ -31,9 +31,14 @@ class ObjectMenuOptionsProviderImpl(
ObjectWrapper.Basic(fields.map).layout
}
override fun provide(ctx: Id, isLocked: Boolean): Flow<Options> {
override fun provide(ctx: Id, isLocked: Boolean, isReadOnly: Boolean): Flow<Options> {
return combine(observeLayout(ctx), restrictions) { layout, restrictions ->
createOptions(layout, restrictions, isLocked)
createOptions(
layout = layout,
restrictions = restrictions,
isLocked = isLocked,
isReadOnly = isReadOnly
)
}
}
@ -41,10 +46,11 @@ class ObjectMenuOptionsProviderImpl(
layout: ObjectType.Layout?,
restrictions: List<ObjectRestriction>,
isLocked: Boolean,
isReadOnly: Boolean
): Options {
val hasIcon = !isLocked
val hasCover = !isLocked
val hasLayout = !isLocked && !restrictions.contains(ObjectRestriction.LAYOUT_CHANGE)
val hasIcon = !isLocked && !isReadOnly
val hasCover = !isLocked && !isReadOnly
val hasLayout = !isLocked && !restrictions.contains(ObjectRestriction.LAYOUT_CHANGE) && !isReadOnly
val options = if (layout != null) {
when (layout) {
ObjectType.Layout.PARTICIPANT -> Options.ALL.copy(
@ -72,7 +78,7 @@ class ObjectMenuOptionsProviderImpl(
hasCover = hasCover,
hasLayout = false,
hasDiagnosticsVisibility = true,
hasHistory = !isLocked
hasHistory = !isLocked && !isReadOnly
)
}
ObjectType.Layout.BASIC,
@ -82,7 +88,7 @@ class ObjectMenuOptionsProviderImpl(
hasCover = hasCover,
hasLayout = hasLayout,
hasDiagnosticsVisibility = true,
hasHistory = !isLocked
hasHistory = !isLocked && !isReadOnly
)
ObjectType.Layout.TODO -> Options(
hasIcon = false,
@ -90,7 +96,7 @@ class ObjectMenuOptionsProviderImpl(
hasLayout = hasLayout,
hasRelations = true,
hasDiagnosticsVisibility = true,
hasHistory = !isLocked
hasHistory = !isLocked && !isReadOnly
)
ObjectType.Layout.NOTE -> Options(
@ -99,7 +105,7 @@ class ObjectMenuOptionsProviderImpl(
hasLayout = hasLayout,
hasRelations = true,
hasDiagnosticsVisibility = true,
hasHistory = !isLocked
hasHistory = !isLocked && !isReadOnly
)
else -> Options.NONE.copy(
hasDiagnosticsVisibility = true

View file

@ -108,20 +108,20 @@ class ObjectMenuViewModel(
isArchived: Boolean,
isFavorite: Boolean,
isTemplate: Boolean,
isLocked: Boolean
isLocked: Boolean,
isReadOnly: Boolean
): List<ObjectAction> = buildList {
val wrapper = ObjectWrapper.Basic(storage.details.current().details[ctx]?.map.orEmpty())
val layout = wrapper.layout
if (isLocked) {
if (isReadOnly) {
add(ObjectAction.COPY_LINK)
add(ObjectAction.SEARCH_ON_PAGE)
if (layout in fileLayouts) {
add(ObjectAction.DOWNLOAD_FILE)
}
} else {
if (!isTemplate) {
if (isFavorite) {
add(ObjectAction.REMOVE_FROM_FAVOURITE)

View file

@ -111,18 +111,22 @@ abstract class ObjectMenuViewModelBase(
isFavorite: Boolean,
isArchived: Boolean,
isLocked: Boolean,
isTemplate: Boolean
isTemplate: Boolean,
isReadOnly: Boolean
) {
Timber.d("ObjectMenuViewModelBase, onStart, ctx:[$ctx], isFavorite:[$isFavorite], isArchived:[$isArchived], isLocked:[$isLocked]")
Timber.d("ObjectMenuViewModelBase, onStart, ctx:[$ctx], isFavorite:[$isFavorite], isArchived:[$isArchived], isLocked:[$isLocked], isReadOnly: [$isReadOnly]")
actions.value = buildActions(
ctx = ctx,
isArchived = isArchived,
isFavorite = isFavorite,
isTemplate = isTemplate,
isLocked = isLocked
isLocked = isLocked,
isReadOnly = isReadOnly
)
jobs += viewModelScope.launch {
menuOptionsProvider.provide(ctx, isLocked).collect(_options)
menuOptionsProvider
.provide(ctx = ctx, isLocked = isLocked, isReadOnly = isReadOnly)
.collect(_options)
}
}
@ -133,7 +137,8 @@ abstract class ObjectMenuViewModelBase(
isArchived: Boolean,
isFavorite: Boolean,
isTemplate: Boolean = false,
isLocked: Boolean
isLocked: Boolean,
isReadOnly: Boolean
): List<ObjectAction>
protected fun proceedWithRemovingFromFavorites(ctx: Id) {

View file

@ -180,9 +180,10 @@ class ObjectSetMenuViewModel(
isArchived: Boolean,
isFavorite: Boolean,
isTemplate: Boolean,
isLocked: Boolean
isLocked: Boolean,
isReadOnly: Boolean
): List<ObjectAction> = buildList {
if (!isLocked) {
if (!isReadOnly) {
if (isArchived) {
add(ObjectAction.RESTORE)
} else {

View file

@ -12,7 +12,7 @@ sealed class ObjectSetCommand {
val space: Id,
val isArchived: Boolean,
val isFavorite: Boolean,
val isLocked: Boolean
val isReadOnly: Boolean
) : Modal()
data class OpenSettings(

View file

@ -1252,7 +1252,7 @@ class ObjectSetViewModel(
space = space,
isArchived = state.details[vmParams.ctx]?.isArchived ?: false,
isFavorite = state.details[vmParams.ctx]?.isFavorite ?: false,
isLocked = !isOwnerOrEditor
isReadOnly = !isOwnerOrEditor
)
)
} else {

View file

@ -101,7 +101,8 @@ class EditorMenuTest : EditorPresentationTestSetup() {
isLocked = false,
isTemplate = false,
space = defaultSpace,
ctx = root
ctx = root,
isReadOnly = false
)
}
}
@ -156,6 +157,7 @@ class EditorMenuTest : EditorPresentationTestSetup() {
isArchived = false,
isFavorite = false,
isLocked = false,
isReadOnly = false,
isTemplate = false,
space = space,
ctx = root
@ -236,6 +238,7 @@ class EditorMenuTest : EditorPresentationTestSetup() {
value.peekContent() == Command.OpenDocumentMenu(
isFavorite = false,
isLocked = false,
isReadOnly = false,
isArchived = false,
isTemplate = false,
space = space,

View file

@ -119,9 +119,14 @@ class ObjectMenuOptionsProviderImplTest {
private fun assertOptions(
expected: ObjectMenuOptionsProvider.Options,
isLocked: Boolean = false,
isReadOnly: Boolean = false
) {
runTest {
provider.provide(objectId, isLocked).test {
provider.provide(
objectId,
isLocked = isLocked,
isReadOnly = isReadOnly
).test {
assertEquals(
expected = expected,
actual = awaitItem()