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

DROID-574 Editor | Enhancement | Enable checking / unchecking link-to-object blocks referencing task objects (#2708)

* DROID-574 click on checkbox

* DROID-574 tests

* DROID-574 click on checkbox

* DROID-574 set object details

* DROID-574 rename

Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
Konstantin Ivanov 2022-11-16 16:08:31 +01:00 committed by GitHub
parent 9306f5d5aa
commit 613fc45b18
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 184 additions and 71 deletions

View file

@ -182,6 +182,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_VIDEO_PLACEHOLDER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_VIDEO_UPLOAD
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import timber.log.Timber
import java.util.*
@ -556,7 +557,18 @@ class BlockAdapter(
HOLDER_OBJECT_LINK_DEFAULT -> {
LinkToObject(
ItemBlockObjectLinkBinding.inflate(inflater, parent, false)
)
).apply {
objectIcon.checkbox.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val view = views[pos] as BlockView.LinkToObject.Default.Text
onLinkToObjectCheckedIconClicked(
target = view.id,
icon = view.icon
)
}
}
}
}
HOLDER_OBJECT_LINK_CARD_SMALL_ICON -> {
LinkToObjectCardSmallIcon(
@ -565,7 +577,18 @@ class BlockAdapter(
parent,
false
)
)
).apply {
objectIconView.checkbox.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val view = views[pos] as BlockView.LinkToObject.Default.Card.SmallIcon
onLinkToObjectCheckedIconClicked(
target = view.id,
icon = view.icon
)
}
}
}
}
HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON -> {
LinkToObjectCardMediumIcon(
@ -574,7 +597,18 @@ class BlockAdapter(
parent,
false
)
)
).apply {
objectIconView.checkbox.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val view = views[pos] as BlockView.LinkToObject.Default.Card.MediumIcon
onLinkToObjectCheckedIconClicked(
target = view.id,
icon = view.icon
)
}
}
}
}
HOLDER_OBJECT_LINK_CARD_SMALL_ICON_COVER -> {
LinkToObjectCardSmallIconCover(
@ -583,7 +617,19 @@ class BlockAdapter(
parent,
false
)
)
).apply {
objectIconView.checkbox.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val view =
views[pos] as BlockView.LinkToObject.Default.Card.SmallIconCover
onLinkToObjectCheckedIconClicked(
target = view.id,
icon = view.icon
)
}
}
}
}
HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON_COVER -> {
LinkToObjectCardMediumIconCover(
@ -592,7 +638,19 @@ class BlockAdapter(
parent,
false
)
)
).apply {
objectIconView.checkbox.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val view =
views[pos] as BlockView.LinkToObject.Default.Card.MediumIconCover
onLinkToObjectCheckedIconClicked(
target = view.id,
icon = view.icon
)
}
}
}
}
HOLDER_OBJECT_LINK_ARCHIVE -> {
LinkToObjectArchive(
@ -1548,4 +1606,15 @@ class BlockAdapter(
override fun provide(pos: Int): BlockView {
return blocks[pos]
}
private fun onLinkToObjectCheckedIconClicked(target: Id, icon: ObjectIcon) {
if (icon is ObjectIcon.Task) {
onClickListener(
ListenerType.LinkToObjectCheckboxUpdate(
target = target,
isChecked = icon.isChecked
)
)
}
}
}

View file

@ -39,7 +39,7 @@ class LinkToObject(
private val root = binding.root
private val container = binding.container
private val untitled = itemView.resources.getString(R.string.untitled)
private val objectIcon = binding.objectIconWidget
val objectIcon = binding.objectIconWidget
private val objectIconContainer = binding.iconObjectContainer
private val title = binding.text
private val description = binding.tvDescription

View file

@ -21,6 +21,7 @@ import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.SmartBlockType
import com.anytypeio.anytype.core_models.SyncStatus
import com.anytypeio.anytype.core_models.Url
@ -2886,8 +2887,8 @@ class EditorViewModel(
renderizePipeline.send(blocks)
}
private fun onPageClicked(block: Id) {
val block = blocks.firstOrNull { it.id == block }
private fun onPageClicked(blockLinkId: Id) {
val block = blocks.firstOrNull { it.id == blockLinkId }
when (val content = block?.content) {
is Content.Link -> {
proceedWithOpeningObjectByLayout(target = content.target)
@ -3542,8 +3543,8 @@ class EditorViewModel(
}
is ListenerType.LinkToObject -> {
when (mode) {
EditorMode.Edit -> onPageClicked(clicked.target)
EditorMode.Locked -> onPageClicked(clicked.target)
EditorMode.Edit -> onPageClicked(blockLinkId = clicked.target)
EditorMode.Locked -> onPageClicked(blockLinkId = clicked.target)
EditorMode.Select -> onBlockMultiSelectClicked(clicked.target)
else -> Unit
}
@ -3568,6 +3569,21 @@ class EditorViewModel(
else -> Unit
}
}
is ListenerType.LinkToObjectCheckboxUpdate -> {
when (mode) {
EditorMode.Edit -> {
val content = blocks.firstOrNull { it.id == clicked.target }?.content
if (content is Content.Link) {
proceedWithSetObjectDetails(
ctx = content.target,
key = Relations.DONE,
value = !clicked.isChecked
)
}
}
else -> Unit
}
}
is ListenerType.Mention -> {
when (mode) {
EditorMode.Edit, EditorMode.Locked -> {
@ -3711,29 +3727,11 @@ class EditorViewModel(
Relation.Format.CHECKBOX -> {
val view = clicked.relation
if (view is DocumentRelationView.Checkbox) {
viewModelScope.launch {
updateDetail(
UpdateDetail.Params(
ctx = context,
key = relationId,
value = !view.isChecked
)
).process(
success = {
dispatcher.send(it)
sendAnalyticsRelationValueEvent(
analytics = analytics,
context = analyticsContext
)
},
failure = {
Timber.e(
it,
"Error while updating relation values"
)
}
)
}
proceedWithSetObjectDetails(
ctx = context,
key = relationId,
value = !view.isChecked
)
}
}
Relation.Format.DATE -> {
@ -3882,25 +3880,12 @@ class EditorViewModel(
value: BlockView.Relation.Related,
relation: Id
) {
viewModelScope.launch {
val view = value.view as DocumentRelationView.Checkbox
updateDetail(
UpdateDetail.Params(
ctx = context,
key = relation,
value = !view.isChecked
)
).process(
success = {
dispatcher.send(it)
sendAnalyticsRelationValueEvent(
analytics = analytics,
context = analyticsContext
)
},
failure = { Timber.e(it, "Error while updating relation values") }
)
}
val view = value.view as DocumentRelationView.Checkbox
proceedWithSetObjectDetails(
ctx = context,
key = relation,
value = !view.isChecked
)
}
override fun onProceedWithFilePath(filePath: String?) {
@ -4087,6 +4072,29 @@ class EditorViewModel(
}
}
private fun proceedWithSetObjectDetails(ctx: Id, key: String, value: Any?) {
viewModelScope.launch {
updateDetail(
UpdateDetail.Params(
ctx = ctx,
key = key,
value = value
)
).process(
success = {
dispatcher.send(it)
sendAnalyticsRelationValueEvent(
analytics = analytics,
context = analyticsContext
)
},
failure = {
Timber.e(it, "Error while set object details")
}
)
}
}
private fun sendToast(msg: String) {
jobs += viewModelScope.launch {
_toasts.emit(msg)
@ -4147,24 +4155,11 @@ class EditorViewModel(
relationId: Id
) {
Timber.d("onRelationTextValueChanged, ctx:[$ctx] value:[$value] relationId:[$relationId]")
viewModelScope.launch {
updateDetail(
UpdateDetail.Params(
ctx = ctx,
key = relationId,
value = value
)
).process(
success = {
dispatcher.send(it)
sendAnalyticsRelationValueEvent(
analytics = analytics,
context = analyticsContext
)
},
failure = { Timber.e(it, "Error while updating relation values") }
)
}
proceedWithSetObjectDetails(
ctx = ctx,
key = relationId,
value = value
)
}
fun onObjectTypeChanged(type: Id, isObjectDraft: Boolean) {

View file

@ -54,6 +54,7 @@ sealed interface ListenerType {
data class LinkToObjectArchived(val target: String) : ListenerType
data class LinkToObjectDeleted(val target: String) : ListenerType
data class LinkToObjectLoading(val target: String) : ListenerType
data class LinkToObjectCheckboxUpdate(val target: Id, val isChecked: Boolean) : ListenerType
data class Mention(val target: String) : ListenerType

View file

@ -61,7 +61,55 @@ class LinkAppearanceMenuTest {
}
@Test
fun `when is todo note - no icon and no description`() {
fun `when is todo layout and card style without cover - no icon`() {
val factory = LinkAppearanceFactory(
content = StubLinkContent(
iconSize = Link.IconSize.SMALL,
cardStyle = Link.CardStyle.CARD,
description = Link.Description.NONE,
relations = setOf(Link.Relation.NAME)
),
layout = ObjectType.Layout.TODO
)
val actual = factory.createAppearanceMenuItems()
val expected = BlockView.Appearance.Menu(
preview = MenuItem.PreviewLayout.CARD,
icon = null,
cover = MenuItem.Cover.WITHOUT,
description = MenuItem.Description.NONE,
objectType = MenuItem.ObjectType.WITHOUT,
iconMenus = listOf()
)
assertEquals(expected, actual)
}
@Test
fun `when is todo layout and card style with cover - no icon`() {
val factory = LinkAppearanceFactory(
content = StubLinkContent(
iconSize = Link.IconSize.SMALL,
cardStyle = Link.CardStyle.CARD,
description = Link.Description.NONE,
relations = setOf(Link.Relation.NAME, Link.Relation.COVER)
),
layout = ObjectType.Layout.TODO
)
val actual = factory.createAppearanceMenuItems()
val expected = BlockView.Appearance.Menu(
preview = MenuItem.PreviewLayout.CARD,
icon = null,
cover = MenuItem.Cover.WITH,
description = MenuItem.Description.NONE,
objectType = MenuItem.ObjectType.WITHOUT,
iconMenus = listOf()
)
assertEquals(expected, actual)
}
@Test
fun `when is note - no icon and no description`() {
val factory = LinkAppearanceFactory(
content = defaultLinkAppearance.copy(
description = Link.Description.ADDED