From 1cb82f4c64594ec358de863e699c0afe771284d2 Mon Sep 17 00:00:00 2001 From: Konstantin Ivanov <54908981+konstantiniiv@users.noreply.github.com> Date: Wed, 10 Aug 2022 20:56:25 +0200 Subject: [PATCH] DROID-285 Editor | Table of contents placeholder and clicks (#2499) * DROID-285 toc item, add editor touch processor * DROID-285 add toc placeholder + click fixes * DROID-285 toc click listener type * DROID-285 block adapter toc fixes * DROID-285 toc selection, action menu and clicks Co-authored-by: konstantiniiv --- .../core_ui/features/editor/BlockAdapter.kt | 8 ++--- .../editor/holders/other/TableOfContents.kt | 31 +++++++++++++++++-- .../widgets/text/TableOfContentsItemWidget.kt | 6 ++++ .../src/main/res/layout/item_block_toc.xml | 14 ++++++++- .../presentation/editor/EditorViewModel.kt | 16 +++++++++- .../editor/editor/listener/ListenerType.kt | 1 + 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt index 7d27066bde..5eedd7d3a4 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt @@ -688,7 +688,8 @@ class BlockAdapter( } HOLDER_TOC -> { TableOfContents( - ItemBlockTocBinding.inflate(inflater, parent, false) + binding = ItemBlockTocBinding.inflate(inflater, parent, false), + onDragAndDropTrigger = onDragAndDropTrigger ) } HOLDER_UNSUPPORTED -> Unsupported( @@ -765,11 +766,6 @@ class BlockAdapter( onDragAndDropTrigger(holder, it) } } - is TableOfContents -> { - holder.editorTouchProcessor.onDragAndDropTrigger = { - onDragAndDropTrigger(holder, it) - } - } else -> { holder.itemView.setOnLongClickListener { val pos = holder.bindingAdapterPosition diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/TableOfContents.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/TableOfContents.kt index 171057e6f6..4adb8a86e9 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/TableOfContents.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/TableOfContents.kt @@ -1,8 +1,11 @@ package com.anytypeio.anytype.core_ui.features.editor.holders.other +import android.view.MotionEvent +import android.view.View import android.widget.FrameLayout import android.widget.LinearLayout import androidx.core.view.ViewCompat.generateViewId +import androidx.recyclerview.widget.RecyclerView import com.anytypeio.anytype.core_ui.R import com.anytypeio.anytype.core_ui.databinding.ItemBlockTocBinding import com.anytypeio.anytype.core_ui.extensions.setBlockBackgroundColor @@ -14,33 +17,52 @@ import com.anytypeio.anytype.core_ui.features.editor.EditorTouchProcessor import com.anytypeio.anytype.core_ui.features.editor.SupportCustomTouchProcessor import com.anytypeio.anytype.core_ui.widgets.text.TableOfContentsItemWidget import com.anytypeio.anytype.core_models.ThemeColor +import com.anytypeio.anytype.core_utils.ext.gone +import com.anytypeio.anytype.core_utils.ext.visible import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType import com.anytypeio.anytype.presentation.editor.editor.model.BlockView class TableOfContents( - val binding: ItemBlockTocBinding + private val binding: ItemBlockTocBinding, + private val onDragAndDropTrigger: (RecyclerView.ViewHolder, event: MotionEvent?) -> Boolean ) : BlockViewHolder(binding.root), BlockViewHolder.DragAndDropHolder, SupportCustomTouchProcessor { val root: FrameLayout = binding.root val container: LinearLayout = binding.container + val placeholder: View = binding.placeholder private val selected = binding.selected private val defPadding = root.resources.getDimension(R.dimen.def_toc_item_padding_start).toInt() override val editorTouchProcessor = EditorTouchProcessor( - fallback = { e -> itemView.onTouchEvent(e) } + fallback = { e -> root.onTouchEvent(e) } ) + init { + root.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) } + } + fun bind(item: BlockView.TableOfContents, clicked: (ListenerType) -> Unit) { + cleanup() selected.isSelected = item.isSelected + if (item.items.isNotEmpty()) { + placeholder.gone() + } else { + placeholder.visible() + } item.items.forEach { header -> val textview = TableOfContentsItemWidget(root.context).apply { id = generateViewId() setPadding(getPadding(header.depth), 0, 0, 0) setName(header.name) - setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) } + this.editorTouchProcessor.onLongClick = { + clicked.invoke(ListenerType.LongClick(target = item.id)) + } + this.editorTouchProcessor.onDragAndDropTrigger = { + onDragAndDropTrigger(this@TableOfContents, it) + } setOnClickListener { clicked.invoke( ListenerType.TableOfContentsItem( @@ -53,6 +75,9 @@ class TableOfContents( container.addView(textview) } applyBackground(item.background) + root.setOnClickListener { + clicked(ListenerType.TableOfContents(target = item.id)) + } } private fun applyBackground(background: ThemeColor) { diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/TableOfContentsItemWidget.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/TableOfContentsItemWidget.kt index e87a2b7c30..fdd2de660f 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/TableOfContentsItemWidget.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/TableOfContentsItemWidget.kt @@ -7,6 +7,7 @@ import android.view.LayoutInflater import android.widget.FrameLayout import com.anytypeio.anytype.core_ui.R import com.anytypeio.anytype.core_ui.databinding.TvTableOfContentsBinding +import com.anytypeio.anytype.core_ui.features.editor.EditorTouchProcessor class TableOfContentsItemWidget @JvmOverloads constructor( context: Context, @@ -17,9 +18,14 @@ class TableOfContentsItemWidget @JvmOverloads constructor( val binding = TvTableOfContentsBinding.inflate(LayoutInflater.from(context), this) val textView = binding.text + val editorTouchProcessor = EditorTouchProcessor( + fallback = { e -> this.onTouchEvent(e) } + ) + init { textView.apply { paintFlags = Paint.UNDERLINE_TEXT_FLAG + setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) } } } diff --git a/core-ui/src/main/res/layout/item_block_toc.xml b/core-ui/src/main/res/layout/item_block_toc.xml index 0cd2b7aeb9..910453f980 100644 --- a/core-ui/src/main/res/layout/item_block_toc.xml +++ b/core-ui/src/main/res/layout/item_block_toc.xml @@ -4,7 +4,9 @@ android:id="@+id/root" style="@style/DefaultTableOfContentsBlockRootStyle" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:clickable="true" + android:longClickable="true"> + + select(child) } @@ -1717,6 +1717,11 @@ class EditorViewModel( excludedActions.add(ActionItemType.Copy) excludedActions.add(ActionItemType.Style) } + is Content.TableOfContents -> { + excludedActions.add(ActionItemType.Paste) + excludedActions.add(ActionItemType.Copy) + excludedActions.add(ActionItemType.Style) + } else -> { // do nothing } @@ -2881,6 +2886,9 @@ class EditorViewModel( is Content.Table -> { addNewBlockAtTheEnd() } + is Content.TableOfContents -> { + addNewBlockAtTheEnd() + } else -> { Timber.d("Outside-click has been ignored.") } @@ -3794,6 +3802,12 @@ class EditorViewModel( else -> Unit } } + is ListenerType.TableOfContents -> { + when (mode) { + EditorMode.Select -> onBlockMultiSelectClicked(clicked.target) + else -> Unit + } + } is ListenerType.Callout.Icon -> { dispatch(Command.OpenTextBlockIconPicker(clicked.blockId)) } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/listener/ListenerType.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/listener/ListenerType.kt index 250c100344..40b4aae979 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/listener/ListenerType.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/listener/ListenerType.kt @@ -68,6 +68,7 @@ sealed interface ListenerType { } data class TableOfContentsItem(val target: Id, val item: Id) : ListenerType + data class TableOfContents(val target: Id) : ListenerType data class TableEmptyCell(val cellId: Id, val rowId: Id, val tableId: Id) : ListenerType data class TableTextCell(val cellId: Id, val tableId: Id) : ListenerType data class TableEmptyCellMenu(val rowId: Id, val columnId: Id) : ListenerType