mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
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 <ki@anytype.io>
This commit is contained in:
parent
7ed2842766
commit
1cb82f4c64
6 changed files with 65 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
|
@ -14,6 +16,16 @@
|
|||
android:layout_marginEnd="@dimen/dp_12"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/placeholder"
|
||||
style="@style/BlockTextContentStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:longClickable="false"
|
||||
android:text="Add headings to create a table of contents"
|
||||
android:textColor="@color/editor_default_hint_text_color" />
|
||||
|
||||
<View
|
||||
android:id="@+id/selected"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1620,7 +1620,7 @@ class EditorViewModel(
|
|||
|
||||
toggleSelection(target)
|
||||
|
||||
if (view !is BlockView.Table) {
|
||||
if (view !is BlockView.Table && view !is BlockView.TableOfContents) {
|
||||
val descendants = blocks.asMap().descendants(parent = target)
|
||||
if (isSelected(target)) {
|
||||
descendants.forEach { child -> 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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue