1
0
Fork 0
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:
Konstantin Ivanov 2022-04-13 22:31:27 +03:00 committed by GitHub
parent 9f19016948
commit 503935ce07
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 385 additions and 1426 deletions

View file

@ -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(

View file

@ -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 -> {

View file

@ -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() {

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -3462,7 +3462,6 @@ class BlockAdapterTest {
onToggleClicked = {},
onTextBlockTextChanged = {},
onTitleBlockTextChanged = onTitleBlockTextChanged,
onContextMenuStyleClick = {},
onTitleTextInputClicked = {},
onClickListener = {},
clipboardInterceptor = clipboardInterceptor,

View file

@ -389,7 +389,6 @@ class HeaderBlockTest {
onToggleClicked = {},
onTextBlockTextChanged = {},
onTitleBlockTextChanged = {_, _ ->},
onContextMenuStyleClick = {},
onTitleTextInputClicked = {},
onClickListener = {},
clipboardInterceptor = clipboardInterceptor,

View file

@ -118,7 +118,6 @@ class HighlightingBlockTest {
onToggleClicked = {},
onTextBlockTextChanged = {},
onTitleBlockTextChanged = {_, _ -> },
onContextMenuStyleClick = {},
onTitleTextInputClicked = {},
onClickListener = {},
clipboardInterceptor = clipboardInterceptor,

View file

@ -387,7 +387,6 @@ class BlockAdapterCursorBindingTest {
onToggleClicked = {},
onTextBlockTextChanged = {},
onTitleBlockTextChanged = {_, _ -> },
onContextMenuStyleClick = {},
onTitleTextInputClicked = {},
onClickListener = {},
clipboardInterceptor = clipboardInterceptor,

View file

@ -50,7 +50,6 @@ open class BlockAdapterTestSetup {
onToggleClicked = onToggleClicked,
onTextBlockTextChanged = onTextBlockTextChanged,
onTitleBlockTextChanged = {_, _ -> },
onContextMenuStyleClick = {},
onTitleTextInputClicked = {},
onClickListener = {},
clipboardInterceptor = clipboardInterceptor,

View file

@ -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

View file

@ -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
) {

View file

@ -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
)
}

View file

@ -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()

View file

@ -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,

View file

@ -1,5 +0,0 @@
package com.anytypeio.anytype.presentation.editor.editor.styling
enum class StylingMode {
MARKUP, BLOCK
}

View file

@ -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()
)
}
}

View file

@ -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`() {

View file

@ -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)
}
}

View file

@ -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(

View file

@ -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()
)
)

View file

@ -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,

View file

@ -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`() {