diff --git a/app/src/androidTest/java/com/anytypeio/anytype/features/editor/base/EditorTestSetup.kt b/app/src/androidTest/java/com/anytypeio/anytype/features/editor/base/EditorTestSetup.kt index ac739d5528..3f807aa80e 100644 --- a/app/src/androidTest/java/com/anytypeio/anytype/features/editor/base/EditorTestSetup.kt +++ b/app/src/androidTest/java/com/anytypeio/anytype/features/editor/base/EditorTestSetup.kt @@ -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, diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/EditorDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/EditorDI.kt index a323a544bc..eeb0311a51 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/EditorDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/EditorDI.kt @@ -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 { diff --git a/app/src/main/java/com/anytypeio/anytype/ui/editor/EditorFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/editor/EditorFragment.kt index 0ecbba7795..2d565bc6f9 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/editor/EditorFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/editor/EditorFragment.kt @@ -603,7 +603,7 @@ open class EditorFragment : NavigationFragment(R.layout.f .doneButton .clicks() .throttleFirst() - .onEach { vm.onCellsSelectionDoneClick() } + .onEach { vm.onCellSelectionTopToolbarDoneButtonClick() } .launchIn(lifecycleScope) binding.bottomToolbar diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt index 3f9e0e732d..21caaca143 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockAdapter.kt @@ -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, diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockViewDiffUtil.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockViewDiffUtil.kt index 63320b504d..24fa51f1df 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockViewDiffUtil.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/BlockViewDiffUtil.kt @@ -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 } } \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableBlockAdapter.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableBlockAdapter.kt deleted file mode 100644 index 0b4bda304e..0000000000 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableBlockAdapter.kt +++ /dev/null @@ -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(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 - ) { - if (payloads.isEmpty()) { - onBindViewHolder(holder, position) - } else { - if (holder is TableCellHolder.TableTextCellHolder) { - holder.processChangePayload( - payloads = payloads.typeOf().first(), - cell = getItem(position) - ) - } - } - } -} \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableCellsDiffUtil.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableCellsDiffUtil.kt index e4a8c22c4f..2952598f7f 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableCellsDiffUtil.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableCellsDiffUtil.kt @@ -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() { +class TableCellsDiffUtil( + private val old: List, + private val new: List +) : 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() - 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 - ) { - 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 } \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableEditableCellsAdapter.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableEditableCellsAdapter.kt index 27f1ec922d..b97866cfc3 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableEditableCellsAdapter.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/TableEditableCellsAdapter.kt @@ -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, @@ -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.Adapter(), ItemProviderAdapter { - 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 { 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 { 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 ) { - 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, - private val new: List - ) : 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 - } - } } \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/EditableCellHolder.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/EditableCellHolder.kt index 4c2c047539..59b575dde5 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/EditableCellHolder.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/EditableCellHolder.kt @@ -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(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 { - 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, + 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) {} diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableBlockHolder.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableBlockHolder.kt index 9e2d26735f..f720bf5a0a 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableBlockHolder.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableBlockHolder.kt @@ -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)) { diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableTextCellHolder.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableTextCellHolder.kt deleted file mode 100644 index 3f195cc308..0000000000 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/table/holders/TableTextCellHolder.kt +++ /dev/null @@ -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() -} \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/layout/TableCellSelectionDecoration.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/layout/TableCellSelectionDecoration.kt index 35f2e62e59..7ab316671a 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/layout/TableCellSelectionDecoration.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/layout/TableCellSelectionDecoration.kt @@ -19,7 +19,7 @@ class TableCellSelectionDecoration( selectionState.addAll(newState) } - override fun onDraw( + override fun onDrawOver( canvas: Canvas, parent: RecyclerView, state: RecyclerView.State diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/toolbar/table/SimpleTableWidgetAdapter.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/toolbar/table/SimpleTableWidgetAdapter.kt index e4e6ee26cf..a2ded90db4 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/toolbar/table/SimpleTableWidgetAdapter.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/toolbar/table/SimpleTableWidgetAdapter.kt @@ -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 -> { diff --git a/core-ui/src/main/res/drawable/ic_clear_32.xml b/core-ui/src/main/res/drawable/ic_clear_32.xml new file mode 100644 index 0000000000..0eeb6befff --- /dev/null +++ b/core-ui/src/main/res/drawable/ic_clear_32.xml @@ -0,0 +1,10 @@ + + + diff --git a/core-ui/src/main/res/drawable/ic_color_32.png b/core-ui/src/main/res/drawable/ic_color_32.png new file mode 100644 index 0000000000..823e2d31f6 Binary files /dev/null and b/core-ui/src/main/res/drawable/ic_color_32.png differ diff --git a/core-ui/src/main/res/drawable/ic_reset_32.xml b/core-ui/src/main/res/drawable/ic_reset_32.xml new file mode 100644 index 0000000000..7e384b0804 --- /dev/null +++ b/core-ui/src/main/res/drawable/ic_reset_32.xml @@ -0,0 +1,10 @@ + + + diff --git a/core-ui/src/main/res/drawable/ic_style_32.xml b/core-ui/src/main/res/drawable/ic_style_32.xml new file mode 100644 index 0000000000..e107183183 --- /dev/null +++ b/core-ui/src/main/res/drawable/ic_style_32.xml @@ -0,0 +1,10 @@ + + + diff --git a/core-ui/src/main/res/layout/item_block_table_row_item_editable.xml b/core-ui/src/main/res/layout/item_block_table_cell.xml similarity index 87% rename from core-ui/src/main/res/layout/item_block_table_row_item_editable.xml rename to core-ui/src/main/res/layout/item_block_table_cell.xml index 1d5d6f5eca..1aaf1141ac 100644 --- a/core-ui/src/main/res/layout/item_block_table_row_item_editable.xml +++ b/core-ui/src/main/res/layout/item_block_table_cell.xml @@ -1,6 +1,5 @@ diff --git a/core-ui/src/main/res/layout/item_block_table_column_header.xml b/core-ui/src/main/res/layout/item_block_table_column_header.xml deleted file mode 100644 index 78458b5ddd..0000000000 --- a/core-ui/src/main/res/layout/item_block_table_column_header.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/core-ui/src/main/res/layout/item_block_table_row_item.xml b/core-ui/src/main/res/layout/item_block_table_row_item.xml deleted file mode 100644 index 7eadc7b3af..0000000000 --- a/core-ui/src/main/res/layout/item_block_table_row_item.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/core-ui/src/main/res/layout/item_block_table_row_item_empty.xml b/core-ui/src/main/res/layout/item_block_table_row_item_empty.xml deleted file mode 100644 index d3cf7d55d8..0000000000 --- a/core-ui/src/main/res/layout/item_block_table_row_item_empty.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/core-ui/src/main/res/layout/item_simple_table_action.xml b/core-ui/src/main/res/layout/item_simple_table_action.xml index 980c89dcc5..208595ef45 100644 --- a/core-ui/src/main/res/layout/item_simple_table_action.xml +++ b/core-ui/src/main/res/layout/item_simple_table_action.xml @@ -1,7 +1,7 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + tools:src="@drawable/ic_style_32"/> + tools:text="Reset Style" /> \ No newline at end of file diff --git a/core-ui/src/main/res/values/strings.xml b/core-ui/src/main/res/values/strings.xml index a01eb8b2ab..f6b69e6515 100644 --- a/core-ui/src/main/res/values/strings.xml +++ b/core-ui/src/main/res/values/strings.xml @@ -540,10 +540,10 @@ Type Restore - Clear contents - Color - Style - Clear style + Clear + Color + Style + Reset Style Insert left Insert right Move left diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/interactor/ClearBlockStyle.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/interactor/ClearBlockStyle.kt new file mode 100644 index 0000000000..b791604775 --- /dev/null +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/interactor/ClearBlockStyle.kt @@ -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() { + + data class Params( + val ctx: Id, + val blockIds: List + ) + + override suspend fun run(params: Params): Either = safe { + repository.clearBlockStyle( + ctx = params.ctx, + blockIds = params.blockIds + ) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/ControlPanelMachine.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/ControlPanelMachine.kt index 56e86cefe9..229e7d932f 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/ControlPanelMachine.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/ControlPanelMachine.kt @@ -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() + ) + } } } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/Editor.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/Editor.kt index a5b2f70466..c7a534dda3 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/Editor.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/Editor.kt @@ -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) : Mode() } class Storage { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt index ddca3a35d3..58f38c2a3b 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt @@ -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, - 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) { + val selected = blocks.filter { ids.contains(it.id) } + val state = selected.getStyleColorBackgroundToolbarState() + controlPanelInteractor.onEvent( + ControlPanelMachine.Event.ColorBackgroundToolbar.Update(state) + ) + } + + private fun onShowStyleOtherToolbarEvent( + ids: List, + 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, 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) { 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 \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Intent.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Intent.kt index 6df45fcb3c..c63b8e2efa 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Intent.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Intent.kt @@ -174,6 +174,11 @@ sealed class Intent { val context: Id, val targets: List ): Text() + + class ClearStyle( + val context: Id, + val targets: List + ) : Text() } sealed class Media : Intent() { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Orchestrator.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Orchestrator.kt index d0af1a3d2f..99b9104d73 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Orchestrator.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Orchestrator.kt @@ -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) } + ) + } } } } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/control/ControlPanelState.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/control/ControlPanelState.kt index e831f3df20..473c929508 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/control/ControlPanelState.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/control/ControlPanelState.kt @@ -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 ) } } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/styling/StyleToolbarExt.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/styling/StyleToolbarExt.kt index f4639bce25..6a6547ffbb 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/styling/StyleToolbarExt.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/styling/StyleToolbarExt.kt @@ -11,6 +11,7 @@ import timber.log.Timber fun Editor.Mode.getIds(): List? = 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 diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/selection/TableCellExt.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/selection/TableCellExt.kt index b309b833cb..7c6d00922e 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/selection/TableCellExt.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/selection/TableCellExt.kt @@ -370,9 +370,9 @@ fun List.updateTableBlockSelection(tableId: Id, selection: List): fun List.getSimpleTableWidgetItems(): List { 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 ) } \ No newline at end of file diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt index f03701a005..a26ebd287d 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt @@ -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(), diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt index d761812d5a..07941aa84e 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt @@ -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( diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/EditorTableBlockTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/EditorTableBlockTest.kt index 3bf0ab8f4e..6b0dcde3b9 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/EditorTableBlockTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/EditorTableBlockTest.kt @@ -173,9 +173,10 @@ class EditorTableBlockTest : EditorPresentationTestSetup() { ) } + val selectedState = vm.currentSelection() runBlocking { - assertEquals(1, selectedState.size) + assertEquals(0, selectedState.size) verifyNoInteractions(fillTableRow) } }