mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-291 Editor | Enhancement | Add block action "Open object" for bookmark block in editor (#2498)
This commit is contained in:
parent
5f886a0a8b
commit
a7940a5ae2
15 changed files with 71 additions and 73 deletions
|
@ -146,6 +146,7 @@ object EventsDictionary {
|
|||
const val preview = "Preview"
|
||||
const val copy = "Copy"
|
||||
const val paste = "Paste"
|
||||
const val openObject = "OpenObject"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.anytypeio.anytype.core_models.Event
|
|||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Position
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.StubBookmark
|
||||
import com.anytypeio.anytype.core_ui.features.editor.slash.holders.MainMenuHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.slash.holders.MediaMenuHolder
|
||||
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
|
||||
|
@ -768,14 +769,7 @@ class SlashWidgetTesting : EditorTestSetup() {
|
|||
val paragraph = paragraph(text = "FooBar")
|
||||
val paragraph2 = paragraph(text = "Second")
|
||||
|
||||
val bookmark = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Bookmark(
|
||||
null, null, null, null, null
|
||||
)
|
||||
)
|
||||
val bookmark = StubBookmark()
|
||||
|
||||
val page = Block(
|
||||
id = root,
|
||||
|
|
|
@ -1807,7 +1807,7 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
).apply {
|
||||
duration = SELECT_BUTTON_HIDE_ANIMATION_DURATION
|
||||
interpolator = DecelerateInterpolator()
|
||||
doOnEnd { binding.topToolbar.visible() }
|
||||
doOnEnd { if (hasBinding) binding.topToolbar.visible() }
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,7 +263,8 @@ data class Block(
|
|||
val title: String?,
|
||||
val description: String?,
|
||||
val image: Hash?,
|
||||
val favicon: Hash?
|
||||
val favicon: Hash?,
|
||||
val targetObjectId: Id?
|
||||
) : Content()
|
||||
|
||||
data class Divider(val style: Style) : Content() {
|
||||
|
|
|
@ -122,6 +122,10 @@ class BlockActionWidget @JvmOverloads constructor(
|
|||
title.setText(R.string.paste)
|
||||
icon.setImageResource(R.drawable.ic_block_action_paste)
|
||||
}
|
||||
ActionItemType.OpenObject -> {
|
||||
title.setText(R.string.open_object)
|
||||
icon.setImageResource(R.drawable.ic_action_open_object)
|
||||
}
|
||||
else -> {
|
||||
title.text = action::class.simpleName
|
||||
}
|
||||
|
|
10
core-ui/src/main/res/drawable/ic_action_open_object.xml
Normal file
10
core-ui/src/main/res/drawable/ic_action_open_object.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M22,2V2.063V3.5V10.313C22,10.727 21.664,11.063 21.25,11.063C20.836,11.063 20.5,10.727 20.5,10.313V4.615L14.028,11.033L12.972,9.967L19.494,3.5H13.75C13.336,3.5 13,3.164 13,2.75C13,2.336 13.336,2 13.75,2H22ZM11.03,14.03L4.498,20.563H10.25C10.664,20.563 11,20.898 11,21.313C11,21.727 10.664,22.063 10.25,22.063H2V22V20.563V13.75C2,13.336 2.336,13 2.75,13C3.164,13 3.5,13.336 3.5,13.75V19.439L9.97,12.97L11.03,14.03Z"
|
||||
android:fillColor="@color/glyph_active"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -543,5 +543,6 @@
|
|||
<string name="simple_tables_widget_tab_cell">Cell</string>
|
||||
<string name="simple_tables_widget_tab_row">Row</string>
|
||||
<string name="simple_tables_widget_tab_column">Column</string>
|
||||
<string name="open_object">Open object</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -23,6 +23,7 @@ abstract class BaseFragment<T : ViewBinding>(
|
|||
|
||||
private var _binding: T? = null
|
||||
val binding: T get() = _binding!!
|
||||
val hasBinding get() = _binding != null
|
||||
|
||||
protected val jobs = mutableListOf<Job>()
|
||||
|
||||
|
|
|
@ -285,7 +285,8 @@ fun MBlock.toCoreModelsBookmark(): Block.Content.Bookmark {
|
|||
title = content.title.ifEmpty { null },
|
||||
description = content.description.ifEmpty { null },
|
||||
image = content.imageHash.ifEmpty { null },
|
||||
favicon = content.faviconHash.ifEmpty { null }
|
||||
favicon = content.faviconHash.ifEmpty { null },
|
||||
targetObjectId = content.targetObjectId.ifEmpty { null }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1664,6 +1664,7 @@ class EditorViewModel(
|
|||
excludedActions.add(ActionItemType.AddBelow)
|
||||
excludedActions.add(ActionItemType.Divider)
|
||||
excludedActions.add(ActionItemType.DividerExtended)
|
||||
excludedActions.add(ActionItemType.OpenObject)
|
||||
}
|
||||
|
||||
var needSortByDownloads = false
|
||||
|
@ -1673,6 +1674,12 @@ class EditorViewModel(
|
|||
when (val content = block.content) {
|
||||
is Content.Bookmark -> {
|
||||
excludedActions.add(ActionItemType.Download)
|
||||
if (!isMultiMode) {
|
||||
val idx = targetActions.indexOf(ActionItemType.OpenObject)
|
||||
if (idx == NO_POSITION) {
|
||||
targetActions.add(OPEN_OBJECT_POSITION, ActionItemType.OpenObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
is Content.Divider -> {
|
||||
excludedActions.add(ActionItemType.Download)
|
||||
|
@ -5126,12 +5133,34 @@ class EditorViewModel(
|
|||
proceedWithExitingMultiSelectMode()
|
||||
onSendBlockActionAnalyticsEvent(EventsDictionary.BlockAction.paste)
|
||||
}
|
||||
ActionItemType.OpenObject -> {
|
||||
val selected = blocks.firstOrNull { currentSelection().contains(it.id) }
|
||||
proceedWithExitingMultiSelectMode()
|
||||
if (selected != null) {
|
||||
proceedWithMultiSelectOpenObjectAction(
|
||||
selected = selected
|
||||
)
|
||||
} else {
|
||||
sendToast("No blocks were selected. Please, try again.")
|
||||
}
|
||||
onSendBlockActionAnalyticsEvent(EventsDictionary.BlockAction.openObject)
|
||||
}
|
||||
else -> {
|
||||
sendToast("TODO")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithMultiSelectOpenObjectAction(selected: Block) {
|
||||
when (val content = selected.content) {
|
||||
is Content.Bookmark -> {
|
||||
val target = content.targetObjectId
|
||||
if (target != null) { proceedWithOpeningPage(target) }
|
||||
}
|
||||
else -> sendToast("Unexpected object")
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSendBlockActionAnalyticsEvent(type: String) {
|
||||
viewModelScope.launch {
|
||||
sendAnalyticsBlockActionEvent(
|
||||
|
@ -5932,4 +5961,5 @@ class EditorViewModel(
|
|||
}
|
||||
|
||||
private const val NO_POSITION = -1
|
||||
private const val PREVIEW_POSITION = 2
|
||||
private const val PREVIEW_POSITION = 2
|
||||
private const val OPEN_OBJECT_POSITION = 2
|
|
@ -18,6 +18,7 @@ sealed class ActionItemType {
|
|||
object Preview : ActionItemType()
|
||||
object Copy : ActionItemType()
|
||||
object Paste : ActionItemType()
|
||||
object OpenObject: ActionItemType()
|
||||
|
||||
companion object {
|
||||
val defaultSorting = listOf(
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.presentation.editor
|
|||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link.IconSize
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.StubBookmark
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory
|
||||
|
@ -31,18 +32,7 @@ class DocumentExternalEventReducerTest {
|
|||
)
|
||||
)
|
||||
|
||||
val bookmark = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Bookmark(
|
||||
url = null,
|
||||
description = null,
|
||||
title = null,
|
||||
favicon = null,
|
||||
image = null
|
||||
)
|
||||
)
|
||||
val bookmark = StubBookmark()
|
||||
|
||||
val page = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
|
@ -168,18 +158,7 @@ class DocumentExternalEventReducerTest {
|
|||
)
|
||||
)
|
||||
|
||||
val bookmark = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Bookmark(
|
||||
url = null,
|
||||
description = null,
|
||||
title = null,
|
||||
favicon = null,
|
||||
image = null
|
||||
)
|
||||
)
|
||||
val bookmark = StubBookmark()
|
||||
|
||||
val page = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.anytypeio.anytype.core_models.Event
|
|||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.RelationFormat
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.StubBookmark
|
||||
import com.anytypeio.anytype.core_models.StubBulleted
|
||||
import com.anytypeio.anytype.core_models.StubCheckbox
|
||||
import com.anytypeio.anytype.core_models.StubDescription
|
||||
|
@ -456,18 +457,7 @@ class EditorBackspaceDeleteTest : EditorPresentationTestSetup() {
|
|||
|
||||
// SETUP
|
||||
|
||||
val bookmark = Block(
|
||||
id = MockDataFactory.randomString(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Bookmark(
|
||||
url = MockDataFactory.randomString(),
|
||||
description = MockDataFactory.randomString(),
|
||||
title = MockDataFactory.randomString(),
|
||||
favicon = null,
|
||||
image = null
|
||||
)
|
||||
)
|
||||
val bookmark = StubBookmark()
|
||||
|
||||
val paragraph = Block(
|
||||
id = MockDataFactory.randomString(),
|
||||
|
@ -569,18 +559,7 @@ class EditorBackspaceDeleteTest : EditorPresentationTestSetup() {
|
|||
|
||||
// SETUP
|
||||
|
||||
val bookmark = Block(
|
||||
id = MockDataFactory.randomString(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Bookmark(
|
||||
url = MockDataFactory.randomString(),
|
||||
description = MockDataFactory.randomString(),
|
||||
title = MockDataFactory.randomString(),
|
||||
favicon = null,
|
||||
image = null
|
||||
)
|
||||
)
|
||||
val bookmark = StubBookmark()
|
||||
|
||||
val paragraph = Block(
|
||||
id = MockDataFactory.randomString(),
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.SmartBlockType
|
||||
import com.anytypeio.anytype.core_models.StubBookmark
|
||||
import com.anytypeio.anytype.core_models.StubTitle
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
|
@ -466,17 +467,10 @@ class EditorLockPageTest : EditorPresentationTestSetup() {
|
|||
val bookmarkDescription = "Operating system for life"
|
||||
val bookmarkTitle = "Anytype"
|
||||
|
||||
val bookmark = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(emptyMap()),
|
||||
content = Block.Content.Bookmark(
|
||||
description = bookmarkDescription,
|
||||
url = bookmarkUrl,
|
||||
favicon = null,
|
||||
image = null,
|
||||
title = bookmarkTitle
|
||||
),
|
||||
children = emptyList()
|
||||
val bookmark = StubBookmark(
|
||||
url = bookmarkUrl,
|
||||
description = bookmarkDescription,
|
||||
title = bookmarkTitle
|
||||
)
|
||||
|
||||
val page = listOf(
|
||||
|
|
|
@ -213,7 +213,8 @@ fun StubBookmark(
|
|||
favicon: Hash? = null,
|
||||
title: String? = MockDataFactory.randomString(),
|
||||
fields: Block.Fields = Block.Fields.empty(),
|
||||
backgroundColor: String? = null
|
||||
backgroundColor: String? = null,
|
||||
targetObjectId: Id? = null
|
||||
): Block = Block(
|
||||
id = id,
|
||||
content = Block.Content.Bookmark(
|
||||
|
@ -221,7 +222,8 @@ fun StubBookmark(
|
|||
url = url,
|
||||
description = description,
|
||||
image = image,
|
||||
favicon = favicon
|
||||
favicon = favicon,
|
||||
targetObjectId = targetObjectId
|
||||
),
|
||||
children = emptyList(),
|
||||
fields = fields,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue