mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
Tech | Legacy style toolbar logic (#2183)
* removed legacy onContextMenuStyleClick from text blocks * remove old style toolbar legacy code * remove legacy styling mode * fix tests Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
parent
9f19016948
commit
503935ce07
30 changed files with 385 additions and 1426 deletions
|
@ -267,7 +267,6 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
onCoverClicked = vm::onAddCoverClicked,
|
||||
onTogglePlaceholderClicked = vm::onTogglePlaceholderClicked,
|
||||
onToggleClicked = vm::onToggleClicked,
|
||||
onContextMenuStyleClick = vm::onEditorContextMenuStyleClicked,
|
||||
onTitleTextInputClicked = vm::onTitleTextInputClicked,
|
||||
onClickListener = vm::onClickListener,
|
||||
clipboardInterceptor = this,
|
||||
|
@ -805,14 +804,6 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
is Command.OpenAddBlockPanel -> {
|
||||
// hideKeyboard()
|
||||
// AddBlockFragment.newInstance(command.ctx).show(childFragmentManager, null)
|
||||
}
|
||||
is Command.OpenTurnIntoPanel -> {
|
||||
// TurnIntoFragment.single(
|
||||
// target = command.target,
|
||||
// excludedCategories = command.excludedCategories,
|
||||
// excludedTypes = command.excludedTypes
|
||||
//
|
||||
// ).show(childFragmentManager, null)
|
||||
}
|
||||
is Command.OpenMultiSelectTurnIntoPanel -> {
|
||||
// TurnIntoFragment.multiple(
|
||||
|
|
|
@ -130,7 +130,6 @@ class BlockAdapter(
|
|||
private val onCoverClicked: () -> Unit,
|
||||
private val onTogglePlaceholderClicked: (String) -> Unit,
|
||||
private val onToggleClicked: (String) -> Unit,
|
||||
private val onContextMenuStyleClick: (IntRange) -> Unit,
|
||||
private val clipboardInterceptor: ClipboardInterceptor,
|
||||
private val onMentionEvent: (MentionEvent) -> Unit,
|
||||
private val onSlashEvent: (SlashEvent) -> Unit,
|
||||
|
@ -170,8 +169,7 @@ class BlockAdapter(
|
|||
R.layout.item_block_text,
|
||||
parent,
|
||||
false
|
||||
),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
)
|
||||
)
|
||||
}
|
||||
HOLDER_TITLE -> {
|
||||
|
@ -300,20 +298,17 @@ class BlockAdapter(
|
|||
}
|
||||
HOLDER_HEADER_ONE -> {
|
||||
HeaderOne(
|
||||
binding = ItemBlockHeaderOneBinding.inflate(inflater, parent, false),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
binding = ItemBlockHeaderOneBinding.inflate(inflater, parent, false)
|
||||
)
|
||||
}
|
||||
HOLDER_HEADER_TWO -> {
|
||||
HeaderTwo(
|
||||
binding = ItemBlockHeaderTwoBinding.inflate(inflater, parent, false),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
binding = ItemBlockHeaderTwoBinding.inflate(inflater, parent, false)
|
||||
)
|
||||
}
|
||||
HOLDER_HEADER_THREE -> {
|
||||
HeaderThree(
|
||||
binding = ItemBlockHeaderThreeBinding.inflate(inflater, parent, false),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
binding = ItemBlockHeaderThreeBinding.inflate(inflater, parent, false)
|
||||
)
|
||||
}
|
||||
HOLDER_CODE_SNIPPET -> {
|
||||
|
@ -325,32 +320,28 @@ class BlockAdapter(
|
|||
Checkbox(
|
||||
binding = ItemBlockCheckboxBinding.inflate(
|
||||
inflater, parent, false
|
||||
),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
)
|
||||
)
|
||||
}
|
||||
HOLDER_BULLET -> {
|
||||
Bulleted(
|
||||
binding = ItemBlockBulletedBinding.inflate(
|
||||
inflater, parent, false
|
||||
),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
)
|
||||
)
|
||||
}
|
||||
HOLDER_NUMBERED -> {
|
||||
Numbered(
|
||||
binding = ItemBlockNumberedBinding.inflate(
|
||||
inflater, parent, false
|
||||
),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
)
|
||||
)
|
||||
}
|
||||
HOLDER_TOGGLE -> {
|
||||
Toggle(
|
||||
binding = ItemBlockToggleBinding.inflate(
|
||||
inflater, parent, false
|
||||
),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
)
|
||||
)
|
||||
}
|
||||
HOLDER_DESCRIPTION -> {
|
||||
|
@ -562,8 +553,7 @@ class BlockAdapter(
|
|||
Highlight(
|
||||
binding = ItemBlockHighlightBinding.inflate(
|
||||
inflater, parent, false
|
||||
),
|
||||
onContextMenuStyleClick = onContextMenuStyleClick
|
||||
)
|
||||
)
|
||||
}
|
||||
HOLDER_RELATION_DEFAULT -> {
|
||||
|
|
|
@ -10,12 +10,13 @@ import android.view.MenuItem
|
|||
import android.widget.TextView
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.*
|
||||
import com.anytypeio.anytype.core_ui.extensions.*
|
||||
import com.anytypeio.anytype.core_ui.extensions.applyMovementMethod
|
||||
import com.anytypeio.anytype.core_ui.extensions.cursorYBottomCoordinate
|
||||
import com.anytypeio.anytype.core_ui.extensions.dark
|
||||
import com.anytypeio.anytype.core_ui.extensions.lighter
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.`interface`.TextHolder
|
||||
import com.anytypeio.anytype.core_ui.menu.EditorContextMenu
|
||||
import com.anytypeio.anytype.core_ui.tools.*
|
||||
import com.anytypeio.anytype.core_ui.widgets.text.MentionSpan
|
||||
import com.anytypeio.anytype.core_utils.ext.hideKeyboard
|
||||
import com.anytypeio.anytype.core_utils.ext.removeSpans
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Markup
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ThemeColor
|
||||
|
@ -34,12 +35,9 @@ interface TextBlockHolder : TextHolder {
|
|||
|
||||
fun getDefaultTextColor(): Int
|
||||
|
||||
fun setup(
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
) {
|
||||
fun setup() {
|
||||
with(content) {
|
||||
setSpannableFactory(DefaultSpannableFactory())
|
||||
//setupSelectionActionMode(onContextMenuStyleClick)
|
||||
setupCustomInsertionActionMode()
|
||||
}
|
||||
}
|
||||
|
@ -394,22 +392,6 @@ interface TextBlockHolder : TextHolder {
|
|||
|
||||
//region CONTEXT MENU
|
||||
|
||||
private fun setupSelectionActionMode(
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
) {
|
||||
with(content) {
|
||||
customSelectionActionModeCallback = EditorContextMenu(
|
||||
onStyleClick = {
|
||||
preserveSelection {
|
||||
content.hideKeyboard()
|
||||
onContextMenuStyleClick.invoke(content.range())
|
||||
//todo maybe add mode.finish
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupCustomInsertionActionMode() {
|
||||
val bookmarkMenuItemTitle = content.resources.getString(R.string.bookmark)
|
||||
content.customInsertionActionModeCallback = object : ActionMode.Callback2() {
|
||||
|
|
|
@ -20,8 +20,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Bulleted(
|
||||
val binding: ItemBlockBulletedBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockBulletedBinding
|
||||
) : Text(binding.root), SupportNesting {
|
||||
|
||||
val indent: View = binding.bulletIndent
|
||||
|
@ -37,7 +36,7 @@ class Bulleted(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
|
||||
|
|
|
@ -18,8 +18,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Checkbox(
|
||||
val binding: ItemBlockCheckboxBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockCheckboxBinding
|
||||
) : Text(binding.root), SupportNesting {
|
||||
|
||||
var mode = BlockView.Mode.EDIT
|
||||
|
@ -36,7 +35,7 @@ class Checkbox(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
|
||||
|
|
|
@ -8,8 +8,7 @@ import com.anytypeio.anytype.core_ui.databinding.ItemBlockHeaderOneBinding
|
|||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
|
||||
class HeaderOne(
|
||||
val binding: ItemBlockHeaderOneBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockHeaderOneBinding
|
||||
) : Header(binding.root) {
|
||||
|
||||
override val header: TextInputWidget = binding.headerOne
|
||||
|
@ -23,7 +22,7 @@ class HeaderOne(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_header_one)
|
||||
|
|
|
@ -8,8 +8,7 @@ import com.anytypeio.anytype.core_ui.databinding.ItemBlockHeaderThreeBinding
|
|||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
|
||||
class HeaderThree(
|
||||
val binding: ItemBlockHeaderThreeBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockHeaderThreeBinding
|
||||
) : Header(binding.root) {
|
||||
|
||||
override val header: TextInputWidget = binding.headerThree
|
||||
|
@ -23,7 +22,7 @@ class HeaderThree(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_header_three)
|
||||
|
|
|
@ -8,8 +8,7 @@ import com.anytypeio.anytype.core_ui.databinding.ItemBlockHeaderTwoBinding
|
|||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
|
||||
class HeaderTwo(
|
||||
val binding: ItemBlockHeaderTwoBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockHeaderTwoBinding
|
||||
) : Header(binding.root) {
|
||||
|
||||
override val header: TextInputWidget = binding.headerTwo
|
||||
|
@ -23,7 +22,7 @@ class HeaderTwo(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_header_two)
|
||||
|
|
|
@ -18,8 +18,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Highlight(
|
||||
val binding: ItemBlockHighlightBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockHighlightBinding
|
||||
) : Text(binding.root), BlockViewHolder.IndentableHolder {
|
||||
|
||||
override val content: TextInputWidget = binding.highlightContent
|
||||
|
@ -35,7 +34,7 @@ class Highlight(
|
|||
|
||||
init {
|
||||
content.setSpannableFactory(DefaultSpannableFactory())
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
|
||||
|
|
|
@ -22,8 +22,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Numbered(
|
||||
val binding: ItemBlockNumberedBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockNumberedBinding
|
||||
) : Text(binding.root), SupportNesting {
|
||||
|
||||
private val container = binding.numberedBlockContentContainer
|
||||
|
@ -38,7 +37,7 @@ class Numbered(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
|
||||
|
|
|
@ -15,8 +15,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Paragraph(
|
||||
view: View,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
view: View
|
||||
) : Text(view), SupportNesting {
|
||||
|
||||
override val root: View = itemView
|
||||
|
@ -29,7 +28,7 @@ class Paragraph(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
|
||||
|
|
|
@ -18,8 +18,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Toggle(
|
||||
val binding: ItemBlockToggleBinding,
|
||||
onContextMenuStyleClick: (IntRange) -> Unit
|
||||
val binding: ItemBlockToggleBinding
|
||||
) : Text(binding.root), SupportNesting {
|
||||
|
||||
private var mode = BlockView.Mode.EDIT
|
||||
|
@ -38,7 +37,7 @@ class Toggle(
|
|||
private val mentionInitialsSize: Float
|
||||
|
||||
init {
|
||||
setup(onContextMenuStyleClick)
|
||||
setup()
|
||||
with(itemView.context) {
|
||||
mentionIconSize =
|
||||
resources.getDimensionPixelSize(R.dimen.mention_span_image_size_default)
|
||||
|
|
|
@ -3462,7 +3462,6 @@ class BlockAdapterTest {
|
|||
onToggleClicked = {},
|
||||
onTextBlockTextChanged = {},
|
||||
onTitleBlockTextChanged = onTitleBlockTextChanged,
|
||||
onContextMenuStyleClick = {},
|
||||
onTitleTextInputClicked = {},
|
||||
onClickListener = {},
|
||||
clipboardInterceptor = clipboardInterceptor,
|
||||
|
|
|
@ -389,7 +389,6 @@ class HeaderBlockTest {
|
|||
onToggleClicked = {},
|
||||
onTextBlockTextChanged = {},
|
||||
onTitleBlockTextChanged = {_, _ ->},
|
||||
onContextMenuStyleClick = {},
|
||||
onTitleTextInputClicked = {},
|
||||
onClickListener = {},
|
||||
clipboardInterceptor = clipboardInterceptor,
|
||||
|
|
|
@ -118,7 +118,6 @@ class HighlightingBlockTest {
|
|||
onToggleClicked = {},
|
||||
onTextBlockTextChanged = {},
|
||||
onTitleBlockTextChanged = {_, _ -> },
|
||||
onContextMenuStyleClick = {},
|
||||
onTitleTextInputClicked = {},
|
||||
onClickListener = {},
|
||||
clipboardInterceptor = clipboardInterceptor,
|
||||
|
|
|
@ -387,7 +387,6 @@ class BlockAdapterCursorBindingTest {
|
|||
onToggleClicked = {},
|
||||
onTextBlockTextChanged = {},
|
||||
onTitleBlockTextChanged = {_, _ -> },
|
||||
onContextMenuStyleClick = {},
|
||||
onTitleTextInputClicked = {},
|
||||
onClickListener = {},
|
||||
clipboardInterceptor = clipboardInterceptor,
|
||||
|
|
|
@ -50,7 +50,6 @@ open class BlockAdapterTestSetup {
|
|||
onToggleClicked = onToggleClicked,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onTitleBlockTextChanged = {_, _ -> },
|
||||
onContextMenuStyleClick = {},
|
||||
onTitleTextInputClicked = {},
|
||||
onClickListener = {},
|
||||
clipboardInterceptor = clipboardInterceptor,
|
||||
|
|
|
@ -15,7 +15,6 @@ import com.anytypeio.anytype.presentation.editor.editor.control.ControlPanelStat
|
|||
import com.anytypeio.anytype.presentation.editor.editor.control.ControlPanelState.Toolbar
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.Alignment
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashWidgetState
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingMode
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.getStyleConfig
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.getSupportedMarkupTypes
|
||||
import com.anytypeio.anytype.presentation.extension.*
|
||||
|
@ -94,16 +93,6 @@ sealed class ControlPanelMachine {
|
|||
*/
|
||||
object OnBlockTextColorSelected : Event()
|
||||
|
||||
|
||||
@Deprecated("Legacy")
|
||||
data class OnEditorContextMenuStyleClicked(
|
||||
val selection: IntRange,
|
||||
val target: Block,
|
||||
val details: Block.Details,
|
||||
val urlBuilder: UrlBuilder
|
||||
) : Event()
|
||||
|
||||
|
||||
object OnBlockStyleSelected : Event()
|
||||
|
||||
/**
|
||||
|
@ -323,9 +312,6 @@ sealed class ControlPanelMachine {
|
|||
)
|
||||
}
|
||||
}
|
||||
state.styleTextToolbar.isVisible -> {
|
||||
handleOnSelectionChangedForStylingToolbar(event.selection, event, state)
|
||||
}
|
||||
state.mentionToolbar.isVisible -> {
|
||||
val newMentionToolbarState = handleOnSelectionChangedForMentionState(
|
||||
state = state.mentionToolbar,
|
||||
|
@ -401,34 +387,6 @@ sealed class ControlPanelMachine {
|
|||
is Event.OnBlockStyleSelected -> state.copy()
|
||||
is Event.OnAddBlockToolbarOptionSelected -> state.copy()
|
||||
is Event.OnMarkupBackgroundColorSelected -> state.copy()
|
||||
is Event.OnEditorContextMenuStyleClicked -> {
|
||||
val config = event.target.getStyleConfig(
|
||||
focus = true,
|
||||
selection = event.selection
|
||||
)
|
||||
val target = target(
|
||||
block = event.target,
|
||||
urlBuilder = event.urlBuilder,
|
||||
details = event.details
|
||||
)
|
||||
val props = getMarkupLevelStylingProps(target, event.selection)
|
||||
state.copy(
|
||||
mainToolbar = state.mainToolbar.copy(
|
||||
isVisible = false
|
||||
),
|
||||
navigationToolbar = state.navigationToolbar.copy(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = state.styleTextToolbar.copy(
|
||||
isVisible = true,
|
||||
config = config,
|
||||
mode = StylingMode.MARKUP,
|
||||
target = target,
|
||||
props = props
|
||||
),
|
||||
styleBackgroundToolbar = Toolbar.Styling.Background.reset()
|
||||
)
|
||||
}
|
||||
is Event.OnClearFocusClicked -> init()
|
||||
is Event.OnTextInputClicked -> {
|
||||
if (state.styleTextToolbar.isVisible) {
|
||||
|
@ -465,7 +423,6 @@ sealed class ControlPanelMachine {
|
|||
),
|
||||
styleTextToolbar = state.styleTextToolbar.copy(
|
||||
isVisible = true,
|
||||
mode = getModeForSelection(event.selection),
|
||||
target = target,
|
||||
style = style,
|
||||
config = event.target.getStyleConfig(event.focused, event.selection),
|
||||
|
@ -485,7 +442,6 @@ sealed class ControlPanelMachine {
|
|||
),
|
||||
styleTextToolbar = state.styleTextToolbar.copy(
|
||||
isVisible = true,
|
||||
mode = null,
|
||||
target = null,
|
||||
style = null,
|
||||
config = null,
|
||||
|
@ -664,11 +620,6 @@ sealed class ControlPanelMachine {
|
|||
)
|
||||
}
|
||||
|
||||
private fun getModeForSelection(selection: IntRange?): StylingMode {
|
||||
return if (selection != null && selection.first != selection.last) StylingMode.MARKUP
|
||||
else StylingMode.BLOCK
|
||||
}
|
||||
|
||||
private fun getPropsForSelection(target: Toolbar.Styling.Target, selection: IntRange?)
|
||||
: Toolbar.Styling.Props {
|
||||
return if (selection != null && selection.first != selection.last) {
|
||||
|
@ -742,27 +693,6 @@ sealed class ControlPanelMachine {
|
|||
)
|
||||
}
|
||||
|
||||
private fun handleOnSelectionChangedForStylingToolbar(
|
||||
selection: IntRange?,
|
||||
event: Event.OnSelectionChanged,
|
||||
state: ControlPanelState
|
||||
): ControlPanelState {
|
||||
return if (selection == null || selection.first >= selection.last) {
|
||||
state.copy(styleTextToolbar = Toolbar.Styling.reset())
|
||||
} else {
|
||||
val target = state.styleTextToolbar.target
|
||||
if (target != null && state.styleTextToolbar.mode == StylingMode.MARKUP) {
|
||||
state.copy(
|
||||
styleTextToolbar = state.styleTextToolbar.copy(
|
||||
props = getMarkupLevelStylingProps(target, event.selection)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
state.copy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleStylingToolbarEvent(
|
||||
event: Event.StylingToolbar,
|
||||
state: ControlPanelState
|
||||
|
|
|
@ -45,11 +45,6 @@ import com.anytypeio.anytype.presentation.common.StateReducer
|
|||
import com.anytypeio.anytype.presentation.common.SupportCommand
|
||||
import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Interactor
|
||||
import com.anytypeio.anytype.presentation.editor.Editor.Restore
|
||||
import com.anytypeio.anytype.presentation.editor.TurnIntoConstants.excludeCategoriesForDivider
|
||||
import com.anytypeio.anytype.presentation.editor.TurnIntoConstants.excludeTypesForDotsDivider
|
||||
import com.anytypeio.anytype.presentation.editor.TurnIntoConstants.excludeTypesForLineDivider
|
||||
import com.anytypeio.anytype.presentation.editor.TurnIntoConstants.excludeTypesForText
|
||||
import com.anytypeio.anytype.presentation.editor.TurnIntoConstants.excludedCategoriesForText
|
||||
import com.anytypeio.anytype.presentation.editor.editor.*
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Command
|
||||
import com.anytypeio.anytype.presentation.editor.editor.actions.ActionItemType
|
||||
|
@ -74,7 +69,6 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashExtensions.SL
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashExtensions.getSlashWidgetAlignmentItems
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashExtensions.getSlashWidgetStyleItems
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingEvent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingMode
|
||||
import com.anytypeio.anytype.presentation.editor.model.EditorFooter
|
||||
import com.anytypeio.anytype.presentation.editor.model.TextUpdate
|
||||
import com.anytypeio.anytype.presentation.editor.render.BlockViewRenderer
|
||||
|
@ -1422,22 +1416,6 @@ class EditorViewModel(
|
|||
actions.value = targetActions.toList()
|
||||
}
|
||||
|
||||
@Deprecated("Legacy")
|
||||
fun onEditorContextMenuStyleClicked(selection: IntRange) {
|
||||
|
||||
Timber.d("onEditorContextMenuStyleClicked, selection:[$selection]")
|
||||
|
||||
val target = blocks.first { it.id == orchestrator.stores.focus.current().id }
|
||||
controlPanelInteractor.onEvent(
|
||||
ControlPanelMachine.Event.OnEditorContextMenuStyleClicked(
|
||||
target = target,
|
||||
selection = selection,
|
||||
urlBuilder = urlBuilder,
|
||||
details = orchestrator.stores.details.current()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onStylingToolbarEvent(event: StylingEvent) {
|
||||
Timber.d("onStylingToolbarEvent, event:[$event]")
|
||||
val state = controlPanelViewState.value!!
|
||||
|
@ -1567,23 +1545,19 @@ class EditorViewModel(
|
|||
type: Markup.Type,
|
||||
param: String?
|
||||
) {
|
||||
if (state.styleTextToolbar.mode == StylingMode.MARKUP) {
|
||||
onStyleToolbarMarkupAction(type, param)
|
||||
} else {
|
||||
state.styleTextToolbar.target?.id?.let { id ->
|
||||
when (type) {
|
||||
Markup.Type.ITALIC -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.BOLD -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.STRIKETHROUGH -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.TEXT_COLOR -> onToolbarTextColorAction(listOf(id), param)
|
||||
Markup.Type.BACKGROUND_COLOR -> onBlockBackgroundColorAction(listOf(id), param)
|
||||
Markup.Type.LINK -> onBlockStyleLinkClicked(id)
|
||||
Markup.Type.KEYBOARD -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.MENTION -> Unit
|
||||
Markup.Type.OBJECT -> Unit
|
||||
}
|
||||
} ?: run { Timber.e("Target id was missing for markup styling event: $type") }
|
||||
}
|
||||
state.styleTextToolbar.target?.id?.let { id ->
|
||||
when (type) {
|
||||
Markup.Type.ITALIC -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.BOLD -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.STRIKETHROUGH -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.TEXT_COLOR -> onToolbarTextColorAction(listOf(id), param)
|
||||
Markup.Type.BACKGROUND_COLOR -> onBlockBackgroundColorAction(listOf(id), param)
|
||||
Markup.Type.LINK -> onBlockStyleLinkClicked(id)
|
||||
Markup.Type.KEYBOARD -> onBlockStyleMarkupActionClicked(id, type)
|
||||
Markup.Type.MENTION -> Unit
|
||||
Markup.Type.OBJECT -> Unit
|
||||
}
|
||||
} ?: run { Timber.e("Target id was missing for markup styling event: $type") }
|
||||
}
|
||||
|
||||
fun onStyleToolbarMarkupAction(type: Markup.Type, param: String? = null) {
|
||||
|
@ -1726,139 +1700,6 @@ class EditorViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated("To be deleted")
|
||||
fun onActionMenuItemClicked(id: String, action: ActionItemType) {
|
||||
Timber.d("onActionMenuItemClicked, id:[$id] action:[$action]")
|
||||
when (action) {
|
||||
ActionItemType.AddBelow -> {
|
||||
onExitActionMode()
|
||||
dispatch(Command.PopBackStack)
|
||||
proceedWithCreatingNewTextBlock(
|
||||
id = id,
|
||||
style = Content.Text.Style.P
|
||||
)
|
||||
}
|
||||
ActionItemType.TurnInto -> {
|
||||
val excludedTypes = mutableListOf<String>()
|
||||
val excludedCategories = mutableListOf<String>()
|
||||
val target = blocks.first { it.id == id }
|
||||
when (val content = target.content) {
|
||||
is Content.Text -> {
|
||||
val categories = excludedCategoriesForText()
|
||||
excludedCategories.addAll(categories)
|
||||
excludedTypes.addAll(excludeTypesForText())
|
||||
}
|
||||
is Content.Divider -> {
|
||||
excludedCategories.addAll(excludeCategoriesForDivider())
|
||||
when (content.style) {
|
||||
Content.Divider.Style.LINE -> excludedTypes.addAll(
|
||||
excludeTypesForLineDivider()
|
||||
)
|
||||
Content.Divider.Style.DOTS -> excludedTypes.addAll(
|
||||
excludeTypesForDotsDivider()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
onExitActionMode()
|
||||
dispatch(
|
||||
Command.OpenTurnIntoPanel(
|
||||
target = id,
|
||||
excludedCategories = excludedCategories,
|
||||
excludedTypes = excludedTypes
|
||||
)
|
||||
)
|
||||
}
|
||||
ActionItemType.Delete -> {
|
||||
proceedWithUnlinking(target = id)
|
||||
onExitActionMode()
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
ActionItemType.Duplicate -> {
|
||||
duplicateBlock(
|
||||
blocks = listOf(id),
|
||||
target = id
|
||||
)
|
||||
onExitActionMode()
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
ActionItemType.Rename -> {
|
||||
sendToast("Rename not implemented")
|
||||
}
|
||||
ActionItemType.MoveTo -> {
|
||||
onExitActionMode()
|
||||
dispatch(Command.PopBackStack)
|
||||
proceedWithMoveToButtonClicked(
|
||||
blocks = listOf(id),
|
||||
restorePosition = null,
|
||||
restoreBlock = null
|
||||
)
|
||||
}
|
||||
ActionItemType.Style -> {
|
||||
viewModelScope.launch { proceedWithOpeningStyleToolbarFromActionMenu(id) }
|
||||
}
|
||||
ActionItemType.Download -> {}
|
||||
ActionItemType.SAM -> {
|
||||
mode = EditorMode.SAM
|
||||
viewModelScope.launch { orchestrator.stores.focus.update(Editor.Focus.empty()) }
|
||||
viewModelScope.launch { refresh() }
|
||||
proceedWithSAMQuickStartSelection(id)
|
||||
controlPanelInteractor.onEvent(ControlPanelMachine.Event.SAM.OnQuickStart(1))
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
ActionItemType.Replace -> {
|
||||
sendToast("Replace not implemented")
|
||||
}
|
||||
ActionItemType.AddCaption -> {
|
||||
sendToast("Add caption not implemented")
|
||||
}
|
||||
ActionItemType.Divider -> {
|
||||
sendToast("not implemented")
|
||||
}
|
||||
ActionItemType.TurnIntoPage -> {
|
||||
proceedWithTurningIntoDocument(targets = listOf(id))
|
||||
onExitActionMode()
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
else -> Timber.d("Action ignored: $action")
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithOpeningStyleToolbarFromActionMenu(id: String) {
|
||||
val target = id
|
||||
|
||||
val lastKnownSelection = orchestrator.stores.textSelection.current().takeIf { value ->
|
||||
value.id == target
|
||||
}
|
||||
|
||||
val lastKnownCursor = lastKnownSelection?.selection
|
||||
|
||||
val isFocused = lastKnownSelection?.isNotEmpty ?: false
|
||||
|
||||
mode = EditorMode.Styling.Single(
|
||||
target = target,
|
||||
cursor = lastKnownCursor?.first
|
||||
)
|
||||
|
||||
viewModelScope.launch {
|
||||
orchestrator.stores.focus.update(Editor.Focus.empty())
|
||||
orchestrator.stores.views.update(views.singleStylingMode(target))
|
||||
renderCommand.send(Unit)
|
||||
}
|
||||
|
||||
controlPanelInteractor.onEvent(
|
||||
ControlPanelMachine.Event.OnBlockActionToolbarStyleClicked(
|
||||
target = blocks.first { it.id == target },
|
||||
focused = isFocused,
|
||||
selection = lastKnownCursor,
|
||||
urlBuilder = urlBuilder,
|
||||
details = orchestrator.stores.details.current()
|
||||
)
|
||||
)
|
||||
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
|
||||
private fun proceedWithUnlinking(target: String) {
|
||||
|
||||
val position = views.indexOfFirst { it.id == target }
|
||||
|
@ -3038,40 +2879,6 @@ class EditorViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun proceedWithSAMQuickStartSelection(target: Id) {
|
||||
(stateData.value as? ViewState.Success)?.let { state ->
|
||||
|
||||
var allow = true
|
||||
|
||||
val parent = blocks.find { it.children.contains(target) }
|
||||
|
||||
if (parent != null && parent.id != context) {
|
||||
if (isSelected(parent.id)) allow = false
|
||||
}
|
||||
|
||||
if (!allow) return
|
||||
|
||||
toggleSelection(target)
|
||||
|
||||
val descendants = blocks.asMap().descendants(parent = target)
|
||||
|
||||
if (isSelected(target)) {
|
||||
descendants.forEach { child -> select(child) }
|
||||
} else {
|
||||
descendants.forEach { child -> unselect(child) }
|
||||
}
|
||||
|
||||
val update = state.blocks.map { view ->
|
||||
if (view.id == target || descendants.contains(view.id))
|
||||
view.updateSelection(newSelection = isSelected(target))
|
||||
else
|
||||
view
|
||||
}
|
||||
|
||||
stateData.postValue(ViewState.Success(update))
|
||||
}
|
||||
}
|
||||
|
||||
fun onPaste(
|
||||
range: IntRange
|
||||
) {
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
package com.anytypeio.anytype.presentation.editor
|
||||
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.UiBlock
|
||||
|
||||
object TurnIntoConstants {
|
||||
|
||||
fun excludedCategoriesForText() : List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
fun excludeTypesForText() = listOf(
|
||||
UiBlock.FILE.name,
|
||||
UiBlock.IMAGE.name,
|
||||
UiBlock.VIDEO.name,
|
||||
UiBlock.BOOKMARK.name,
|
||||
UiBlock.LINE_DIVIDER.name,
|
||||
UiBlock.THREE_DOTS.name,
|
||||
UiBlock.LINK_TO_OBJECT.name,
|
||||
UiBlock.RELATION.name,
|
||||
)
|
||||
|
||||
fun excludeTypesForLineDivider() = listOf(
|
||||
UiBlock.CODE.name,
|
||||
UiBlock.LINE_DIVIDER.name
|
||||
)
|
||||
|
||||
fun excludeTypesForDotsDivider() = listOf(
|
||||
UiBlock.CODE.name,
|
||||
UiBlock.THREE_DOTS.name
|
||||
)
|
||||
|
||||
fun excludeCategoriesForDivider() = listOf(
|
||||
UiBlock.Category.TEXT.name,
|
||||
UiBlock.Category.LIST.name,
|
||||
UiBlock.Category.OBJECT.name,
|
||||
UiBlock.Category.RELATION.name
|
||||
)
|
||||
}
|
|
@ -32,12 +32,6 @@ sealed class Command {
|
|||
data class Measure(val target: Id) : Command()
|
||||
data class ScrollToActionMenu(val target: Id?) : Command()
|
||||
|
||||
data class OpenTurnIntoPanel(
|
||||
val target: Id,
|
||||
val excludedCategories: List<String> = emptyList(),
|
||||
val excludedTypes: List<String> = emptyList()
|
||||
) : Command()
|
||||
|
||||
data class OpenMultiSelectTurnIntoPanel(
|
||||
val excludedCategories: List<String> = emptyList(),
|
||||
val excludedTypes: List<String> = emptyList()
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.anytypeio.anytype.presentation.editor.editor.Markup
|
|||
import com.anytypeio.anytype.presentation.editor.editor.model.Alignment
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashWidgetState
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StyleConfig
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingMode
|
||||
import com.anytypeio.anytype.presentation.editor.markup.MarkupStyleDescriptor
|
||||
import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectTypeView
|
||||
|
@ -107,7 +106,6 @@ data class ControlPanelState(
|
|||
val target: Target? = null,
|
||||
val config: StyleConfig? = null,
|
||||
val props: Props? = null,
|
||||
val mode: StylingMode? = null,
|
||||
val style: TextStyle? = TextStyle.P
|
||||
) : Toolbar() {
|
||||
|
||||
|
@ -115,9 +113,7 @@ data class ControlPanelState(
|
|||
fun reset() = Styling(
|
||||
isVisible = false,
|
||||
target = null,
|
||||
config = null,
|
||||
props = null,
|
||||
mode = null
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -316,8 +312,7 @@ data class ControlPanelState(
|
|||
count = 0
|
||||
),
|
||||
styleTextToolbar = Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package com.anytypeio.anytype.presentation.editor.editor.styling
|
||||
|
||||
enum class StylingMode {
|
||||
MARKUP, BLOCK
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.presentation.editor
|
||||
|
||||
import MockDataFactory
|
||||
import android.os.Build
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
|
@ -16,7 +17,13 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@Config(sdk = [Build.VERSION_CODES.P])
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class BlockReadModeTest : EditorViewModelTest() {
|
||||
|
||||
val blocks = listOf(
|
||||
|
@ -70,6 +77,26 @@ class BlockReadModeTest : EditorViewModelTest() {
|
|||
}
|
||||
)
|
||||
|
||||
private val blockViewsReadModeSelected = listOf<BlockView>(
|
||||
blocks[0].let { p ->
|
||||
BlockView.Text.Paragraph(
|
||||
id = p.id,
|
||||
marks = emptyList(),
|
||||
text = p.content<Block.Content.Text>().text,
|
||||
mode = BlockView.Mode.READ
|
||||
)
|
||||
},
|
||||
blocks[1].let { p ->
|
||||
BlockView.Text.Paragraph(
|
||||
id = p.id,
|
||||
marks = emptyList(),
|
||||
text = p.content<Block.Content.Text>().text,
|
||||
mode = BlockView.Mode.READ,
|
||||
isSelected = true
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
private val blockViewsEditMode = listOf<BlockView>(
|
||||
blocks[0].let { p ->
|
||||
BlockView.Text.Paragraph(
|
||||
|
@ -219,7 +246,7 @@ class BlockReadModeTest : EditorViewModelTest() {
|
|||
)
|
||||
)
|
||||
|
||||
vm.onActionMenuItemClicked(id = paragraphs[1].id, action = ActionItemType.Style)
|
||||
vm.onMultiSelectStyleButtonClicked()
|
||||
|
||||
val testObserver = vm.state.test()
|
||||
|
||||
|
@ -248,40 +275,6 @@ class BlockReadModeTest : EditorViewModelTest() {
|
|||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should enter edit mode after action menu is closed by action item turn into`() {
|
||||
|
||||
val paragraphs = blocks
|
||||
stubObserveEvents(flow)
|
||||
stubOpenPage()
|
||||
buildViewModel()
|
||||
|
||||
vm.onStart(root)
|
||||
|
||||
coroutineTestRule.advanceTime(100)
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.onClickListener(
|
||||
clicked = ListenerType.LongClick(
|
||||
target = paragraphs[1].id,
|
||||
dimensions = BlockDimensions(0, 0, 0, 0, 0, 0)
|
||||
)
|
||||
)
|
||||
|
||||
vm.onActionMenuItemClicked(id = paragraphs[1].id, action = ActionItemType.TurnInto)
|
||||
|
||||
val testObserver = vm.state.test()
|
||||
|
||||
val initial = blockViewsEditMode
|
||||
|
||||
testObserver.assertValue(
|
||||
ViewState.Success(
|
||||
blocks = listOf(titleEditModeView) + initial
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should enter edit mode after action menu is closed by action item delete`() {
|
||||
|
||||
|
@ -303,21 +296,24 @@ class BlockReadModeTest : EditorViewModelTest() {
|
|||
)
|
||||
)
|
||||
|
||||
vm.onActionMenuItemClicked(id = paragraphs[1].id, action = ActionItemType.Delete)
|
||||
vm.onMultiSelectAction(ActionItemType.Delete)
|
||||
|
||||
val testObserver = vm.state.test()
|
||||
|
||||
val initial = blockViewsEditMode
|
||||
|
||||
testObserver.assertValue(
|
||||
ViewState.Success(
|
||||
coroutineTestRule.advanceTime(EditorViewModel.DELAY_REFRESH_DOCUMENT_ON_EXIT_MULTI_SELECT_MODE)
|
||||
|
||||
assertEquals(
|
||||
expected = ViewState.Success(
|
||||
blocks = listOf(titleEditModeView) + initial
|
||||
)
|
||||
),
|
||||
actual = testObserver.value()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should enter edit mode after action menu is closed by action item duplicate`() {
|
||||
fun `should be in read mode and selected after action item duplicate`() {
|
||||
|
||||
val paragraphs = blocks
|
||||
stubObserveEvents(flow)
|
||||
|
@ -337,16 +333,17 @@ class BlockReadModeTest : EditorViewModelTest() {
|
|||
)
|
||||
)
|
||||
|
||||
vm.onActionMenuItemClicked(id = paragraphs[1].id, action = ActionItemType.Duplicate)
|
||||
vm.onMultiSelectAction(ActionItemType.Duplicate)
|
||||
|
||||
val testObserver = vm.state.test()
|
||||
|
||||
val initial = blockViewsEditMode
|
||||
val initial = blockViewsReadModeSelected
|
||||
|
||||
testObserver.assertValue(
|
||||
assertEquals(
|
||||
ViewState.Success(
|
||||
blocks = listOf(titleEditModeView) + initial
|
||||
)
|
||||
blocks = listOf(titleReadModeView) + initial
|
||||
),
|
||||
testObserver.value()
|
||||
)
|
||||
}
|
||||
}
|
|
@ -8,8 +8,8 @@ import com.anytypeio.anytype.presentation.editor.editor.Markup
|
|||
import com.anytypeio.anytype.presentation.editor.editor.control.ControlPanelState
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.Alignment
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StyleConfig
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingMode
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingType
|
||||
import com.anytypeio.anytype.presentation.editor.markup.MarkupStyleDescriptor
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
|
@ -91,8 +91,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -149,8 +148,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -204,8 +202,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -261,8 +258,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = false,
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -328,8 +324,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -376,8 +371,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -423,8 +417,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false,
|
||||
|
@ -449,8 +442,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -493,8 +485,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -519,8 +510,7 @@ class ControlPanelStateReducerTest {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -551,69 +541,60 @@ class ControlPanelStateReducerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should update style toolbar state with italic true after selection changed`() {
|
||||
fun `should update style toolbar state with italic true after selection changed`() = runBlocking {
|
||||
|
||||
val block = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = "Foo Bar",
|
||||
style = Block.Content.Text.Style.P,
|
||||
marks = listOf(
|
||||
Block.Content.Text.Mark(
|
||||
range = IntRange(0, 2),
|
||||
type = Block.Content.Text.Mark.Type.BOLD
|
||||
),
|
||||
Block.Content.Text.Mark(
|
||||
range = IntRange(4, 6),
|
||||
type = Block.Content.Text.Mark.Type.ITALIC
|
||||
)
|
||||
)
|
||||
),
|
||||
fields = Block.Fields.empty()
|
||||
)
|
||||
|
||||
val selectionFirst = IntRange(0, 2)
|
||||
val selectionSecond = IntRange(4, 6)
|
||||
|
||||
val given = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation.reset(),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect.reset(),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset(),
|
||||
markupMainToolbar = ControlPanelState.Toolbar.MarkupMainToolbar(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = paragraph.id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.START,
|
||||
marks = listOf(
|
||||
Markup.Mark.Bold(0, 3),
|
||||
Markup.Mark.Italic(4, 7)
|
||||
)
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
style = MarkupStyleDescriptor.Default(
|
||||
isBold = true,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.START,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
isStrikethrough = false,
|
||||
markupTextColor = "yellow",
|
||||
markupUrl = null,
|
||||
markupHighlightColor = "red",
|
||||
range = IntRange(0, 2),
|
||||
blockBackroundColor = null,
|
||||
blockTextColor = null
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget(
|
||||
isVisible = false
|
||||
supportedTypes = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -622,7 +603,7 @@ class ControlPanelStateReducerTest {
|
|||
state = given,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
selection = selectionSecond,
|
||||
target = paragraph
|
||||
target = block
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -634,196 +615,42 @@ class ControlPanelStateReducerTest {
|
|||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget(
|
||||
isVisible = false
|
||||
),
|
||||
markupMainToolbar = ControlPanelState.Toolbar.MarkupMainToolbar(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = paragraph.id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.START,
|
||||
marks = listOf(
|
||||
Markup.Mark.Bold(0, 3),
|
||||
Markup.Mark.Italic(4, 7)
|
||||
)
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
style = MarkupStyleDescriptor.Default(
|
||||
isBold = false,
|
||||
isItalic = true,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.START,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget(
|
||||
isVisible = false
|
||||
)
|
||||
)
|
||||
assertEquals(
|
||||
expected = expected,
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should update style toolbar state without markup after selection changed`() {
|
||||
|
||||
val id = MockDataFactory.randomUuid()
|
||||
val selectionFirst = IntRange(0, 2)
|
||||
val selectionSecond = IntRange(4, 6)
|
||||
|
||||
val given = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.START,
|
||||
marks = listOf(Markup.Mark.Bold(0, 3))
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = true,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.START,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
markupTextColor = null,
|
||||
markupUrl = null,
|
||||
markupHighlightColor = null,
|
||||
range = IntRange(4, 6),
|
||||
blockBackroundColor = null,
|
||||
blockTextColor = null
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget(
|
||||
isVisible = false
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking {
|
||||
reducer.reduce(
|
||||
state = given,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
selection = selectionSecond,
|
||||
target = paragraph
|
||||
supportedTypes = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val expected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.START,
|
||||
marks = listOf(Markup.Mark.Bold(0, 3))
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = false,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.START,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget(
|
||||
isVisible = false
|
||||
)
|
||||
)
|
||||
assertEquals(
|
||||
expected = expected,
|
||||
|
@ -946,8 +773,7 @@ class ControlPanelStateReducerTest {
|
|||
alignment = Alignment.START,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
)
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -1025,7 +851,7 @@ class ControlPanelStateReducerTest {
|
|||
state = given,
|
||||
event = ControlPanelMachine.Event.OnBlockActionToolbarStyleClicked(
|
||||
target = block,
|
||||
selection = IntRange(1,1),
|
||||
selection = IntRange(1, 1),
|
||||
focused = true,
|
||||
urlBuilder = urlBuilder,
|
||||
details = Block.Details(mapOf())
|
||||
|
@ -1080,8 +906,7 @@ class ControlPanelStateReducerTest {
|
|||
alignment = Alignment.CENTER,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.BLOCK
|
||||
)
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
|
@ -1096,403 +921,108 @@ class ControlPanelStateReducerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should update style toolbar when selection is changed and not zero or empty`() {
|
||||
|
||||
val id = MockDataFactory.randomUuid()
|
||||
|
||||
val block = Block(
|
||||
id = id,
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = "Foo Bar",
|
||||
style = Block.Content.Text.Style.P,
|
||||
marks = listOf(
|
||||
Block.Content.Text.Mark(
|
||||
range = 0..3,
|
||||
type = Block.Content.Text.Mark.Type.BOLD
|
||||
)
|
||||
),
|
||||
color = "yellow",
|
||||
align = Block.Align.AlignLeft
|
||||
),
|
||||
fields = Block.Fields.empty(),
|
||||
backgroundColor = "red"
|
||||
)
|
||||
|
||||
//Focus block
|
||||
fun `should update markup toolbar when selection is changed`() =
|
||||
runBlocking {
|
||||
reducer.reduce(
|
||||
|
||||
val id = MockDataFactory.randomUuid()
|
||||
|
||||
Block(
|
||||
id = id,
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = "Foo Bar",
|
||||
style = Block.Content.Text.Style.P,
|
||||
marks = listOf(
|
||||
Block.Content.Text.Mark(
|
||||
range = 0..3,
|
||||
type = Block.Content.Text.Mark.Type.BOLD
|
||||
)
|
||||
),
|
||||
color = "yellow",
|
||||
align = Block.Align.AlignLeft
|
||||
),
|
||||
fields = Block.Fields.empty(),
|
||||
backgroundColor = "red"
|
||||
)
|
||||
|
||||
//Focus block
|
||||
val stateAfterFocus = reducer.reduce(
|
||||
state = ControlPanelState.init(),
|
||||
event = ControlPanelMachine.Event.OnFocusChanged(
|
||||
id = id,
|
||||
style = Block.Content.Text.Style.P
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
//Select Foo
|
||||
runBlocking {
|
||||
reducer.reduce(
|
||||
state = ControlPanelState.init(),
|
||||
assertEquals(
|
||||
ControlPanelState.init().copy(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation.reset(),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(true)
|
||||
), stateAfterFocus
|
||||
)
|
||||
|
||||
val stateSelectedFirst = reducer.reduce(
|
||||
state = stateAfterFocus,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
selection = IntRange(3, 3),
|
||||
target = paragraph
|
||||
)
|
||||
)
|
||||
|
||||
//Select Foo
|
||||
val stateSelectedSecond = reducer.reduce(
|
||||
state = stateSelectedFirst,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
selection = IntRange(0, 3),
|
||||
target = paragraph
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val given = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
|
||||
|
||||
runBlocking {
|
||||
reducer.reduce(
|
||||
state = given,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
selection = IntRange(0, 3),
|
||||
target = paragraph
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
runBlocking {
|
||||
reducer.reduce(
|
||||
state = given,
|
||||
event = ControlPanelMachine.Event.OnEditorContextMenuStyleClicked(
|
||||
selection = IntRange(0, 3),
|
||||
target = block,
|
||||
urlBuilder = urlBuilder,
|
||||
details = Block.Details(mapOf())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val result = runBlocking {
|
||||
reducer.reduce(
|
||||
state = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.CENTER,
|
||||
marks = listOf(
|
||||
Markup.Mark.Bold(0, 3)
|
||||
)
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(
|
||||
Alignment.START,
|
||||
Alignment.CENTER,
|
||||
Alignment.END
|
||||
),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = true,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.CENTER,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
),
|
||||
val result = reducer.reduce(
|
||||
state = stateSelectedSecond,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
selection = IntRange(0, 7),
|
||||
target = paragraph
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val expected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.CENTER,
|
||||
marks = listOf(
|
||||
Markup.Mark.Bold(0, 3)
|
||||
)
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
val expected = ControlPanelState(
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation.reset(),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect.reset(),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset(),
|
||||
markupMainToolbar = ControlPanelState.Toolbar.MarkupMainToolbar(
|
||||
isVisible = true,
|
||||
style = MarkupStyleDescriptor.Default(
|
||||
isBold = false,
|
||||
isItalic = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
isStrikethrough = false,
|
||||
markupTextColor = null,
|
||||
markupUrl = null,
|
||||
markupHighlightColor = null,
|
||||
range = IntRange(0, 7),
|
||||
blockBackroundColor = null,
|
||||
blockTextColor = null
|
||||
),
|
||||
enabledAlignment = listOf(
|
||||
Alignment.START,
|
||||
Alignment.CENTER,
|
||||
Alignment.END
|
||||
),
|
||||
enabledMarkup = listOf(
|
||||
supportedTypes = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = false,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.CENTER,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.MARKUP
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
assertEquals(
|
||||
expected = expected,
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should reset style toolbar only when selection range is 0 on block that in focus`() {
|
||||
|
||||
val id = MockDataFactory.randomUuid()
|
||||
|
||||
val block = Block(
|
||||
id = id,
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = "Foo Bar",
|
||||
style = Block.Content.Text.Style.P,
|
||||
marks = listOf(),
|
||||
color = "yellow",
|
||||
align = Block.Align.AlignLeft
|
||||
),
|
||||
fields = Block.Fields.empty(),
|
||||
backgroundColor = "red"
|
||||
)
|
||||
|
||||
//Focus block
|
||||
val afterFocusStateResult = runBlocking {
|
||||
reducer.reduce(
|
||||
state = ControlPanelState.init(),
|
||||
event = ControlPanelMachine.Event.OnFocusChanged(
|
||||
id = id,
|
||||
style = Block.Content.Text.Style.P
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val afterFocusStateExpected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = afterFocusStateExpected,
|
||||
actual = afterFocusStateResult
|
||||
)
|
||||
|
||||
//Select last position
|
||||
val afterSelectionStateResult = runBlocking {
|
||||
reducer.reduce(
|
||||
state = afterFocusStateResult,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
target = paragraph,
|
||||
selection = IntRange(6, 6)
|
||||
)
|
||||
assertEquals(
|
||||
expected = expected,
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
val afterSelectionStateExpected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = true
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = afterSelectionStateExpected,
|
||||
actual = afterSelectionStateResult
|
||||
)
|
||||
|
||||
//Click on [T] style button
|
||||
val afterShowStyleToolbarStateResult = runBlocking {
|
||||
reducer.reduce(
|
||||
state = afterSelectionStateExpected,
|
||||
event = ControlPanelMachine.Event.OnBlockActionToolbarStyleClicked(
|
||||
target = block,
|
||||
selection = IntRange(6,6),
|
||||
focused = true,
|
||||
urlBuilder = urlBuilder,
|
||||
details = Block.Details(mapOf())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val afterShowStyleToolbarStateExpected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = id,
|
||||
text = "Foo Bar",
|
||||
color = "yellow",
|
||||
background = "red",
|
||||
alignment = Alignment.START,
|
||||
marks = listOf()
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(
|
||||
Alignment.START,
|
||||
Alignment.CENTER,
|
||||
Alignment.END
|
||||
),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = false,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.START,
|
||||
color = "yellow",
|
||||
background = "red"
|
||||
),
|
||||
mode = StylingMode.BLOCK
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = afterShowStyleToolbarStateExpected,
|
||||
actual = afterShowStyleToolbarStateResult
|
||||
)
|
||||
|
||||
//New selection block
|
||||
val result = runBlocking {
|
||||
reducer.reduce(
|
||||
state = afterShowStyleToolbarStateResult,
|
||||
event = ControlPanelMachine.Event.OnSelectionChanged(
|
||||
target = paragraph,
|
||||
selection = IntRange(1, 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val expected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling.reset(),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = expected,
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `state should have visible navigation toolbar on init`() {
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.presentation.editor
|
||||
|
||||
import MockDataFactory
|
||||
import android.os.Build
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
|
@ -47,7 +48,6 @@ import com.anytypeio.anytype.presentation.editor.editor.model.UiBlock
|
|||
import com.anytypeio.anytype.presentation.editor.editor.pattern.DefaultPatternMatcher
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StyleConfig
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingEvent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingMode
|
||||
import com.anytypeio.anytype.presentation.editor.editor.styling.StylingType
|
||||
import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer
|
||||
import com.anytypeio.anytype.presentation.editor.selection.SelectionStateHolder
|
||||
|
@ -60,22 +60,25 @@ import com.anytypeio.anytype.presentation.util.TXT
|
|||
import com.jraska.livedata.test
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.*
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@Config(sdk = [Build.VERSION_CODES.P])
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@ExperimentalCoroutinesApi
|
||||
open class EditorViewModelTest {
|
||||
|
||||
|
@ -809,11 +812,7 @@ open class EditorViewModelTest {
|
|||
selection = firstTimeRange
|
||||
)
|
||||
|
||||
vm.onEditorContextMenuStyleClicked(
|
||||
selection = firstTimeRange
|
||||
)
|
||||
|
||||
vm.onStylingToolbarEvent(event = firstTimeMarkup)
|
||||
vm.onStyleToolbarMarkupAction(type = Markup.Type.BOLD)
|
||||
|
||||
val firstTimeExpected = ViewState.Success(
|
||||
listOf(
|
||||
|
@ -851,7 +850,7 @@ open class EditorViewModelTest {
|
|||
selection = secondTimeRange
|
||||
)
|
||||
|
||||
vm.onStylingToolbarEvent(event = secondTimeMarkup)
|
||||
vm.onStyleToolbarMarkupAction(type = Markup.Type.ITALIC)
|
||||
|
||||
val secondTimeExpected = ViewState.Success(
|
||||
listOf(
|
||||
|
@ -953,11 +952,7 @@ open class EditorViewModelTest {
|
|||
selection = firstTimeRange
|
||||
)
|
||||
|
||||
vm.onEditorContextMenuStyleClicked(
|
||||
selection = firstTimeRange
|
||||
)
|
||||
|
||||
vm.onStylingToolbarEvent(event = firstTimeMarkup)
|
||||
vm.onStyleToolbarMarkupAction(type = Markup.Type.BOLD)
|
||||
|
||||
val firstTimeExpected = ViewState.Success(
|
||||
listOf(
|
||||
|
@ -982,10 +977,7 @@ open class EditorViewModelTest {
|
|||
)
|
||||
)
|
||||
|
||||
vm.state.test().apply {
|
||||
assertHasValue()
|
||||
assertValue(firstTimeExpected)
|
||||
}
|
||||
assertEquals(firstTimeExpected, vm.state.value)
|
||||
|
||||
vm.onSelectionChanged(
|
||||
id = paragraph.id,
|
||||
|
@ -1005,11 +997,7 @@ open class EditorViewModelTest {
|
|||
selection = secondTimeRange
|
||||
)
|
||||
|
||||
vm.onEditorContextMenuStyleClicked(
|
||||
selection = secondTimeRange
|
||||
)
|
||||
|
||||
vm.onStylingToolbarEvent(event = secondTimeMarkup)
|
||||
vm.onStyleToolbarMarkupAction(type = Markup.Type.BOLD)
|
||||
|
||||
val secondTimeExpected = ViewState.Success(
|
||||
listOf(
|
||||
|
@ -1108,11 +1096,7 @@ open class EditorViewModelTest {
|
|||
selection = range
|
||||
)
|
||||
|
||||
vm.onEditorContextMenuStyleClicked(
|
||||
selection = range
|
||||
)
|
||||
|
||||
vm.onStylingToolbarEvent(markup)
|
||||
vm.onStyleToolbarMarkupAction(type = Markup.Type.BOLD)
|
||||
|
||||
val marks = listOf(
|
||||
Block.Content.Text.Mark(
|
||||
|
@ -1638,7 +1622,11 @@ open class EditorViewModelTest {
|
|||
|
||||
vm.onBlockFocusChanged(id = child, hasFocus = true)
|
||||
|
||||
vm.onActionMenuItemClicked(id = child, action = ActionItemType.Duplicate)
|
||||
vm.onBlockToolbarBlockActionsClicked()
|
||||
|
||||
vm.onBlockFocusChanged(id = child, hasFocus = false)
|
||||
|
||||
vm.onMultiSelectAction(ActionItemType.Duplicate)
|
||||
|
||||
runBlockingTest {
|
||||
verify(duplicateBlock, times(1)).invoke(
|
||||
|
@ -1678,7 +1666,6 @@ open class EditorViewModelTest {
|
|||
val doc = listOf(page, header, title, child)
|
||||
|
||||
val events: Flow<List<Event.Command>> = flow {
|
||||
delay(1000)
|
||||
emit(
|
||||
listOf(
|
||||
Event.Command.ShowObject(
|
||||
|
@ -1699,10 +1686,16 @@ open class EditorViewModelTest {
|
|||
|
||||
vm.onStart(root)
|
||||
|
||||
coroutineTestRule.advanceTime(1001)
|
||||
coroutineTestRule.advanceTime(100)
|
||||
|
||||
vm.onSelectionChanged(id = child.id, selection = IntRange(0, 0))
|
||||
vm.onBlockFocusChanged(id = child.id, hasFocus = true)
|
||||
vm.onActionMenuItemClicked(id = child.id, action = ActionItemType.Delete)
|
||||
vm.onBlockToolbarBlockActionsClicked()
|
||||
vm.onBlockFocusChanged(id = child.id, hasFocus = false)
|
||||
vm.onMultiSelectModeDeleteClicked()
|
||||
vm.onExitMultiSelectModeClicked()
|
||||
|
||||
coroutineTestRule.advanceTime(300)
|
||||
|
||||
runBlockingTest {
|
||||
verify(unlinkBlocks, times(1)).invoke(
|
||||
|
@ -1811,7 +1804,10 @@ open class EditorViewModelTest {
|
|||
)
|
||||
|
||||
vm.onBlockFocusChanged(id = firstChild.id, hasFocus = true)
|
||||
vm.onActionMenuItemClicked(id = firstChild.id, action = ActionItemType.Delete)
|
||||
vm.onBlockToolbarBlockActionsClicked()
|
||||
vm.onBlockFocusChanged(id = firstChild.id, hasFocus = false)
|
||||
vm.onMultiSelectModeDeleteClicked()
|
||||
vm.onExitMultiSelectModeClicked()
|
||||
|
||||
assertEquals(expected = 5, actual = vm.blocks.size)
|
||||
|
||||
|
@ -1819,23 +1815,25 @@ open class EditorViewModelTest {
|
|||
|
||||
assertEquals(expected = 4, actual = vm.blocks.size)
|
||||
|
||||
testObserver.assertValue(
|
||||
ViewState.Success(
|
||||
blocks = listOf(
|
||||
BlockView.Title.Basic(
|
||||
isFocused = true,
|
||||
id = title.id,
|
||||
text = title.content<TXT>().text,
|
||||
cursor = title.content<TXT>().text.length
|
||||
),
|
||||
BlockView.Text.Paragraph(
|
||||
id = secondChild.id,
|
||||
text = secondChild.content<Block.Content.Text>().text,
|
||||
backgroundColor = secondChild.backgroundColor
|
||||
)
|
||||
val expected = ViewState.Success(
|
||||
blocks = listOf(
|
||||
BlockView.Title.Basic(
|
||||
isFocused = false,
|
||||
id = title.id,
|
||||
text = title.content<TXT>().text,
|
||||
cursor = null
|
||||
),
|
||||
BlockView.Text.Paragraph(
|
||||
id = secondChild.id,
|
||||
text = secondChild.content<Block.Content.Text>().text,
|
||||
backgroundColor = secondChild.backgroundColor
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(expected, testObserver.value())
|
||||
|
||||
coroutineTestRule.advanceTime(300L)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2121,7 +2119,7 @@ open class EditorViewModelTest {
|
|||
|
||||
val color = MockDataFactory.randomString()
|
||||
|
||||
vm.onToolbarTextColorAction(color = color, targets= listOf(child))
|
||||
vm.onToolbarTextColorAction(color = color, targets = listOf(child))
|
||||
|
||||
runBlockingTest {
|
||||
verify(updateTextColor, times(1)).invoke(
|
||||
|
@ -3081,7 +3079,7 @@ open class EditorViewModelTest {
|
|||
params = eq(
|
||||
SetObjectIsArchived.Params(
|
||||
context = root,
|
||||
isArchived = true
|
||||
isArchived = true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -3451,7 +3449,9 @@ open class EditorViewModelTest {
|
|||
|
||||
focus.assertValue { id -> id == paragraph.id }
|
||||
|
||||
vm.onActionMenuItemClicked(id = paragraph.id, action = ActionItemType.Duplicate)
|
||||
vm.onBlockToolbarBlockActionsClicked()
|
||||
vm.onBlockFocusChanged(id = paragraph.id, hasFocus = false)
|
||||
vm.onMultiSelectAction(ActionItemType.Duplicate)
|
||||
|
||||
runBlockingTest {
|
||||
verify(duplicateBlock, times(1)).invoke(
|
||||
|
@ -3468,6 +3468,8 @@ open class EditorViewModelTest {
|
|||
verifyNoMoreInteractions(duplicateBlock)
|
||||
|
||||
focus.assertValue { id -> id == newBlockId }
|
||||
|
||||
coroutineTestRule.advanceTime(200)
|
||||
}
|
||||
|
||||
private fun stubDuplicateBlock(newBlockId: String, root: String) {
|
||||
|
@ -3863,9 +3865,9 @@ open class EditorViewModelTest {
|
|||
onBlocking { invoke(any()) } doReturn Either.Right(
|
||||
Pair(
|
||||
MockDataFactory.randomString(), Payload(
|
||||
context = root,
|
||||
events = listOf()
|
||||
)
|
||||
context = root,
|
||||
events = listOf()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -3918,7 +3920,12 @@ open class EditorViewModelTest {
|
|||
|
||||
private fun stubGetDefaultObjectType(type: String? = null, name: String? = null) {
|
||||
getDefaultEditorType.stub {
|
||||
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type, null))
|
||||
onBlocking { invoke(Unit) } doReturn Either.Right(
|
||||
GetDefaultEditorType.Response(
|
||||
type,
|
||||
null
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4380,7 +4387,7 @@ open class EditorViewModelTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should update style toolbar when no blocks in focus`() {
|
||||
fun `should not update text style in multi select mode`() {
|
||||
|
||||
val id1 = MockDataFactory.randomUuid()
|
||||
val id2 = MockDataFactory.randomUuid()
|
||||
|
@ -4452,127 +4459,35 @@ open class EditorViewModelTest {
|
|||
assertTrue(stateBefore.navigationToolbar.isVisible)
|
||||
assertFalse(stateBefore.styleTextToolbar.isVisible)
|
||||
|
||||
vm.onActionMenuItemClicked(blocks[0].id, ActionItemType.Style)
|
||||
vm.onClickListener(ListenerType.LongClick(target = blocks[0].id))
|
||||
vm.onMultiSelectStyleButtonClicked()
|
||||
|
||||
vm.controlPanelViewState.test().assertValue(
|
||||
ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
mode = StylingMode.BLOCK,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = blocks[0].id,
|
||||
text = blocks[0].content.asText().text,
|
||||
color = null,
|
||||
background = null,
|
||||
alignment = Alignment.CENTER,
|
||||
marks = listOf(
|
||||
Markup.Mark.Bold(0, 7)
|
||||
)
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(
|
||||
Alignment.START,
|
||||
Alignment.CENTER,
|
||||
Alignment.END
|
||||
),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = true,
|
||||
isItalic = false,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.CENTER,
|
||||
color = null,
|
||||
background = null
|
||||
)
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
val actual = vm.controlPanelViewState.test().value()
|
||||
val expected = ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
style = null
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
count = 1
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
|
||||
vm.onStylingToolbarEvent(event = StylingEvent.Markup.Italic)
|
||||
|
||||
vm.controlPanelViewState.test().assertValue(
|
||||
ControlPanelState(
|
||||
navigationToolbar = ControlPanelState.Toolbar.Navigation(
|
||||
isVisible = false
|
||||
),
|
||||
mainToolbar = ControlPanelState.Toolbar.Main(
|
||||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
mode = StylingMode.BLOCK,
|
||||
target = ControlPanelState.Toolbar.Styling.Target(
|
||||
id = blocks[0].id,
|
||||
text = blocks[0].content.asText().text,
|
||||
color = null,
|
||||
background = null,
|
||||
alignment = Alignment.CENTER,
|
||||
marks = listOf(
|
||||
Markup.Mark.Bold(0, 7),
|
||||
Markup.Mark.Italic(0, 7)
|
||||
)
|
||||
),
|
||||
config = StyleConfig(
|
||||
visibleTypes = listOf(
|
||||
StylingType.STYLE,
|
||||
StylingType.TEXT_COLOR,
|
||||
StylingType.BACKGROUND
|
||||
),
|
||||
enabledAlignment = listOf(
|
||||
Alignment.START,
|
||||
Alignment.CENTER,
|
||||
Alignment.END
|
||||
),
|
||||
enabledMarkup = listOf(
|
||||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
),
|
||||
props = ControlPanelState.Toolbar.Styling.Props(
|
||||
isBold = true,
|
||||
isItalic = true,
|
||||
isStrikethrough = false,
|
||||
isCode = false,
|
||||
isLinked = false,
|
||||
alignment = Alignment.CENTER,
|
||||
color = null,
|
||||
background = null
|
||||
)
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false
|
||||
),
|
||||
mentionToolbar = ControlPanelState.Toolbar.MentionToolbar.reset(),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
)
|
||||
)
|
||||
verifyNoMoreInteractions(updateText)
|
||||
|
||||
coroutineTestRule.advanceTime(200)
|
||||
}
|
||||
}
|
|
@ -154,8 +154,7 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -255,8 +254,7 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -372,8 +370,7 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -1334,7 +1331,6 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
val expectedState = ControlPanelState(
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = true,
|
||||
mode = null,
|
||||
style = null
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.junit.Before
|
|||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.MockitoAnnotations
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class EditorQuickStartingScrollAndMoveTest : EditorPresentationTestSetup() {
|
||||
|
||||
|
@ -51,7 +52,7 @@ class EditorQuickStartingScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
)
|
||||
|
||||
@Test
|
||||
fun `should exit to editing-mode when exiting from quick SAM`() {
|
||||
fun `should be in selected mode when exiting from quick SAM`() {
|
||||
|
||||
// SETUP
|
||||
|
||||
|
@ -101,57 +102,58 @@ class EditorQuickStartingScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
vm.apply {
|
||||
onBlockFocusChanged(id = b.id, hasFocus = true)
|
||||
onBlockToolbarBlockActionsClicked()
|
||||
onActionMenuItemClicked(id = b.id, action = ActionItemType.SAM)
|
||||
onBlockFocusChanged(id = b.id, hasFocus = false)
|
||||
onEnterScrollAndMoveClicked()
|
||||
onExitScrollAndMoveClicked()
|
||||
}
|
||||
|
||||
// VERIFYING
|
||||
|
||||
controlPanelTestObserver.assertValue(
|
||||
val actual = controlPanelTestObserver.value()
|
||||
|
||||
val expected =
|
||||
ControlPanelState(
|
||||
navigationToolbar = Toolbar.Navigation(isVisible = true),
|
||||
mainToolbar = Toolbar.Main(isVisible = false),
|
||||
mentionToolbar = Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
navigationToolbar = Toolbar.Navigation.reset(),
|
||||
mainToolbar = Toolbar.Main.reset(),
|
||||
mentionToolbar = Toolbar.MentionToolbar.reset(),
|
||||
multiSelect = Toolbar.MultiSelect(
|
||||
isVisible = false,
|
||||
count = 0,
|
||||
isVisible = true,
|
||||
count = 1,
|
||||
isScrollAndMoveEnabled = false,
|
||||
isQuickScrollAndMoveMode = false,
|
||||
),
|
||||
styleTextToolbar = Toolbar.Styling(isVisible = false),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
styleTextToolbar = Toolbar.Styling.reset(),
|
||||
slashWidget = Toolbar.SlashWidget.reset()
|
||||
)
|
||||
)
|
||||
|
||||
viewStateTestObserver.assertValue(
|
||||
ViewState.Success(
|
||||
listOf(
|
||||
BlockView.Title.Basic(
|
||||
id = title.id,
|
||||
text = title.content<TXT>().text,
|
||||
mode = BlockView.Mode.EDIT,
|
||||
),
|
||||
BlockView.Text.Numbered(
|
||||
id = a.id,
|
||||
text = a.content<TXT>().text,
|
||||
number = 1,
|
||||
mode = BlockView.Mode.EDIT,
|
||||
isSelected = false
|
||||
),
|
||||
BlockView.Text.Paragraph(
|
||||
id = b.id,
|
||||
text = b.content<TXT>().text,
|
||||
mode = BlockView.Mode.EDIT,
|
||||
isSelected = false
|
||||
)
|
||||
assertEquals(expected, actual)
|
||||
|
||||
val actualViewState = viewStateTestObserver.value()
|
||||
|
||||
val expectedViewState = ViewState.Success(
|
||||
listOf(
|
||||
BlockView.Title.Basic(
|
||||
id = title.id,
|
||||
text = title.content<TXT>().text,
|
||||
mode = BlockView.Mode.READ,
|
||||
),
|
||||
BlockView.Text.Numbered(
|
||||
id = a.id,
|
||||
text = a.content<TXT>().text,
|
||||
number = 1,
|
||||
mode = BlockView.Mode.READ,
|
||||
isSelected = false
|
||||
),
|
||||
BlockView.Text.Paragraph(
|
||||
id = b.id,
|
||||
text = b.content<TXT>().text,
|
||||
mode = BlockView.Mode.READ,
|
||||
isSelected = true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertEquals(expectedViewState, actualViewState)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -205,7 +207,8 @@ class EditorQuickStartingScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
vm.apply {
|
||||
onBlockFocusChanged(id = b.id, hasFocus = true)
|
||||
onBlockToolbarBlockActionsClicked()
|
||||
onActionMenuItemClicked(id = b.id, action = ActionItemType.SAM)
|
||||
onBlockFocusChanged(id = b.id, hasFocus = false)
|
||||
onEnterScrollAndMoveClicked()
|
||||
onSystemBackPressed(false)
|
||||
}
|
||||
|
||||
|
@ -214,21 +217,11 @@ class EditorQuickStartingScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
controlPanelTestObserver.assertValue(
|
||||
ControlPanelState(
|
||||
navigationToolbar = Toolbar.Navigation(isVisible = true),
|
||||
mainToolbar = Toolbar.Main(isVisible = false),
|
||||
mentionToolbar = Toolbar.MentionToolbar(
|
||||
isVisible = false,
|
||||
cursorCoordinate = null,
|
||||
mentionFilter = null,
|
||||
mentionFrom = null
|
||||
),
|
||||
multiSelect = Toolbar.MultiSelect(
|
||||
isVisible = false,
|
||||
count = 0,
|
||||
isScrollAndMoveEnabled = false,
|
||||
isQuickScrollAndMoveMode = false,
|
||||
),
|
||||
styleTextToolbar = Toolbar.Styling(isVisible = false),
|
||||
slashWidget = ControlPanelState.Toolbar.SlashWidget.reset()
|
||||
mainToolbar = Toolbar.Main.reset(),
|
||||
mentionToolbar = Toolbar.MentionToolbar.reset(),
|
||||
multiSelect = Toolbar.MultiSelect.reset(),
|
||||
styleTextToolbar = Toolbar.Styling.reset(),
|
||||
slashWidget = Toolbar.SlashWidget.reset()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -131,8 +131,7 @@ class EditorScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -226,8 +225,7 @@ class EditorScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = true,
|
||||
|
@ -301,8 +299,7 @@ class EditorScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false,
|
||||
|
@ -420,8 +417,7 @@ class EditorScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
isVisible = false
|
||||
),
|
||||
styleTextToolbar = ControlPanelState.Toolbar.Styling(
|
||||
isVisible = false,
|
||||
mode = null
|
||||
isVisible = false
|
||||
),
|
||||
multiSelect = ControlPanelState.Toolbar.MultiSelect(
|
||||
isVisible = false,
|
||||
|
|
|
@ -173,106 +173,6 @@ class EditorTurnIntoTest : EditorPresentationTestSetup() {
|
|||
verifyBlocking(turnIntoDocument, times(1)) { invoke(params) }
|
||||
}
|
||||
|
||||
//@Test
|
||||
fun `should open turn-into panel with restrictions for text block in edit mode`() {
|
||||
|
||||
// SETUP
|
||||
|
||||
val a = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = MockDataFactory.randomUuid(),
|
||||
marks = emptyList(),
|
||||
style = Block.Content.Text.Style.values().random()
|
||||
)
|
||||
)
|
||||
|
||||
val b = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = MockDataFactory.randomString(),
|
||||
marks = emptyList(),
|
||||
style = Block.Content.Text.Style.values().random()
|
||||
)
|
||||
)
|
||||
|
||||
val page = Block(
|
||||
id = root,
|
||||
fields = Block.Fields(emptyMap()),
|
||||
content = Block.Content.Smart(),
|
||||
children = listOf(a.id, b.id)
|
||||
)
|
||||
|
||||
val document = listOf(page, a, b)
|
||||
|
||||
stubOpenDocument(document = document)
|
||||
stubInterceptThreadStatus()
|
||||
stubInterceptEvents(InterceptEvents.Params(context = root))
|
||||
|
||||
val vm = buildViewModel()
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.apply {
|
||||
onStart(root)
|
||||
onBlockFocusChanged(id = a.id, hasFocus = true)
|
||||
onClickListener(
|
||||
ListenerType.LongClick(
|
||||
target = b.id,
|
||||
dimensions = BlockDimensions(
|
||||
MockDataFactory.randomInt(),
|
||||
MockDataFactory.randomInt(),
|
||||
MockDataFactory.randomInt(),
|
||||
MockDataFactory.randomInt(),
|
||||
MockDataFactory.randomInt(),
|
||||
MockDataFactory.randomInt()
|
||||
)
|
||||
)
|
||||
)
|
||||
onActionMenuItemClicked(
|
||||
id = b.id,
|
||||
action = ActionItemType.TurnInto
|
||||
)
|
||||
}
|
||||
|
||||
val result = vm.commands.value?.peekContent()
|
||||
|
||||
val expectedExcludedTypes = listOf(
|
||||
UiBlock.LINE_DIVIDER.name,
|
||||
UiBlock.THREE_DOTS.name,
|
||||
UiBlock.BOOKMARK.name,
|
||||
UiBlock.LINK_TO_OBJECT.name,
|
||||
UiBlock.FILE.name,
|
||||
UiBlock.VIDEO.name,
|
||||
UiBlock.IMAGE.name,
|
||||
UiBlock.RELATION.name
|
||||
)
|
||||
|
||||
check(result is Command.OpenTurnIntoPanel) { "Wrong command" }
|
||||
|
||||
assertEquals(
|
||||
expected = emptyList(),
|
||||
actual = result.excludedCategories
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = b.id,
|
||||
actual = result.target
|
||||
)
|
||||
|
||||
assertTrue {
|
||||
result.excludedTypes.size == expectedExcludedTypes.size
|
||||
}
|
||||
|
||||
assertTrue {
|
||||
result.excludedTypes.containsAll(expectedExcludedTypes)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should invoke turnIntoDocument on for one text block and one file block in multi-select mode`() {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue