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

DROID-445 Editor | Simple tables, dynamic cell height integration (#2626)

* DROID-445 feature toggle added

* DROID-445 custom grid layout manager as container

* DROID-445 split get span count

* DROID-445 editable cells adapter + holder

* DROID-445 selection and focus listeners

* DROID-445 show cell menu on cell click

* DROID-445 editable cell adapter added

* DROID-445 editor, cell clicks + focus

* DROID-445 fix adapter update

* DROID-445 after develop merge fixes

* DROID-445 fixes

* DROID-445 select cell on focus change

* DROID-445 test update

* DROID-445 turn off editable cells

* DROID-445 ci

* DROID-445 turn on editing cell

* DROID-445 fix test

* DROID-445 ci off

Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
Konstantin Ivanov 2022-10-17 17:29:34 +02:00 committed by GitHub
parent 16293155e0
commit f97fa3ab4c
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 504 additions and 68 deletions

View file

@ -744,7 +744,12 @@ class BlockAdapter(
)
HOLDER_TABLE -> TableBlockHolder(
ItemBlockTableBinding.inflate(inflater, parent, false),
clickListener = onClickListener
clickListener = onClickListener,
onTextBlockTextChanged = onTextBlockTextChanged,
onMentionEvent = onMentionEvent,
onSlashEvent = onSlashEvent,
onSelectionChanged = onSelectionChanged,
onFocusChanged = onFocusChanged
)
else -> throw IllegalStateException("Unexpected view type: $viewType")
}

View file

