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:
parent
2dafc36f9b
commit
8831bdcc05
35 changed files with 650 additions and 807 deletions
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -19,7 +19,7 @@ class TableCellSelectionDecoration(
|
|||
selectionState.addAll(newState)
|
||||
}
|
||||
|
||||
override fun onDraw(
|
||||
override fun onDrawOver(
|
||||
canvas: Canvas,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
|
|
|
@ -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 -> {
|
||||
|
|
10
core-ui/src/main/res/drawable/ic_clear_32.xml
Normal file
10
core-ui/src/main/res/drawable/ic_clear_32.xml
Normal 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>
|
BIN
core-ui/src/main/res/drawable/ic_color_32.png
Normal file
BIN
core-ui/src/main/res/drawable/ic_color_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
10
core-ui/src/main/res/drawable/ic_reset_32.xml
Normal file
10
core-ui/src/main/res/drawable/ic_reset_32.xml
Normal 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>
|
10
core-ui/src/main/res/drawable/ic_style_32.xml
Normal file
10
core-ui/src/main/res/drawable/ic_style_32.xml
Normal 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>
|
|
@ -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" />
|
|
@ -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"/>
|
|
@ -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>
|
|
@ -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" />
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
|
@ -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() {
|
||||
|
|
|
@ -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) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
|
@ -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(),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -173,9 +173,10 @@ class EditorTableBlockTest : EditorPresentationTestSetup() {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
val selectedState = vm.currentSelection()
|
||||
runBlocking {
|
||||
assertEquals(1, selectedState.size)
|
||||
assertEquals(0, selectedState.size)
|
||||
verifyNoInteractions(fillTableRow)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue