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

DROID-606 Editor | Simple table, cell menu options (#2702)

* DROID-606 cells clear style logic

* DROID-606 show color toolbar

* DROID-606 on draw over cells selection divider

* DROID-606 table block diff util

* DROID-606 table block holder refactoring

* DROID-606 code style

* DROID-606 update tests

* DROID-606 cells diff util

* DROID-606 legacy

* DROID-606 cells adapter refactoring

* DROID-606 cell holder refactoring

* DROID-606 cell holder, background color

* DROID-606 rename xml

* DROID-606 update binding

* DROID-606 cell selection + show menus

* DROID-606 cell menu design

* DROID-606 other and color toolbars

* DROID-606 cell menu icon

* DROID-606 fix test

* DROID-606 color fix

Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
Konstantin Ivanov 2022-11-14 13:19:31 +01:00 committed by GitHub
parent 2dafc36f9b
commit 8831bdcc05
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 650 additions and 807 deletions

View file

@ -21,6 +21,7 @@ import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.base.Result
import com.anytypeio.anytype.domain.block.UpdateDivider
import com.anytypeio.anytype.domain.block.interactor.ClearBlockContent
import com.anytypeio.anytype.domain.block.interactor.ClearBlockStyle
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
import com.anytypeio.anytype.domain.block.interactor.DuplicateBlock
import com.anytypeio.anytype.domain.block.interactor.MergeBlocks
@ -191,6 +192,7 @@ open class EditorTestSetup {
lateinit var setObjectType: SetObjectType
lateinit var objectToSet: ConvertObjectToSet
lateinit var clearBlockContent: ClearBlockContent
lateinit var clearBlockStyle: ClearBlockStyle
lateinit var getDefaultEditorType: GetDefaultEditorType
@ -288,6 +290,7 @@ open class EditorTestSetup {
interceptThreadStatus = InterceptThreadStatus(channel = threadStatusChannel)
downloadUnsplashImage = DownloadUnsplashImage(unsplashRepository)
clearBlockContent = ClearBlockContent(repo)
clearBlockStyle = ClearBlockStyle(repo)
downloadFile = DownloadFile(
downloader = mock(),
context = Dispatchers.Main
@ -388,7 +391,8 @@ open class EditorTestSetup {
createBookmarkBlock = createBookmarkBlock,
createTable = createTable,
fillTableRow = fillTableRow,
clearBlockContent = clearBlockContent
clearBlockContent = clearBlockContent,
clearBlockStyle = clearBlockStyle
),
createNewDocument = createNewDocument,
interceptThreadStatus = interceptThreadStatus,

View file

@ -20,6 +20,7 @@ import com.anytypeio.anytype.domain.auth.repo.AuthRepository
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.block.UpdateDivider
import com.anytypeio.anytype.domain.block.interactor.ClearBlockContent
import com.anytypeio.anytype.domain.block.interactor.ClearBlockStyle
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
import com.anytypeio.anytype.domain.block.interactor.DuplicateBlock
import com.anytypeio.anytype.domain.block.interactor.MergeBlocks
@ -361,7 +362,8 @@ object EditorSessionModule {
analytics: Analytics,
updateBlocksMark: UpdateBlocksMark,
middlewareShareDownloader: MiddlewareShareDownloader,
clearBlockContent: ClearBlockContent
clearBlockContent: ClearBlockContent,
clearBlockStyle: ClearBlockStyle
): Orchestrator = Orchestrator(
stores = storage,
createBlock = createBlock,
@ -403,7 +405,8 @@ object EditorSessionModule {
setObjectType = setObjectType,
createTable = createTable,
fillTableRow = fillTableRow,
clearBlockContent = clearBlockContent
clearBlockContent = clearBlockContent,
clearBlockStyle = clearBlockStyle
)
}
@ -1003,6 +1006,13 @@ object EditorUseCaseModule {
repo: BlockRepository
): ClearBlockContent = ClearBlockContent(repo)
@JvmStatic
@Provides
@PerScreen
fun provideBlockListClearStyle(
repo: BlockRepository
): ClearBlockStyle = ClearBlockStyle(repo)
@Module
interface Bindings {

View file

@ -603,7 +603,7 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
.doneButton
.clicks()
.throttleFirst()
.onEach { vm.onCellsSelectionDoneClick() }
.onEach { vm.onCellSelectionTopToolbarDoneButtonClick() }
.launchIn(lifecycleScope)
binding.bottomToolbar

View file

@ -255,9 +255,6 @@ class BlockAdapter(
is Video -> {
holder.recycle()
}
is TableBlockHolder -> {
holder.recycle()
}
}
}
@ -743,7 +740,7 @@ class BlockAdapter(
ItemBlockUnsupportedBinding.inflate(inflater, parent, false)
)
HOLDER_TABLE -> TableBlockHolder(
ItemBlockTableBinding.inflate(inflater, parent, false),
binding = ItemBlockTableBinding.inflate(inflater, parent, false),
clickListener = onClickListener,
onTextBlockTextChanged = onTextBlockTextChanged,
onMentionEvent = onMentionEvent,

View file

@ -245,6 +245,9 @@ class BlockViewDiffUtil(
}
if (newBlock is BlockView.Table && oldBlock is BlockView.Table) {
if (newBlock.rowCount != oldBlock.rowCount) {
changes.add(TABLE_ROW_COUNT_CHANGED)
}
if (newBlock.cells != oldBlock.cells) {
changes.add(TABLE_CELLS_CHANGED)
}
@ -310,6 +313,10 @@ class BlockViewDiffUtil(
fun alignmentChanged() = changes.contains(ALIGNMENT_CHANGED)
fun relationValueChanged() = changes.contains(RELATION_VALUE_CHANGED)
fun relationNameChanged() = changes.contains(RELATION_NAME_CHANGED)
fun tableCellsSelectionChanged() = changes.contains(TABLE_CELLS_SELECTION_CHANGED)
fun tableCellsChanged() = changes.contains(TABLE_CELLS_CHANGED)
fun tableRowCountChanged() = changes.contains(TABLE_ROW_COUNT_CHANGED)
}
companion object {
@ -347,5 +354,6 @@ class BlockViewDiffUtil(
const val TABLE_CELLS_SELECTION_CHANGED = 340
const val TABLE_CELLS_CHANGED = 341
const val TABLE_ROW_COUNT_CHANGED = 342
}
}

View file

@ -1,86 +0,0 @@
package com.anytypeio.anytype.core_ui.features.table
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableRowItemBinding
import com.anytypeio.anytype.core_ui.features.table.holders.TableCellHolder
import com.anytypeio.anytype.core_utils.ext.typeOf
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
class TableBlockAdapter(
differ: TableCellsDiffUtil,
private val clickListener: (ListenerType) -> Unit
) : ListAdapter<BlockView.Table.Cell, TableCellHolder>(differ) {
private var tableBlockId = ""
fun setTableBlockId(id: Id) {
tableBlockId = id
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableCellHolder {
val binding = ItemBlockTableRowItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return TableCellHolder.TableTextCellHolder(
context = parent.context,
binding = binding
).apply {
textContent.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
onCellClicked(getItem(pos))
}
}
textContent.setOnLongClickListener { _ ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
clickListener(ListenerType.LongClick(tableBlockId))
}
true
}
}
}
private fun onCellClicked(item: BlockView.Table.Cell) {
val block = item.block
if (block == null) {
clickListener(
ListenerType.TableEmptyCell(cell = item)
)
} else {
clickListener(
ListenerType.TableTextCell(cell = item)
)
}
}
override fun onBindViewHolder(holder: TableCellHolder, position: Int) {
if (holder is TableCellHolder.TableTextCellHolder) {
holder.bind(getItem(position))
}
}
override fun onBindViewHolder(
holder: TableCellHolder,
position: Int,
payloads: MutableList<Any>
) {
if (payloads.isEmpty()) {
onBindViewHolder(holder, position)
} else {
if (holder is TableCellHolder.TableTextCellHolder) {
holder.processChangePayload(
payloads = payloads.typeOf<TableCellsDiffUtil.Payload>().first(),
cell = getItem(position)
)
}
}
}
}

View file

@ -1,73 +1,89 @@
package com.anytypeio.anytype.core_ui.features.table
import androidx.recyclerview.widget.DiffUtil
import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil
import com.anytypeio.anytype.presentation.editor.editor.Markup
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
import com.anytypeio.anytype.presentation.editor.editor.model.Focusable
object TableCellsDiffUtil : DiffUtil.ItemCallback<BlockView.Table.Cell>() {
class TableCellsDiffUtil(
private val old: List<BlockView.Table.Cell>,
private val new: List<BlockView.Table.Cell>
) : DiffUtil.Callback() {
override fun areItemsTheSame(
oldItem: BlockView.Table.Cell,
newItem: BlockView.Table.Cell
): Boolean {
return oldItem.getId() == newItem.getId()
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]
return newItem.rowId == oldItem.rowId && newItem.columnId == oldItem.columnId
}
override fun areContentsTheSame(
oldItem: BlockView.Table.Cell,
newItem: BlockView.Table.Cell
): Boolean {
return oldItem.block == newItem.block
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return old[oldItemPosition].block == new[newItemPosition].block
}
override fun getChangePayload(
oldItem: BlockView.Table.Cell,
newItem: BlockView.Table.Cell
): Any? {
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
val oldBlock = old[oldItemPosition].block
val newBlock = new[newItemPosition].block
val changes = mutableListOf<Int>()
val oldBlock = oldItem.block
val newBlock = newItem.block
if (newBlock?.text != oldBlock?.text) {
changes.add(TEXT_CHANGED)
}
if (newBlock?.color != oldBlock?.color) {
changes.add(TEXT_COLOR_CHANGED)
}
if (newBlock?.background != oldBlock?.background) {
changes.add(BACKGROUND_COLOR_CHANGED)
}
if (newBlock?.marks != oldBlock?.marks) {
changes.add(MARKUP_CHANGED)
}
if (newBlock?.alignment != oldBlock?.alignment) {
changes.add(ALIGN_CHANGED)
if (oldBlock == null && newBlock == null) {
return super.getChangePayload(oldItemPosition, newItemPosition)
}
return if (changes.isEmpty()) {
super.getChangePayload(oldItem, newItem)
} else {
Payload(changes)
if (oldBlock == null && newBlock != null) {
changes.add(BlockViewDiffUtil.TEXT_CHANGED)
changes.add(BlockViewDiffUtil.TEXT_COLOR_CHANGED)
changes.add(BlockViewDiffUtil.BACKGROUND_COLOR_CHANGED)
changes.add(BlockViewDiffUtil.MARKUP_CHANGED)
changes.add(BlockViewDiffUtil.FOCUS_CHANGED)
changes.add(BlockViewDiffUtil.CURSOR_CHANGED)
changes.add(BlockViewDiffUtil.ALIGNMENT_CHANGED)
return BlockViewDiffUtil.Payload(changes)
}
if (newBlock is BlockView.TextSupport && oldBlock is BlockView.TextSupport) {
if (newBlock.text != oldBlock.text)
changes.add(BlockViewDiffUtil.TEXT_CHANGED)
if (newBlock.color != oldBlock.color)
changes.add(BlockViewDiffUtil.TEXT_COLOR_CHANGED)
if (newBlock.background != oldBlock.background) {
changes.add(BlockViewDiffUtil.BACKGROUND_COLOR_CHANGED)
}
}
if (newBlock is Markup && oldBlock is Markup) {
if (newBlock.marks != oldBlock.marks)
changes.add(BlockViewDiffUtil.MARKUP_CHANGED)
}
if (newBlock is Focusable && oldBlock is Focusable) {
if (newBlock.isFocused != oldBlock.isFocused)
changes.add(BlockViewDiffUtil.FOCUS_CHANGED)
}
if (newBlock is BlockView.Cursor && oldBlock is BlockView.Cursor) {
if (newBlock.cursor != oldBlock.cursor)
changes.add(BlockViewDiffUtil.CURSOR_CHANGED)
}
if (newBlock is BlockView.Permission && oldBlock is BlockView.Permission) {
if (newBlock.mode != oldBlock.mode)
changes.add(BlockViewDiffUtil.READ_WRITE_MODE_CHANGED)
}
if (newBlock is BlockView.Alignable && oldBlock is BlockView.Alignable) {
if (newBlock.alignment != oldBlock.alignment)
changes.add(BlockViewDiffUtil.ALIGNMENT_CHANGED)
}
return if (changes.isNotEmpty())
BlockViewDiffUtil.Payload(changes)
else
super.getChangePayload(oldItemPosition, newItemPosition)
}
data class Payload(
val changes: List<Int>
) {
val isBordersChanged: Boolean = changes.contains(SETTING_BORDER_CHANGED)
val isWidthChanged: Boolean = changes.contains(SETTING_WIDTH_CHANGED)
val isTextChanged = changes.contains(TEXT_CHANGED)
val isBackgroundChanged = changes.contains(BACKGROUND_COLOR_CHANGED)
val isTextColorChanged = changes.contains(TEXT_COLOR_CHANGED)
val isMarkupChanged = changes.contains(MARKUP_CHANGED)
val isAlignChanged = changes.contains(ALIGN_CHANGED)
}
const val TEXT_CHANGED = 1
const val TEXT_COLOR_CHANGED = 2
const val BACKGROUND_COLOR_CHANGED = 3
const val MARKUP_CHANGED = 4
const val ALIGN_CHANGED = 5
const val SETTING_WIDTH_CHANGED = 6
const val SETTING_BORDER_CHANGED = 7
}

View file

@ -5,17 +5,16 @@ 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.ItemBlockTableCellBinding
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.EditableCellHolder
import com.anytypeio.anytype.core_utils.ext.typeOf
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
import timber.log.Timber
class TableEditableCellsAdapter(
private var items: List<BlockView.Table.Cell>,
@ -25,15 +24,9 @@ class TableEditableCellsAdapter(
private val onSlashEvent: (SlashEvent) -> Unit,
private val onSelectionChanged: (Id, IntRange) -> Unit,
private val onFocusChanged: (Id, Boolean) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(),
) : RecyclerView.Adapter<EditableCellHolder>(),
ItemProviderAdapter<BlockView.Text.Paragraph?> {
private var tableBlockId = ""
fun setTableBlockId(id: Id) {
tableBlockId = id
}
override fun provide(pos: Int): BlockView.Text.Paragraph? {
return items.getOrNull(pos)?.block
}
@ -44,146 +37,95 @@ class TableEditableCellsAdapter(
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) {
clicked(
ListenerType.TableTextCell(cell = items[pos])
)
}
}
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 block = items[pos].block
if (block != null) {
block.cursor = selection.last
onSelectionChanged(block.id, selection)
}
}
}
content.setOnFocusChangeListener { _, hasFocus ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val block = items[pos].block
if (block != null) {
cellSelection(hasFocus)
onFocusChanged(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) {
clicked(
ListenerType.TableEmptyCell(cell = items[pos])
)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EditableCellHolder {
val binding = ItemBlockTableCellBinding.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 cell = items[pos]
if (cell.block != null) {
clicked(ListenerType.TableTextCell(cell))
} else {
clicked(ListenerType.TableEmptyCell(cell))
}
}
}
else -> throw UnsupportedOperationException("wrong viewtype:$viewType")
content.selectionWatcher = { selection ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val block = items[pos].block
if (block != null) {
block.cursor = selection.last
onSelectionChanged(block.id, selection)
}
}
}
content.setOnFocusChangeListener { _, hasFocus ->
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val block = items[pos].block
if (block != null) {
cellSelection(hasFocus)
onFocusChanged(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
)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is EditableCellHolder) {
val block = items[position].block
if (block != null) {
holder.bind(item = block)
} else {
Timber.w("onBindViewHolder Cell, block is null")
}
override fun onBindViewHolder(holder: EditableCellHolder, position: Int) {
val block = items[position].block
if (block != null) {
holder.bind(block)
} else {
holder.bindEmptyCell()
}
}
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
holder: EditableCellHolder,
position: Int,
payloads: MutableList<Any>
) {
super.onBindViewHolder(holder, position, payloads)
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
} else {
val block = items[position].block
if (block != null) {
holder.processChangePayload(
payloads = payloads.typeOf(),
item = block,
clicked = clicked
)
}
}
}
override fun getItemCount(): Int = items.size
override fun getItemViewType(position: Int): Int {
return if (items[position].block == null) {
TYPE_EMPTY
} else {
TYPE_CELL
}
}
companion object {
const val TYPE_CELL = 1
const val TYPE_EMPTY = 2
}
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]
return newItem.rowId == oldItem.rowId && newItem.columnId == oldItem.columnId
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return old[oldItemPosition].block == new[newItemPosition].block
}
}
}

View file

@ -3,26 +3,22 @@ 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.databinding.ItemBlockTableCellBinding
import com.anytypeio.anytype.core_ui.extensions.setBlockBackgroundColor
import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil
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,
private val binding: ItemBlockTableCellBinding,
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
@ -41,24 +37,41 @@ class EditableCellHolder(
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)
}
}
override fun bind(item: BlockView.Text.Paragraph) {
super.bind(item)
applyBackground(item)
}
fun bindEmptyCell() {
if (root.background != null) root.background = null
if (content.text != null) content.text = null
content.enableReadMode()
}
fun cellSelection(isSelected: Boolean) {
selectionView.isSelected = isSelected
binding.selection.isSelected = isSelected
}
override fun processChangePayload(
payloads: List<BlockViewDiffUtil.Payload>,
item: BlockView,
clicked: (ListenerType) -> Unit,
) {
if (item is BlockView.Text.Paragraph) {
if (item.mode == BlockView.Mode.EDIT) {
content.enableEditMode()
}
if (payloads.any { p -> p.isBackgroundColorChanged }) {
applyBackground(item)
}
}
super.processChangePayload(payloads, item, clicked)
}
private fun applyBackground(item: BlockView.Text.Paragraph) {
root.setBlockBackgroundColor(item.background)
}
override fun indentize(item: BlockView.Indentable) {}