@ -0,0 +1,216 @@
package com.anytypeio.anytype.core_ui.features.table
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableRowItemEditableBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableRowItemEmptyBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableSpaceBinding
import com.anytypeio.anytype.core_ui.features.editor.ItemProviderAdapter
import com.anytypeio.anytype.core_ui.features.editor.marks
import com.anytypeio.anytype.core_ui.features.editor.withBlock
import com.anytypeio.anytype.core_ui.features.table.holders.TableCellHolder
import com.anytypeio.anytype.core_ui.features.table.holders.EditableCellHolder
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
import com.anytypeio.anytype.presentation.editor.editor.mention.MentionEvent
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
class TableEditableCellsAdapter(
private var items: List<BlockView.Table.Cell>,
private val clicked: (ListenerType) -> Unit,
private val onTextBlockTextChanged: (BlockView.Text) -> Unit,
private val onMentionEvent: (MentionEvent) -> Unit,
private val onSlashEvent: (SlashEvent) -> Unit,
private val onSelectionChanged: (Id, IntRange) -> Unit,
private val onFocusChanged: (Id, Boolean) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(),
ItemProviderAdapter<BlockView.Text.Paragraph?> {
private var tableBlockId = ""
fun setTableBlockId(id: Id) {
tableBlockId = id
}
override fun provide(pos: Int): BlockView.Text.Paragraph? {
return (items[pos] as? BlockView.Table.Cell.Text)?.block
}
fun updateWithDiffUtil(items: List<BlockView.Table.Cell>) {
val result = DiffUtil.calculateDiff(TableCellsDiffUtil(old = this.items, new = items))
this.items = items
result.dispatchUpdatesTo(this)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
TYPE_CELL -> {
val binding = ItemBlockTableRowItemEditableBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return EditableCellHolder(
binding = binding,
clicked = clicked
).apply {
content.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val item = items[pos]
if (item is BlockView.Table.Cell.Text) {
clicked(
ListenerType.TableTextCell(
tableId = tableBlockId,
cellId = item.block.id
)
)
}
}
}
content.setOnLongClickListener { _ ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
clicked(ListenerType.LongClick(tableBlockId))
}
true
}
content.selectionWatcher = { selection ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val item = items[pos]
if (item is BlockView.Table.Cell.Text) {
item.block.cursor = selection.last
onSelectionChanged(item.block.id, selection)
}
}
}
content.setOnFocusChangeListener { _, hasFocus ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val item = items[pos]
if (item is BlockView.Table.Cell.Text) {
cellSelection(hasFocus)
onFocusChanged(item.block.id, hasFocus)
}
}
}
this.setupViewHolder(
onTextChanged = { editable ->
this.withBlock<BlockView.Text> { item ->
item.apply {
text = editable.toString()
marks = editable.marks()
}
onTextBlockTextChanged(item)
}
},
onEmptyBlockBackspaceClicked = {},
onSplitLineEnterClicked = { _, _, _ -> },
onNonEmptyBlockBackspaceClicked = { _, _ -> },
onMentionEvent = onMentionEvent,
onSlashEvent = onSlashEvent,
onBackPressedCallback = null
)
}
}
TYPE_EMPTY -> {
val binding = ItemBlockTableRowItemEmptyBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return EmptyHolder(binding = binding).apply {
itemView.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val item = items[bindingAdapterPosition]
if (item is BlockView.Table.Cell.Empty) {
clicked(
ListenerType.TableEmptyCell(
cellId = item.getId(),
rowId = item.rowId,
tableId = tableBlockId
)
)
}
}
}
}
}
TYPE_SPACE -> {
val binding = ItemBlockTableSpaceBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return TableCellHolder.TableSpaceHolder(binding)
}
else -> throw UnsupportedOperationException("wrong viewtype:$viewType")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is EditableCellHolder) {
holder.bind(
item = (items[position] as BlockView.Table.Cell.Text).block
)
}
}
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int,
payloads: MutableList<Any>
) {
super.onBindViewHolder(holder, position, payloads)
}
override fun getItemCount(): Int = items.size
override fun getItemViewType(position: Int): Int = when (items[position]) {
is BlockView.Table.Cell.Empty -> TYPE_EMPTY
is BlockView.Table.Cell.Text -> TYPE_CELL
BlockView.Table.Cell.Space -> TYPE_SPACE
}
companion object {
const val TYPE_CELL = 1
const val TYPE_SPACE = 2
const val TYPE_EMPTY = 3
}
class EmptyHolder(binding: ItemBlockTableRowItemEmptyBinding) :
RecyclerView.ViewHolder(binding.root)
class TableCellsDiffUtil(
private val old: List<BlockView.Table.Cell>,
private val new: List<BlockView.Table.Cell>
) : DiffUtil.Callback() {
override fun getOldListSize() = old.size
override fun getNewListSize() = new.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val newItem = new[newItemPosition]
val oldItem = old[oldItemPosition]
if (newItem is BlockView.Table.Cell.Space && oldItem is BlockView.Table.Cell.Space) {
return true
}
if (newItem is BlockView.Table.Cell.Empty && oldItem is BlockView.Table.Cell.Empty) {
return newItem.rowId == oldItem.rowId && newItem.columnId == oldItem.columnId
}
if (newItem is BlockView.Table.Cell.Text && oldItem is BlockView.Table.Cell.Text) {
return newItem.rowId == oldItem.rowId && newItem.columnId == oldItem.columnId
}
return false
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return old[oldItemPosition] == new[newItemPosition]
}
}
}

View file

@ -0,0 +1,70 @@
package com.anytypeio.anytype.core_ui.features.table.holders
import android.graphics.drawable.Drawable
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_ui.BuildConfig
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableRowItemEditableBinding
import com.anytypeio.anytype.core_ui.features.editor.holders.text.Text
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
class EditableCellHolder(
private val binding: ItemBlockTableRowItemEditableBinding,
clicked: (ListenerType) -> Unit,
) : Text<BlockView.Text.Paragraph>(binding.root, clicked) {
override val root: View = binding.root
override val content: TextInputWidget = binding.textContent
private val selectionView: View = binding.selection
private val mentionIconSize: Int
private val mentionIconPadding: Int
private val mentionCheckedIcon: Drawable?
private val mentionUncheckedIcon: Drawable?
private val mentionInitialsSize: Float
init {
setup()
with(itemView.context) {
mentionIconSize =
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
mentionIconPadding =
resources.getDimensionPixelSize(R.dimen.mention_span_image_padding_default)
mentionUncheckedIcon = ContextCompat.getDrawable(this, R.drawable.ic_task_0_text_16)
mentionCheckedIcon = ContextCompat.getDrawable(this, R.drawable.ic_task_1_text_16)
mentionInitialsSize = resources.getDimension(R.dimen.mention_span_initials_size_default)
}
applyDefaultOffsets()
}
private fun applyDefaultOffsets() {
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
binding.root.updatePadding(
left = dimen(R.dimen.default_document_item_padding_start),
right = dimen(R.dimen.default_document_item_padding_end)
)
binding.root.updateLayoutParams<RecyclerView.LayoutParams> {
topMargin = dimen(R.dimen.default_document_item_margin_top)
bottomMargin = dimen(R.dimen.default_document_item_margin_bottom)
}
}
}
fun cellSelection(isSelected: Boolean) {
selectionView.isSelected = isSelected
}
override fun indentize(item: BlockView.Indentable) {}
override fun getMentionIconSize(): Int = mentionIconSize
override fun getMentionIconPadding(): Int = mentionIconPadding
override fun getMentionCheckedIcon(): Drawable? = mentionCheckedIcon
override fun getMentionUncheckedIcon(): Drawable? = mentionUncheckedIcon
override fun getMentionInitialsSize(): Float = mentionInitialsSize
}

View file