View file

@ -11,15 +11,11 @@ import com.anytypeio.anytype.core_ui.extensions.drawable
import com.anytypeio.anytype.core_ui.extensions.setBlockBackgroundColor
import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil
import com.anytypeio.anytype.core_ui.features.editor.BlockViewHolder
import com.anytypeio.anytype.core_ui.features.table.TableBlockAdapter
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.core_ui.layout.TableCellSelectionDecoration
import com.anytypeio.anytype.core_utils.ext.containsItemDecoration
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
@ -36,20 +32,16 @@ class TableBlockHolder(
onFocusChanged: (Id, Boolean) -> Unit
) : BlockViewHolder(binding.root) {
val root: FrameLayout = binding.root
val recycler: RecyclerView = binding.recyclerTable
private val selected = binding.selected
private val root: FrameLayout = binding.root
private val recycler: RecyclerView = binding.recyclerTable
private val selectView = binding.selected
private val cellsSelectionState = TableCellsSelectionState()
private val cellSelectionDecoration: TableCellSelectionDecoration = TableCellSelectionDecoration(
drawable = binding.root.context.drawable(R.drawable.cell_top_border)
)
private val tableAdapter = TableBlockAdapter(
differ = TableCellsDiffUtil,
clickListener = clickListener
)
private val cellSelectionDecoration: TableCellSelectionDecoration =
TableCellSelectionDecoration(
drawable = binding.root.context.drawable(R.drawable.cell_top_border)
)
private val tableEditableCellsAdapter = TableEditableCellsAdapter(
items = listOf(),
@ -61,11 +53,12 @@ class TableBlockHolder(
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)
}
private val lm =
CustomGridLayoutManager(itemView.context, 1, GridLayoutManager.HORIZONTAL, false).apply {
spanSizeLookup = object : CustomGridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int = 1
}
}
init {
val drawable = itemView.context.drawable(R.drawable.divider_dv_grid)
@ -74,37 +67,19 @@ class TableBlockHolder(
recycler.apply {
layoutManager = lm
if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
(lm as CustomGridLayoutManager).spanSizeLookup =
object : CustomGridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int = 1
}
adapter = tableEditableCellsAdapter
setHasFixedSize(true)
} else {
(lm as GridLayoutManager).spanSizeLookup =
object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int = 1
}
adapter = tableAdapter
}
adapter = tableEditableCellsAdapter
setHasFixedSize(true)
addItemDecoration(verticalDecorator)
addItemDecoration(horizontalDecorator)
}
}
fun bind(item: BlockView.Table) {
selected.isSelected = item.isSelected
if (BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
(lm as CustomGridLayoutManager).spanCount = item.rowCount
tableEditableCellsAdapter.setTableBlockId(item.id)
tableEditableCellsAdapter.updateWithDiffUtil(item.cells)
updateCellsSelection(item)
} else {
(lm as GridLayoutManager).spanCount = item.rowCount
tableAdapter.setTableBlockId(item.id)
tableAdapter.submitList(item.cells)
}
applySelection(item)
applyBackground(item)
applyRowCount(item)
applyCells(item)
updateCellsSelection(item)
}
fun processChangePayload(
@ -112,27 +87,28 @@ class TableBlockHolder(
item: BlockView.Table
) {
payloads.forEach { payload ->
if (payload.changes.contains(BlockViewDiffUtil.TABLE_CELLS_CHANGED)) {
bind(item)
}
if (payload.changes.contains(BlockViewDiffUtil.SELECTION_CHANGED)) {
selected.isSelected = item.isSelected
}
if (payload.changes.contains(BlockViewDiffUtil.BACKGROUND_COLOR_CHANGED)) {
applyBackground(item.background)
}
if (payload.changes.contains(BlockViewDiffUtil.TABLE_CELLS_SELECTION_CHANGED)) {
updateCellsSelection(item)
}
if (payload.selectionChanged()) applySelection(item)
if (payload.backgroundColorChanged()) applyBackground(item)
if (payload.tableRowCountChanged()) applyRowCount(item)
if (payload.tableCellsChanged()) applyCells(item)
if (payload.tableCellsSelectionChanged()) updateCellsSelection(item)
}
}
private fun applyBackground(background: ThemeColor) {
root.setBlockBackgroundColor(background)
private fun applyBackground(item: BlockView.Table) {
root.setBlockBackgroundColor(item.background)
}
fun recycle() {
tableAdapter.submitList(emptyList())
private fun applySelection(item: BlockView.Table) {
selectView.isSelected = item.isSelected
}
private fun applyCells(item: BlockView.Table) {
tableEditableCellsAdapter.updateWithDiffUtil(item.cells)
}
private fun applyRowCount(item: BlockView.Table) {
lm.spanCount = item.rowCount
}
private fun updateCellsSelection(item: BlockView.Table) {
@ -146,7 +122,7 @@ class TableBlockHolder(
item.selectedCellsIds.contains(cell.getId())
}
cellsSelectionState.clear()
cellsSelectionState.set(cells = selectedCells)
cellsSelectionState.set(selectedCells)
if (cellsSelectionState.current().isNotEmpty()) {
cellSelectionDecoration.setSelectionState(cellsSelectionState.current())
if (!recycler.containsItemDecoration(cellSelectionDecoration)) {

View file

@ -1,195 +0,0 @@
package com.anytypeio.anytype.core_ui.features.table.holders
import android.content.Context
import android.view.Gravity
import android.view.View
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.common.toSpannable
import com.anytypeio.anytype.core_ui.databinding.ItemBlockTableRowItemBinding
import com.anytypeio.anytype.core_ui.extensions.resolveThemedTextColor
import com.anytypeio.anytype.core_ui.extensions.veryLight
import com.anytypeio.anytype.core_ui.features.table.TableCellsDiffUtil
import com.anytypeio.anytype.presentation.editor.editor.Markup
import com.anytypeio.anytype.core_models.ThemeColor
import com.anytypeio.anytype.presentation.editor.editor.model.Alignment
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
sealed class TableCellHolder(view: View) : RecyclerView.ViewHolder(view) {
class TableTextCellHolder(context: Context, binding: ItemBlockTableRowItemBinding) :
TableCellHolder(binding.root) {
val root: View = binding.root
val textContent: AppCompatTextView = binding.textContent
val selection: View = binding.selection
private val defTextColor: Int = itemView.resources.getColor(R.color.text_primary, null)
private val mentionIconSize =
itemView.resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
private val mentionIconPadding =
itemView.resources.getDimensionPixelSize(R.dimen.mention_span_image_padding_default)
private val mentionCheckedIcon =
ContextCompat.getDrawable(context, R.drawable.ic_task_0_text_16)
private val mentionUncheckedIcon =
ContextCompat.getDrawable(context, R.drawable.ic_task_0_text_16)
private val mentionInitialsSize =
itemView.resources.getDimension(R.dimen.mention_span_initials_size_default)
fun bind(
cell: BlockView.Table.Cell
) {
val textBlock = cell.block
if (textBlock == null) {
textContent.text = null
} else {
setBlockText(
text = textBlock.text,
markup = textBlock,
color = textBlock.color
)
setTextColor(textBlock.color)
setAlignment(textBlock.alignment)
}
}
fun processChangePayload(
payloads: TableCellsDiffUtil.Payload,
cell: BlockView.Table.Cell
) {
val textBlock = cell.block
if (textBlock != null) {
processChangePayload(payloads, textBlock)
}
}
fun processChangePayload(
payloads: TableCellsDiffUtil.Payload,
block: BlockView.Text.Paragraph
) {
if (payloads.isTextChanged) {
setBlockText(
text = block.text,
markup = block,
color = block.color
)
}
if (payloads.isTextColorChanged) {
setTextColor(block.color)
}
if (payloads.isMarkupChanged) {
setBlockSpannableText(block, resolveTextBlockThemedColor(block.color))
}
if (payloads.isAlignChanged) {
setAlignment(block.alignment)
}
}
private fun setBlockText(
text: String,
markup: Markup,
color: ThemeColor
) {
when (markup.marks.isEmpty()) {
true -> textContent.text = text
false -> setBlockSpannableText(markup, resolveTextBlockThemedColor(color))
}
}
private fun setBlockSpannableText(
markup: Markup,
color: Int
) {
when (markup.marks.any { it is Markup.Mark.Mention || it is Markup.Mark.Object }) {
true -> setSpannableWithMention(markup, color)
false -> setSpannable(markup, color)
}
}
private fun setSpannable(markup: Markup, textColor: Int) {
textContent.setText(
markup.toSpannable(
textColor = textColor,
context = itemView.context,
underlineHeight = getUnderlineHeight()
),
TextView.BufferType.SPANNABLE
)
}
private fun setSpannableWithMention(
markup: Markup,
textColor: Int
) {
textContent.setText(
markup.toSpannable(
textColor = textColor,
context = itemView.context,
mentionImageSize = mentionIconSize,
mentionImagePadding = mentionIconPadding,
mentionCheckedIcon = mentionCheckedIcon,
mentionUncheckedIcon = mentionUncheckedIcon,
mentionInitialsSize = mentionInitialsSize,
underlineHeight = getUnderlineHeight()
),
TextView.BufferType.SPANNABLE
)
}
private fun setAlignment(alignment: Alignment?) {
if (alignment != null) {
textContent.gravity = when (alignment) {
Alignment.START -> Gravity.START
Alignment.CENTER -> Gravity.CENTER
Alignment.END -> Gravity.END
}
} else {
textContent.gravity = Gravity.START
}
}
private fun setTextColor(color: ThemeColor) {
textContent.setTextColor(resolveTextBlockThemedColor(color))
}
/**
* @param [bg] color code, @see [ThemeColor]
*/
private fun setTableCellBackgroundColor(
bg: ThemeColor,
view: View,
isHeader: Boolean
) {
if (bg != ThemeColor.DEFAULT) {
view.setBackgroundColor(view.resources.veryLight(bg, 0))
} else {
setTableCellHeaderOrEmptyBackground(view, isHeader)
}
}
private fun setTableCellHeaderOrEmptyBackground(view: View, isHeader: Boolean) {
if (isHeader) {
root.setBackgroundColor(
itemView.resources.getColor(
R.color.table_row_header_background,
null
)
)
} else {
view.background = null
}
}
private fun resolveTextBlockThemedColor(color: ThemeColor): Int {
return itemView.context.resolveThemedTextColor(color, defTextColor)
}
}
fun getUnderlineHeight(): Float =
itemView.resources.getDimensionPixelSize(R.dimen.block_text_markup_underline_height)
.toFloat()
}

View file

@ -19,7 +19,7 @@ class TableCellSelectionDecoration(
selectionState.addAll(newState)
}
override fun onDraw(
override fun onDrawOver(
canvas: Canvas,
parent: RecyclerView,
state: RecyclerView.State

View file

@ -50,23 +50,23 @@ class SimpleTableWidgetAdapter(
SimpleTableWidgetItem.Row.ClearContents,
SimpleTableWidgetItem.Column.ClearContents -> {
title.setText(R.string.simple_tables_widget_item_clear_contents)
icon.setImageResource(R.drawable.ic_slash_actions_clean_style)
icon.setImageResource(R.drawable.ic_clear_32)
}
SimpleTableWidgetItem.Cell.ClearStyle -> {
title.setText(R.string.simple_tables_widget_item_clear_style)
icon.setImageResource(R.drawable.ic_slash_actions_clean_style)
icon.setImageResource(R.drawable.ic_reset_32)
}
SimpleTableWidgetItem.Cell.Color,
SimpleTableWidgetItem.Column.Color,
SimpleTableWidgetItem.Row.Color -> {
title.setText(R.string.simple_tables_widget_item_clear_color)
icon.setImageResource(R.drawable.ic_style_toolbar_color)
title.setText(R.string.simple_tables_widget_item_color)
icon.setImageResource(R.drawable.ic_color_32)
}
SimpleTableWidgetItem.Cell.Style,
SimpleTableWidgetItem.Row.Style,
SimpleTableWidgetItem.Column.Style -> {
title.setText(R.string.simple_tables_widget_item_clear_style)
icon.setImageResource(R.drawable.ic_block_toolbar_block_style)
title.setText(R.string.simple_tables_widget_item_style)
icon.setImageResource(R.drawable.ic_style_32)
}
SimpleTableWidgetItem.Column.Delete,
SimpleTableWidgetItem.Row.Delete -> {

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M25.5,16C25.5,21.247 21.247,25.5 16,25.5C10.753,25.5 6.5,21.247 6.5,16C6.5,10.753 10.753,6.5 16,6.5C21.247,6.5 25.5,10.753 25.5,16ZM27,16C27,22.075 22.075,27 16,27C9.925,27 5,22.075 5,16C5,9.925 9.925,5 16,5C22.075,5 27,9.925 27,16ZM10.75,15.25C10.336,15.25 10,15.586 10,16C10,16.414 10.336,16.75 10.75,16.75H21.25C21.664,16.75 22,16.414 22,16C22,15.586 21.664,15.25 21.25,15.25H10.75Z"
android:fillColor="@color/glyph_active"
android:fillType="evenOdd"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M11,6.5H21C23.485,6.5 25.5,8.515 25.5,11V21C25.5,23.485 23.485,25.5 21,25.5H11C8.515,25.5 6.5,23.485 6.5,21V11C6.5,8.515 8.515,6.5 11,6.5ZM5,11C5,7.686 7.686,5 11,5H21C24.314,5 27,7.686 27,11V21C27,24.314 24.314,27 21,27H11C7.686,27 5,24.314 5,21V11ZM19.535,20.592C19.828,20.885 20.303,20.885 20.596,20.592C20.889,20.299 20.889,19.824 20.596,19.531L17.061,15.996L20.596,12.46C20.889,12.167 20.889,11.693 20.596,11.4C20.303,11.107 19.828,11.107 19.535,11.4L16,14.935L12.465,11.4C12.172,11.107 11.697,11.107 11.404,11.4C11.111,11.693 11.111,12.167 11.404,12.46L14.939,15.996L11.404,19.531C11.111,19.824 11.111,20.299 11.404,20.592C11.697,20.885 12.172,20.885 12.465,20.592L16,17.057L19.535,20.592Z"
android:fillColor="@color/glyph_active"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M13.727,19.18L15.398,24H17L11.316,8H9.684L4,24H5.602L7.273,19.18H13.727ZM13.269,17.867H7.731L10.5,9.898L13.269,17.867ZM22.749,24.273L22.803,24.273L22.857,24.273C24.616,24.273 25.676,23.398 26.238,22.457C26.311,22.339 26.375,22.22 26.43,22.102H26.515V24H28V15.852C28,12.633 25.603,11.836 23.785,11.836L23.73,11.836L23.677,11.836C21.86,11.836 19.988,12.563 19.184,14.523L20.435,14.94L20.599,15L20.601,14.995L20.603,14.996C20.636,14.918 20.672,14.841 20.711,14.765C21.196,13.849 22.216,13.103 23.77,13.086C25.537,13.106 26.515,14.102 26.515,15.727V16.008C26.515,16.812 25.639,16.915 24.05,17.102C23.847,17.126 23.632,17.151 23.406,17.18C20.723,17.516 18.844,18.273 18.844,20.648C18.844,22.961 20.591,24.273 22.749,24.273ZM20.329,20.711C20.329,22.147 21.462,22.981 22.989,23C25.154,22.973 26.515,21.351 26.515,19.398V17.748C25.973,18.094 24.418,18.29 23.515,18.398C21.504,18.648 20.329,19.258 20.329,20.711Z"
android:fillColor="@color/glyph_active"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,6 +1,5 @@
<?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"
@ -13,7 +12,7 @@
style="@style/BlockCellTextContentStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/item_block_multi_select_mode_selector"
android:background="@null"
android:focusable="true"
android:textIsSelectable="true"
tools:text="@string/default_text_placeholder" />

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/shape_primary"/>

View file

@ -1,25 +0,0 @@
<?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="@dimen/item_block_table_cell_width"
android:layout_height="@dimen/item_block_table_cell_height">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/textContent"
style="@style/BlockCellTextContentStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="end"
android:maxLines="2"
android:singleLine="false"
tools:text="@string/default_text_placeholder" />
<View
android:id="@+id/selection"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_table_cell_board_all"
android:visibility="invisible" />
</FrameLayout>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
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" />

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="52dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginEnd="@dimen/dp_10"
@ -15,20 +15,22 @@
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:src="@drawable/ic_style_32"/>
</FrameLayout>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:fontFamily="@font/inter_regular"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:textColor="@color/text_secondary"
android:textSize="11sp"
tools:text="Delete" />
tools:text="Reset Style" />
</LinearLayout>

View file

@ -540,10 +540,10 @@
<string name="item_relation_create_from_scratch_title">Type</string>
<string name="btn_restore">Restore</string>
<string name="simple_tables_widget_item_clear_contents">Clear contents</string>
<string name="simple_tables_widget_item_clear_color">Color</string>
<string name="simple_tables_widget_item_clear_style">Style</string>
<string name="simple_tables_widget_item_clear_clear_style">Clear style</string>
<string name="simple_tables_widget_item_clear_contents">Clear</string>
<string name="simple_tables_widget_item_color">Color</string>
<string name="simple_tables_widget_item_style">Style</string>
<string name="simple_tables_widget_item_clear_style">Reset Style</string>
<string name="simple_tables_widget_item_insert_left">Insert left</string>
<string name="simple_tables_widget_item_insert_right">Insert right</string>
<string name="simple_tables_widget_item_move_left">Move left</string>

View file

@ -0,0 +1,24 @@
package com.anytypeio.anytype.domain.block.interactor
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.block.repo.BlockRepository
class ClearBlockStyle(
private val repository: BlockRepository,
) : BaseUseCase<Payload, ClearBlockStyle.Params>() {
data class Params(
val ctx: Id,
val blockIds: List<Id>
)
override suspend fun run(params: Params): Either<Throwable, Payload> = safe {
repository.clearBlockStyle(
ctx = params.ctx,
blockIds = params.blockIds
)
}
}

View file

@ -136,20 +136,48 @@ sealed class ControlPanelMachine {
val state: StyleToolbarState.Background
) : StylingToolbar()
data class OnUpdateColorBackgroundToolbar(
val state: StyleToolbarState.ColorBackground,
val navigateFromStylingTextToolbar: Boolean,
) : StylingToolbar()
data class OnUpdateOtherToolbar(val state: StyleToolbarState.Other) : StylingToolbar()
object OnExtraClosed : StylingToolbar()
object OnColorBackgroundClosed : StylingToolbar()
data class OnClose(val focused: Boolean) : StylingToolbar()
object OnCloseMulti : StylingToolbar()
object OnExit : StylingToolbar()
object OnBackgroundClosed : StylingToolbar()
}
/**
* Texted Block color & background toolbar related events
*/
sealed class ColorBackgroundToolbar : Event() {
data class Show(
val state: StyleToolbarState.ColorBackground,
val navigateFromStylingTextToolbar: Boolean,
val navigatedFromCellsMenu: Boolean
) : ColorBackgroundToolbar()
data class Update(
val state: StyleToolbarState.ColorBackground
) : ColorBackgroundToolbar()
data class Hide(val focused: Boolean) : ColorBackgroundToolbar()
}
/**
* Texted Block other toolbar related events
*/
sealed class OtherToolbar : Event() {
data class Show(
val state: StyleToolbarState.Other,
val navigateFromStylingTextToolbar: Boolean,
val navigatedFromCellsMenu: Boolean
) : OtherToolbar()
data class Update(
val state: StyleToolbarState.Other
) : OtherToolbar()
object Hide : OtherToolbar()
}
/**
* Multi-select-related events
*/
@ -336,6 +364,12 @@ sealed class ControlPanelMachine {
is Event.StylingToolbar -> {
handleStylingToolbarEvent(event, state)
}
is Event.ColorBackgroundToolbar -> {
handleColorBackgroundToolbarEvents(event, state)
}
is Event.OtherToolbar -> {
handleOtherToolbarEvents(event, state)
}
is Event.MarkupToolbar.OnMarkupColorToggleClicked -> {
val isVisible = if (state.markupColorToolbar.isVisible) {
state.markupMainToolbar.isBackgroundColorSelected
@ -575,31 +609,6 @@ sealed class ControlPanelMachine {
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
is Event.StylingToolbar.OnUpdateOtherToolbar -> {
state.copy(
styleTextToolbar = Toolbar.Styling.reset(),
styleExtraToolbar = Toolbar.Styling.Extra(true, event.state),
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
is Event.StylingToolbar.OnExtraClosed -> {
state.copy(
styleTextToolbar = state.styleTextToolbar.copy(
isVisible = true
),
styleExtraToolbar = Toolbar.Styling.Extra.reset(),
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
is Event.StylingToolbar.OnColorBackgroundClosed -> {
state.copy(
styleTextToolbar = state.styleTextToolbar.copy(
isVisible = state.styleColorBackgroundToolbar.navigatedFromStylingTextToolbar
),
styleColorBackgroundToolbar = Toolbar.Styling.ColorBackground.reset(),
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
is Event.StylingToolbar.OnBackgroundClosed -> {
state.copy(
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
@ -622,19 +631,127 @@ sealed class ControlPanelMachine {
)
)
}
is Event.StylingToolbar.OnUpdateColorBackgroundToolbar -> {
state.copy(
mainToolbar = Toolbar.Main.reset(),
styleColorBackgroundToolbar = Toolbar.Styling.ColorBackground(
isVisible = true,
state = event.state,
navigatedFromStylingTextToolbar = event.navigateFromStylingTextToolbar,
),
navigationToolbar = Toolbar.Navigation.reset(),
styleTextToolbar = Toolbar.Styling.reset(),
styleBackgroundToolbar = Toolbar.Styling.Background.reset(),
styleExtraToolbar = Toolbar.Styling.Extra.reset()
)
}
private fun handleColorBackgroundToolbarEvents(
event: Event.ColorBackgroundToolbar,
state: ControlPanelState
): ControlPanelState {
return when (event) {
is Event.ColorBackgroundToolbar.Show -> {
state.copy(
styleColorBackgroundToolbar = Toolbar.Styling.ColorBackground(
isVisible = true,
state = event.state,
navigatedFromStylingTextToolbar = event.navigateFromStylingTextToolbar,
navigatedFromCellsMenu = event.navigatedFromCellsMenu
),
simpleTableWidget = state.simpleTableWidget.copy(
isVisible = false
),
mainToolbar = Toolbar.Main.reset(),
navigationToolbar = Toolbar.Navigation.reset(),
styleTextToolbar = Toolbar.Styling.reset(),
styleBackgroundToolbar = Toolbar.Styling.Background.reset(),
styleExtraToolbar = Toolbar.Styling.Extra.reset()
)
}
is Event.ColorBackgroundToolbar.Update -> {
state.copy(
mainToolbar = Toolbar.Main.reset(),
styleColorBackgroundToolbar = state.styleColorBackgroundToolbar.copy(
state = event.state
),
simpleTableWidget = state.simpleTableWidget.copy(
isVisible = false
),
navigationToolbar = Toolbar.Navigation.reset(),
styleTextToolbar = Toolbar.Styling.reset(),
styleBackgroundToolbar = Toolbar.Styling.Background.reset(),
styleExtraToolbar = Toolbar.Styling.Extra.reset()
)
}
is Event.ColorBackgroundToolbar.Hide -> {
var mainToolbar = Toolbar.Main.reset()
var navigationToolbar = Toolbar.Navigation.reset()
var styleTextToolbar = state.styleTextToolbar
var simpleTableWidget = state.simpleTableWidget
when {
state.styleColorBackgroundToolbar.navigatedFromStylingTextToolbar -> {
styleTextToolbar = styleTextToolbar.copy(
isVisible = true
)
}
state.styleColorBackgroundToolbar.navigatedFromCellsMenu -> {
simpleTableWidget = simpleTableWidget.copy(
isVisible = true
)
}
!state.styleColorBackgroundToolbar.navigatedFromStylingTextToolbar &&
!state.styleColorBackgroundToolbar.navigatedFromCellsMenu -> {
if (event.focused) {
mainToolbar = mainToolbar.copy(isVisible = true)
} else {
navigationToolbar = navigationToolbar.copy(isVisible = true)
}
}
}
state.copy(
styleTextToolbar = styleTextToolbar,
simpleTableWidget = simpleTableWidget,
mainToolbar = mainToolbar,
navigationToolbar = navigationToolbar,
styleColorBackgroundToolbar = Toolbar.Styling.ColorBackground.reset(),
styleBackgroundToolbar = Toolbar.Styling.Background.reset(),
)
}
}
}
private fun handleOtherToolbarEvents(
event: Event.OtherToolbar,
state: ControlPanelState
): ControlPanelState {
return when (event) {
is Event.OtherToolbar.Show -> {
state.copy(
styleTextToolbar = Toolbar.Styling.reset(),
styleExtraToolbar = Toolbar.Styling.Extra(
isVisible = true,
state = event.state,
navigatedFromStylingTextToolbar = event.navigateFromStylingTextToolbar,
navigatedFromCellsMenu = event.navigatedFromCellsMenu
),
simpleTableWidget = state.simpleTableWidget.copy(
isVisible = false
),
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
is Event.OtherToolbar.Update -> {
state.copy(
styleTextToolbar = Toolbar.Styling.reset(),
styleExtraToolbar = state.styleExtraToolbar.copy(
state = event.state
),
simpleTableWidget = state.simpleTableWidget.copy(
isVisible = false
),
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
Event.OtherToolbar.Hide -> {
state.copy(
styleExtraToolbar = Toolbar.Styling.Extra.reset(),
simpleTableWidget = state.simpleTableWidget.copy(
isVisible = state.styleExtraToolbar.navigatedFromCellsMenu
),
styleTextToolbar = state.styleTextToolbar.copy(
isVisible = state.styleColorBackgroundToolbar.navigatedFromStylingTextToolbar
),
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
)
}
}
}

View file

@ -79,7 +79,7 @@ interface Editor {
/**
* Editor in simple table menu mode.
*/
data class Table(val tableId: Id) : Mode()
data class Table(val tableId: Id, var targets: Set<Id>) : Mode()
}
class Storage {

View file

@ -736,10 +736,7 @@ class EditorViewModel(
if (state.styleColorBackgroundToolbar.isVisible) {
val ids = mode.getIds()
if (ids.isNullOrEmpty()) return
onSendUpdateStyleColorBackgroundToolbarEvent(
ids,
state.styleColorBackgroundToolbar.navigatedFromStylingTextToolbar
)
onSendUpdateStyleColorBackgroundToolbarEvent(ids)
}
if (state.styleExtraToolbar.isVisible) {
val ids = mode.getIds()
@ -768,16 +765,42 @@ class EditorViewModel(
)
}
private fun onSendUpdateStyleColorBackgroundToolbarEvent(
private fun onShowColorBackgroundToolbarEvent(
ids: List<Id>,
navigateFromStylingTextToolbar: Boolean,
navigatedFromCellsMenu: Boolean,
navigateFromStylingTextToolbar: Boolean
) {
val selected = blocks.filter { ids.contains(it.id) }
val state = selected.getStyleColorBackgroundToolbarState()
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.StylingToolbar.OnUpdateColorBackgroundToolbar(
state,
navigateFromStylingTextToolbar
ControlPanelMachine.Event.ColorBackgroundToolbar.Show(
state = state,
navigatedFromCellsMenu = navigatedFromCellsMenu,
navigateFromStylingTextToolbar = navigateFromStylingTextToolbar
)
)
}
private fun onSendUpdateStyleColorBackgroundToolbarEvent(ids: List<Id>) {
val selected = blocks.filter { ids.contains(it.id) }
val state = selected.getStyleColorBackgroundToolbarState()
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.ColorBackgroundToolbar.Update(state)
)
}
private fun onShowStyleOtherToolbarEvent(
ids: List<Id>,
navigatedFromCellsMenu: Boolean,
navigateFromStylingTextToolbar: Boolean
) {
val selected = blocks.filter { ids.contains(it.id) }
val state = selected.map { it.content.asText() }.getStyleOtherToolbarState()
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.OtherToolbar.Show(
state = state,
navigatedFromCellsMenu = navigatedFromCellsMenu,
navigateFromStylingTextToolbar = navigateFromStylingTextToolbar
)
)
}
@ -786,7 +809,7 @@ class EditorViewModel(
val selected = blocks.filter { ids.contains(it.id) }
val state = selected.map { it.content.asText() }.getStyleOtherToolbarState()
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.StylingToolbar.OnUpdateOtherToolbar(state)
ControlPanelMachine.Event.OtherToolbar.Update(state)
)
}
@ -2289,8 +2312,9 @@ class EditorViewModel(
renderCommand.send(Unit)
}
when {
target is BlockView.Title -> onSendUpdateStyleColorBackgroundToolbarEvent(
target is BlockView.Title -> onShowColorBackgroundToolbarEvent(
ids = listOf(targetId),
navigatedFromCellsMenu = false,
navigateFromStylingTextToolbar = false
)
content.style == Content.Text.Style.CODE_SNIPPET -> {
@ -2414,14 +2438,15 @@ class EditorViewModel(
fun onCloseBlockStyleExtraToolbarClicked() {
Timber.d("onCloseBlockStyleExtraToolbarClicked, ")
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.StylingToolbar.OnExtraClosed
ControlPanelMachine.Event.OtherToolbar.Hide
)
}
fun onCloseBlockStyleColorToolbarClicked() {
Timber.d("onCloseBlockStyleColorToolbarClicked, ")
val focused = !orchestrator.stores.focus.current().isEmpty
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.StylingToolbar.OnColorBackgroundClosed
ControlPanelMachine.Event.ColorBackgroundToolbar.Hide(focused = focused)
)
}
@ -2512,15 +2537,20 @@ class EditorViewModel(
Timber.d("onBlockStyleToolbarOtherClicked, ")
val ids = mode.getIds()
if (ids.isNullOrEmpty()) return
onSendUpdateStyleOtherToolbarEvent(ids)
onShowStyleOtherToolbarEvent(
ids = ids,
navigatedFromCellsMenu = false,
navigateFromStylingTextToolbar = true
)
}
fun onBlockStyleToolbarColorClicked() {
Timber.d("onBlockStyleToolbarColorClicked, ")
val ids = mode.getIds()
if (ids.isNullOrEmpty()) return
onSendUpdateStyleColorBackgroundToolbarEvent(
onShowColorBackgroundToolbarEvent(
ids = ids,
navigatedFromCellsMenu = false,
navigateFromStylingTextToolbar = true
)
}
@ -2758,38 +2788,6 @@ class EditorViewModel(
}
}
private fun onTableRowEmptyCellClicked(cellId: Id, rowId: Id, tableId: Id) {
fillTableBlockRow(
cellId = cellId,
targetIds = listOf(rowId),
tableId = tableId
)
}
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,
targetIds = targetIds
)
)
}
if (!BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = cellId,
table = tableId
)
)
}
}
fun onAddDividerBlockClicked(style: Content.Divider.Style) {
Timber.d("onAddDividerBlockClicked, style:[$style]")
addDividerBlock(style)
@ -3825,48 +3823,26 @@ class EditorViewModel(
dispatch(Command.OpenTextBlockIconPicker(clicked.blockId))
}
is ListenerType.TableEmptyCell -> {
when (mode) {
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.cell.getId(),
tableId = clicked.cell.tableId
)
onTableRowEmptyCellClicked(
cellId = clicked.cell.getId(),
rowId = clicked.cell.rowId,
tableId = clicked.cell.tableId
)
}
}
when (val m = mode) {
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.cell.getId(),
tableId = clicked.cell.tableId
)
onTableRowEmptyCellClicked(
cellId = clicked.cell.getId(),
rowId = clicked.cell.rowId,
tableId = clicked.cell.tableId
rowId = clicked.cell.rowId
)
}
EditorMode.Select -> {
onBlockMultiSelectClicked(
target = clicked.cell.tableId
)
}
EditorMode.Select -> onBlockMultiSelectClicked(target = clicked.cell.tableId)
is EditorMode.Table -> {
val modeTableId = (mode as EditorMode.Table).tableId
val modeTableId = m.tableId
val cellTableId = clicked.cell.tableId
if (cellTableId == modeTableId) {
onTableRowEmptyCellClicked(
cellId = clicked.cell.getId(),
rowId = clicked.cell.rowId
)
proceedWithClickingOnCellInTableMode(
cell = clicked.cell,
tableId = cellTableId
@ -3879,48 +3855,12 @@ class EditorViewModel(
}
}
is ListenerType.TableTextCell -> {
when (mode) {
EditorMode.Edit -> {
if (currentSelection().isNotEmpty()) {
Timber.e("Some other blocks are selected, amend table cell click")
return
}
proceedWithSelectingCell(
cellId = clicked.cell.getId(),
tableId = clicked.cell.tableId
)
if (!BuildConfig.USE_SIMPLE_TABLES_IN_EDITOR_EDDITING) {
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = clicked.cell.getId(),
table = clicked.cell.tableId
)
)
}
when (val m = mode) {
EditorMode.Select -> {
onBlockMultiSelectClicked(target = clicked.cell.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.cell.getId(),
tableId = clicked.cell.tableId
)
dispatch(
Command.OpenSetBlockTextValueScreen(
ctx = context,
block = clicked.cell.getId(),
table = clicked.cell.tableId
)
)
}
}
EditorMode.Select -> onBlockMultiSelectClicked(target = clicked.cell.tableId)
is EditorMode.Table -> {
val modeTableId = (mode as EditorMode.Table).tableId
val modeTableId = m.tableId
val cellTableId = clicked.cell.tableId
if (cellTableId == modeTableId) {
proceedWithClickingOnCellInTableMode(
@ -6124,27 +6064,58 @@ class EditorViewModel(
//endregion
//region SIMPLE TABLES
fun onCellsSelectionDoneClick() {
fun onCellSelectionTopToolbarDoneButtonClick() {
Timber.d("onCellSelectionTopToolbarDoneButtonClick, ")
proceedWithExitingTableMode()
}
fun onHideSimpleTableWidget() {
Timber.d("onHideSimpleTableWidget, ")
proceedWithExitingTableMode()
}
fun onSimpleTableWidgetItemClicked(item: SimpleTableWidgetItem) {
Timber.d("onSimpleTableWidgetItemClicked, item:[$item]")
when (item) {
SimpleTableWidgetItem.Cell.ClearContents -> {
val selected = currentSelection()
viewModelScope.launch {
orchestrator.proxies.intents.send(
Intent.Text.ClearContent(
context = context,
targets = selected.toList()
targets = currentSelection().toList()
)
)
}
}
SimpleTableWidgetItem.Cell.ClearStyle -> {
viewModelScope.launch {
orchestrator.proxies.intents.send(
Intent.Text.ClearStyle(
context = context,
targets = currentSelection().toList()
)
)
}
}
SimpleTableWidgetItem.Cell.Color -> {
onShowColorBackgroundToolbarEvent(
ids = currentSelection().toList(),
navigatedFromCellsMenu = true,
navigateFromStylingTextToolbar = false
)
}
SimpleTableWidgetItem.Cell.Style -> {
val selected = blocks.filter { currentSelection().contains(it.id) }
val state = selected.map { it.content.asText() }.getStyleOtherToolbarState()
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.OtherToolbar.Show(
state = state,
navigatedFromCellsMenu = true,
navigateFromStylingTextToolbar = false
)
)
}
else -> Unit
}
}
@ -6154,9 +6125,9 @@ class EditorViewModel(
*/
private fun proceedWithEnterTableMode(cell: BlockView.Table.Cell) {
viewModelScope.launch {
mode = EditorMode.Table(tableId = cell.tableId)
clearSelections()
toggleSelection(target = cell.getId())
mode = EditorMode.Table(tableId = cell.tableId, targets = currentSelection())
orchestrator.stores.focus.update(Editor.Focus.empty())
orchestrator.stores.views.update(
@ -6212,6 +6183,7 @@ class EditorViewModel(
cell: BlockView.Table.Cell
) {
toggleSelection(target = cell.getId())
(mode as? EditorMode.Table)?.targets = currentSelection()
if (currentSelection().isEmpty()) {
proceedWithExitingTableMode()
} else {
@ -6240,14 +6212,31 @@ class EditorViewModel(
}
}
private fun proceedWithSelectingCell(cellId: Id, tableId: Id) {
clearSelections()
select(listOf(cellId))
private fun onTableRowEmptyCellClicked(cellId: Id, rowId: Id) {
fillTableRow(
cellId = cellId,
targetIds = listOf(rowId)
)
}
private fun fillTableRow(cellId: Id, targetIds: List<Id>) {
viewModelScope.launch {
orchestrator.stores.focus.update(Editor.Focus.empty())
renderCommand.send(Unit)
setFocusInCellWhenInEditMode(cellId = cellId)
orchestrator.proxies.intents.send(
Intent.Table.FillTableRow(
ctx = context,
targetIds = targetIds
)
)
}
}
private fun setFocusInCellWhenInEditMode(cellId: Id) {
if (mode == EditorMode.Edit) {
val focus = Editor.Focus(id = cellId, cursor = null)
viewModelScope.launch {
orchestrator.stores.focus.update(focus)
}
}
}
@ -6258,5 +6247,4 @@ class EditorViewModel(
}
private const val NO_POSITION = -1
private const val PREVIEW_POSITION = 2
private const val OPEN_OBJECT_POSITION = 4

View file

@ -174,6 +174,11 @@ sealed class Intent {
val context: Id,
val targets: List<Id>
): Text()
class ClearStyle(
val context: Id,
val targets: List<Id>
) : Text()
}
sealed class Media : Intent() {

View file

@ -6,6 +6,7 @@ import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.domain.base.suspendFold
import com.anytypeio.anytype.domain.block.UpdateDivider
import com.anytypeio.anytype.domain.block.interactor.ClearBlockContent
import com.anytypeio.anytype.domain.block.interactor.ClearBlockStyle
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
import com.anytypeio.anytype.domain.block.interactor.DuplicateBlock
import com.anytypeio.anytype.domain.block.interactor.MergeBlocks
@ -90,7 +91,8 @@ class Orchestrator(
val proxies: Editor.Proxer,
val textInteractor: Interactor.TextInteractor,
private val analytics: Analytics,
private val clearBlockContent: ClearBlockContent
private val clearBlockContent: ClearBlockContent,
private val clearBlockStyle: ClearBlockStyle
) {
private val defaultOnError: suspend (Throwable) -> Unit = { Timber.e(it) }
@ -640,6 +642,17 @@ class Orchestrator(
success = { payload -> proxies.payloads.send(payload) }
)
}
is Intent.Text.ClearStyle -> {
clearBlockStyle(
params = ClearBlockStyle.Params(
ctx = intent.context,
blockIds = intent.targets
)
).process(
failure = defaultOnError,
success = { payload -> proxies.payloads.send(payload) }
)
}
}
}
}

View file

@ -131,12 +131,16 @@ data class ControlPanelState(
data class Extra(
override val isVisible: Boolean,
val state: StyleToolbarState.Other
val state: StyleToolbarState.Other,
val navigatedFromStylingTextToolbar: Boolean,
val navigatedFromCellsMenu: Boolean
) : Toolbar() {
companion object {
fun reset() = Extra(
isVisible = false,
state = StyleToolbarState.Other.empty()
state = StyleToolbarState.Other.empty(),
navigatedFromStylingTextToolbar = false,
navigatedFromCellsMenu = false
)
}
}
@ -145,12 +149,14 @@ data class ControlPanelState(
override val isVisible: Boolean,
val state: StyleToolbarState.ColorBackground,
val navigatedFromStylingTextToolbar: Boolean,
val navigatedFromCellsMenu: Boolean
) : Toolbar() {
companion object {
fun reset() = ColorBackground(
isVisible = false,
state = StyleToolbarState.ColorBackground.empty(),
navigatedFromStylingTextToolbar = false,
navigatedFromCellsMenu = false
)
}
}

View file

@ -11,6 +11,7 @@ import timber.log.Timber
fun Editor.Mode.getIds(): List<Id>? = when (this) {
is Editor.Mode.Styling.Multi -> targets.toList()
is Editor.Mode.Styling.Single -> listOf(target)
is Editor.Mode.Table -> targets.toList()
else -> {
Timber.e("Couldn't get ids of selected blocks, wrong Editor Mode : $this")
null

View file

@ -370,9 +370,9 @@ fun List<BlockView>.updateTableBlockSelection(tableId: Id, selection: List<Id>):
fun List<BlockView.Table.Cell>.getSimpleTableWidgetItems(): List<SimpleTableWidgetItem> {
return listOf(
SimpleTableWidgetItem.Cell.ClearContents
// SimpleTableWidgetItem.Cell.Style,
// SimpleTableWidgetItem.Cell.Color,
// SimpleTableWidgetItem.Cell.ClearStyle
SimpleTableWidgetItem.Cell.ClearContents,
SimpleTableWidgetItem.Cell.Color,
SimpleTableWidgetItem.Cell.Style,
SimpleTableWidgetItem.Cell.ClearStyle
)
}

View file

@ -28,6 +28,7 @@ import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.base.Result
import com.anytypeio.anytype.domain.block.UpdateDivider
import com.anytypeio.anytype.domain.block.interactor.ClearBlockContent
import com.anytypeio.anytype.domain.block.interactor.ClearBlockStyle
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
import com.anytypeio.anytype.domain.block.interactor.DuplicateBlock
import com.anytypeio.anytype.domain.block.interactor.MergeBlocks
@ -343,6 +344,7 @@ open class EditorViewModelTest {
private lateinit var setDocImageIcon: SetDocumentImageIcon
private lateinit var objectToSet: ConvertObjectToSet
private lateinit var clearBlockContent: ClearBlockContent
private lateinit var clearBlockStyle: ClearBlockStyle
val root = MockDataFactory.randomUuid()
@ -3941,6 +3943,7 @@ open class EditorViewModelTest {
setDocImageIcon = SetDocumentImageIcon(repo)
downloadUnsplashImage = DownloadUnsplashImage(unsplashRepo)
clearBlockContent = ClearBlockContent(repo)
clearBlockStyle = ClearBlockStyle(repo)
vm = EditorViewModel(
openPage = openPage,
@ -4000,7 +4003,8 @@ open class EditorViewModelTest {
setObjectType = setObjectType,
createTable = createTable,
fillTableRow = fillTableRow,
clearBlockContent = clearBlockContent
clearBlockContent = clearBlockContent,
clearBlockStyle = clearBlockStyle
),
analytics = analytics,
dispatcher = Dispatcher.Default(),

View file

@ -16,6 +16,7 @@ import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.base.Result
import com.anytypeio.anytype.domain.block.UpdateDivider
import com.anytypeio.anytype.domain.block.interactor.ClearBlockContent
import com.anytypeio.anytype.domain.block.interactor.ClearBlockStyle
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
import com.anytypeio.anytype.domain.block.interactor.DuplicateBlock
import com.anytypeio.anytype.domain.block.interactor.MergeBlocks
@ -275,6 +276,7 @@ open class EditorPresentationTestSetup {
private lateinit var setDocImageIcon: SetDocumentImageIcon
private lateinit var objectToSet: ConvertObjectToSet
private lateinit var clearBlockContent: ClearBlockContent
private lateinit var clearBlockStyle: ClearBlockStyle
open lateinit var orchestrator: Orchestrator
@ -297,6 +299,7 @@ open class EditorPresentationTestSetup {
applyTemplate = applyTemplate
)
clearBlockContent = ClearBlockContent(repo)
clearBlockStyle = ClearBlockStyle(repo)
orchestrator = Orchestrator(
createBlock = createBlock,
@ -339,7 +342,8 @@ open class EditorPresentationTestSetup {
setObjectType = setObjectType,
createTable = createTable,
fillTableRow = fillTableRow,
clearBlockContent = clearBlockContent
clearBlockContent = clearBlockContent,
clearBlockStyle = clearBlockStyle
)
return EditorViewModel(

View file

@ -173,9 +173,10 @@ class EditorTableBlockTest : EditorPresentationTestSetup() {
)
}
val selectedState = vm.currentSelection()
runBlocking {
assertEquals(1, selectedState.size)
assertEquals(0, selectedState.size)
verifyNoInteractions(fillTableRow)
}
}