@ -1,8 +1,10 @@
package com.anytypeio.anytype.core_ui.features.table.holders
import android.widget.FrameLayout
import androidx.recyclerview.widget.CustomGridLayoutManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableBinding
import com.anytypeio.anytype.core_ui.extensions.drawable
@ -14,12 +16,21 @@ import com.anytypeio.anytype.core_ui.features.table.TableCellsDiffUtil
import com.anytypeio.anytype.core_ui.layout.TableHorizontalItemDivider
import com.anytypeio.anytype.core_ui.layout.TableVerticalItemDivider
import com.anytypeio.anytype.core_models.ThemeColor
import com.anytypeio.anytype.core_ui.features.table.TableEditableCellsAdapter
import com.anytypeio.anytype.presentation.BuildConfig
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
import com.anytypeio.anytype.presentation.editor.editor.mention.MentionEvent
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
class TableBlockHolder(
binding: ItemBlockTableBinding,
clickListener: (ListenerType) -> Unit
clickListener: (ListenerType) -> Unit,
onTextBlockTextChanged: (BlockView.Text) -> Unit,
onMentionEvent: (MentionEvent) -> Unit,
onSlashEvent: (SlashEvent) -> Unit,
onSelectionChanged: (Id, IntRange) -> Unit,
onFocusChanged: (Id, Boolean) -> Unit
) : BlockViewHolder(binding.root) {
val root: FrameLayout = binding.root
@ -30,15 +41,21 @@ class TableBlockHolder(
differ = TableCellsDiffUtil,
clickListener = clickListener
)
private val lm = GridLayoutManager(itemView.context, 1, GridLayoutManager.HORIZONTAL, false)
private val mSpanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when (recycler.adapter?.getItemViewType(position)) {
TableBlockAdapter.TYPE_CELL -> 1
else -> lm.spanCount
}
}
private val tableEditableCellsAdapter = TableEditableCellsAdapter(
items = listOf(),
clicked = clickListener,
onTextBlockTextChanged = onTextBlockTextChanged,
onMentionEvent = onMentionEvent,
onSlashEvent = onSlashEvent,
onSelectionChanged = onSelectionChanged,
onFocusChanged = onFocusChanged
)
private val lm = if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
CustomGridLayoutManager(itemView.context, 1, GridLayoutManager.HORIZONTAL, false)
} else {
GridLayoutManager(itemView.context, 1, GridLayoutManager.HORIZONTAL, false)
}
init {
@ -48,8 +65,30 @@ class TableBlockHolder(
recycler.apply {
layoutManager = lm
lm.spanSizeLookup = mSpanSizeLookup
adapter = tableAdapter
if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
(lm as CustomGridLayoutManager).spanSizeLookup =
object : CustomGridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when (recycler.adapter?.getItemViewType(position)) {
TableEditableCellsAdapter.TYPE_CELL, TableEditableCellsAdapter.TYPE_EMPTY -> 1
else -> lm.spanCount
}
}
}
adapter = tableEditableCellsAdapter
setHasFixedSize(true)
} else {
(lm as GridLayoutManager).spanSizeLookup =
object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when (recycler.adapter?.getItemViewType(position)) {
TableBlockAdapter.TYPE_CELL -> 1
else -> lm.spanCount
}
}
}
adapter = tableAdapter
}
addItemDecoration(verticalDecorator)
addItemDecoration(horizontalDecorator)
}
@ -57,9 +96,15 @@ class TableBlockHolder(
fun bind(item: BlockView.Table) {
selected.isSelected = item.isSelected
lm.spanCount = item.rowCount
tableAdapter.setTableBlockId(item.id)
tableAdapter.submitList(item.cells)
if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
(lm as CustomGridLayoutManager).spanCount = item.rowCount
tableEditableCellsAdapter.setTableBlockId(item.id)
tableEditableCellsAdapter.updateWithDiffUtil(item.cells)
} else {
(lm as GridLayoutManager).spanCount = item.rowCount
tableAdapter.setTableBlockId(item.id)
tableAdapter.submitList(item.cells)
}
}
fun processChangePayload(

View file

@ -4,8 +4,10 @@ import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.View
import androidx.recyclerview.widget.CustomGridLayoutManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.presentation.BuildConfig
import kotlin.math.roundToInt
class TableVerticalItemDivider(
@ -18,7 +20,7 @@ class TableVerticalItemDivider(
state: RecyclerView.State
) {
canvas.save()
val spanCount = (parent.layoutManager as GridLayoutManager).spanCount
val spanCount = getSpanCount(parent)
val childCount = parent.childCount
val itemCount = parent.adapter?.itemCount ?: 0
val rect = Rect()
@ -49,7 +51,7 @@ class TableVerticalItemDivider(
parent: RecyclerView,
state: RecyclerView.State
) {
val spanCount = (parent.layoutManager as GridLayoutManager).spanCount
val spanCount = getSpanCount(parent)
val itemCount = parent.adapter?.itemCount ?: 0
val position = parent.getChildLayoutPosition(view)
outRect.bottom = drawable.intrinsicHeight
@ -57,4 +59,12 @@ class TableVerticalItemDivider(
outRect.top = drawable.intrinsicHeight
}
}
private fun getSpanCount(parent: RecyclerView): Int {
return if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
(parent.layoutManager as CustomGridLayoutManager).spanCount
} else {
(parent.layoutManager as GridLayoutManager).spanCount
}
}
}

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_table_cell_board_all" android:state_selected="true" />
</selector>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="140dp"
android:layout_height="wrap_content"
android:minWidth="@dimen/item_block_table_cell_width"
android:minHeight="@dimen/item_block_table_cell_height">
<com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
android:id="@+id/textContent"
style="@style/BlockCellTextContentStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/item_block_multi_select_mode_selector"
android:focusable="true"
android:textIsSelectable="true"
tools:text="@string/default_text_placeholder" />
<View
android:id="@+id/selection"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_block_cell_selected" />
</FrameLayout>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="140dp"
android:layout_height="match_parent"
android:minHeight="42dp" />
android:layout_height="wrap_content"
android:minWidth="@dimen/item_block_table_cell_width"
android:minHeight="@dimen/item_block_table_cell_height" />

View file

@ -160,12 +160,6 @@ class TableBlockTest {
onItemView(0, R.id.recyclerTable).checkHasChildViewCount(4)
onItemView(0, R.id.recyclerTable).checkHasChildViewWithText(
0,
"",
R.id.textContent
).checkIsDisplayed()
onItemView(0, R.id.recyclerTable).checkHasChildViewWithText(
1,
row1Block1.content.asText().text,
@ -197,13 +191,6 @@ class TableBlockTest {
onItemView(0, R.id.recyclerTable).checkHasChildViewCount(4)
onItemView(0, R.id.recyclerTable).checkHasChildViewWithText(
0,
"",
R.id.textContent
).checkIsDisplayed()
onItemView(0, R.id.recyclerTable).checkHasChildViewWithText(
1,
row1Block1.content.asText().text,

View file

@ -13,6 +13,7 @@ android {
testInstrumentationRunner config["test_runner"]
buildConfigField "boolean", "ENABLE_LINK_APPERANCE_MENU", "true"
buildConfigField "boolean", "NESTED_DECORATION_ENABLED", "true"
buildConfigField "boolean", "USE_SIMPLE_TABLES_IN_EDITOR_EDDITING", "true"
}
testOptions.unitTests.includeAndroidResources = true

View file

@ -107,6 +107,7 @@ import com.anytypeio.anytype.presentation.editor.editor.ext.update
import com.anytypeio.anytype.presentation.editor.editor.ext.updateCursorAndEditMode
import com.anytypeio.anytype.presentation.editor.editor.ext.updateSelection
import com.anytypeio.anytype.presentation.editor.editor.ext.applyBordersToSelectedCells
import com.anytypeio.anytype.presentation.editor.editor.ext.findTableCellView
import com.anytypeio.anytype.presentation.editor.editor.ext.removeBordersFromCells
import com.anytypeio.anytype.presentation.editor.editor.ext.updateTableOfContentsViews
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
@ -2448,19 +2449,27 @@ class EditorViewModel(
fun onBlockToolbarBlockActionsClicked() {
Timber.d("onBlockToolbarBlockActionsClicked, ")
val target = orchestrator.stores.focus.current().id
val view = views.find { it.id == target } ?: return
when (view) {
is BlockView.Title -> {
sendToast(CANNOT_OPEN_ACTION_MENU_FOR_TITLE_ERROR)
val view = views.find { it.id == target }
if (view == null) {
val cell = views.findTableCellView(target)
if (cell != null && cell is BlockView.Table.Cell.Text) {
onShowSimpleTableWidgetClicked(target)
viewModelScope.sendAnalyticsSelectionMenuEvent(analytics)
}
is BlockView.Description -> {
sendToast(CANNOT_OPEN_ACTION_MENU_FOR_DESCRIPTION)
}
else -> {
proceedWithEnteringActionMode(target = target, scrollTarget = false)
} else {
when (view) {
is BlockView.Title -> {
sendToast(CANNOT_OPEN_ACTION_MENU_FOR_TITLE_ERROR)
}
is BlockView.Description -> {
sendToast(CANNOT_OPEN_ACTION_MENU_FOR_DESCRIPTION)
}
else -> {
proceedWithEnteringActionMode(target = target, scrollTarget = false)
}
}
viewModelScope.sendAnalyticsSelectionMenuEvent(analytics)
}
viewModelScope.sendAnalyticsSelectionMenuEvent(analytics)
}
fun onEnterScrollAndMoveClicked() {
@ -2775,6 +2784,10 @@ class EditorViewModel(
private fun fillTableBlockRow(cellId: Id, targetIds: List<Id>, tableId: Id) {
viewModelScope.launch {
if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
val focus = Editor.Focus(id = cellId, cursor = null)
orchestrator.stores.focus.update(focus)
}
orchestrator.proxies.intents.send(
Intent.Table.FillTableRow(
ctx = context,
@ -2782,13 +2795,15 @@ class EditorViewModel(
)
)
}
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = cellId,
table = tableId
if (!BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = cellId,
table = tableId
)
)
)
}
}
fun onAddDividerBlockClicked(style: Content.Divider.Style) {
@ -3827,10 +3842,31 @@ class EditorViewModel(
}
is ListenerType.TableEmptyCell -> {
when (mode) {
EditorMode.Edit, EditorMode.Locked -> {
if (currentSelection().isNotEmpty()) {
Timber.e("Some other blocks are selected, amend table cell click")
return
EditorMode.Locked -> {
if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
Timber.d("Clicked on table cell in Locked Mode")
} else {
if (currentSelection().isNotEmpty()) {
Timber.e("Some other blocks are selected, amend table cell click")
return
}
proceedWithSelectingCell(
cellId = clicked.cellId,
tableId = clicked.tableId
)
onTableRowEmptyCellClicked(
cellId = clicked.cellId,
rowId = clicked.rowId,
tableId = clicked.tableId
)
}
}
EditorMode.Edit -> {
if (!BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
if (currentSelection().isNotEmpty()) {
Timber.e("Some other blocks are selected, amend table cell click")
return
}
}
proceedWithSelectingCell(
cellId = clicked.cellId,
@ -3848,7 +3884,7 @@ class EditorViewModel(
}
is ListenerType.TableTextCell -> {
when (mode) {
EditorMode.Edit, EditorMode.Locked -> {
EditorMode.Edit -> {
if (currentSelection().isNotEmpty()) {
Timber.e("Some other blocks are selected, amend table cell click")
return
@ -3857,13 +3893,34 @@ class EditorViewModel(
cellId = clicked.cellId,
tableId = clicked.tableId
)
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = clicked.cellId,
table = clicked.tableId
if (!BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = clicked.cellId,
table = clicked.tableId
)
)
)
}
}
EditorMode.Locked -> {
if (currentSelection().isNotEmpty()) {
Timber.e("Some other blocks are selected, amend table cell click")
return
}
if (!BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
proceedWithSelectingCell(
cellId = clicked.cellId,
tableId = clicked.tableId
)
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = clicked.cellId,
table = clicked.tableId
)
)
}
}
EditorMode.Select -> onBlockMultiSelectClicked(target = clicked.tableId)
else -> Unit

View file

@ -1149,4 +1149,18 @@ fun List<BlockView>.removeBordersFromCells(): List<BlockView> = map { view ->
} else {
view
}
}
fun List<BlockView>.findTableCellView(id: Id): BlockView.Table.Cell? {
forEach { blockView ->
if (blockView is BlockView.Table) {
val cells = blockView.cells
val cell = cells.find {
it is BlockView.Table.Cell.Empty && it.getId() == id
|| it is BlockView.Table.Cell.Text && it.getId() == id
}
if (cell != null) return cell
}
}
return null
}

View file

@ -19,8 +19,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.inOrder
import org.mockito.kotlin.verifyNoInteractions
import kotlin.test.assertEquals
@ -38,7 +37,7 @@ class EditorTableBlockTest : EditorPresentationTestSetup() {
}
@Test
fun `should amend second empty cell click`() {
fun `should not amend second empty cell click`() {
val columns = StubTableColumns(size = 3)
val rows = StubTableRows(size = 2)
@ -85,16 +84,16 @@ class EditorTableBlockTest : EditorPresentationTestSetup() {
)
}
val selectedState = vm.currentSelection()
assertEquals(1, selectedState.size)
assertEquals(cell1Id, selectedState.first())
coroutineTestRule.advanceTime(50L)
runBlocking {
verify(fillTableRow, times(1)).invoke(
val inOrder = inOrder(fillTableRow)
inOrder.verify(fillTableRow).invoke(
params = FillTableRow.Params(ctx = root, targetIds = listOf(rows[0].id))
)
inOrder.verify(fillTableRow).invoke(
params = FillTableRow.Params(ctx = root, targetIds = listOf(rows[1].id))
)
}
}