mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-50 Editor | Tech | Create text watchers in oncreate (#2620)
This commit is contained in:
parent
12707c651d
commit
7cf46865b2
28 changed files with 863 additions and 1270 deletions
|
@ -139,7 +139,7 @@ class DragAndDropDelegate {
|
|||
)
|
||||
|
||||
val shadow = when (vh) {
|
||||
is Text -> TextInputDragShadow(vh.content.id, vh.itemView, event)
|
||||
is Text<*> -> TextInputDragShadow(vh.content.id, vh.itemView, event)
|
||||
is Code -> TextInputDragShadow(vh.content.id, vh.itemView, event)
|
||||
else -> DefaultEditorDragShadow(vh.itemView, event)
|
||||
}
|
||||
|
|
|
@ -106,10 +106,10 @@ import com.anytypeio.anytype.core_ui.features.editor.holders.text.Numbered
|
|||
import com.anytypeio.anytype.core_ui.features.editor.holders.text.Paragraph
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.text.Text
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.text.Toggle
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.upload.BookmarkUpload
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.upload.FileUpload
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.upload.PictureUpload
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.upload.VideoUpload
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.upload.BookmarkUpload
|
||||
import com.anytypeio.anytype.core_ui.features.table.holders.TableBlockHolder
|
||||
import com.anytypeio.anytype.core_ui.tools.ClipboardInterceptor
|
||||
import com.anytypeio.anytype.core_ui.tools.DefaultTextWatcher
|
||||
|
@ -173,7 +173,6 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER
|
|||
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_VIDEO_PLACEHOLDER
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_VIDEO_UPLOAD
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
import com.anytypeio.anytype.presentation.relations.DocumentRelationView
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
|
@ -215,7 +214,9 @@ class BlockAdapter(
|
|||
private val onDragListener: View.OnDragListener,
|
||||
private val lifecycle: Lifecycle,
|
||||
private val dragAndDropSelector: DragAndDropSelector,
|
||||
) : RecyclerView.Adapter<BlockViewHolder>(), DragAndDropSelector by dragAndDropSelector {
|
||||
) : RecyclerView.Adapter<BlockViewHolder>(),
|
||||
ItemProviderAdapter<BlockView>,
|
||||
DragAndDropSelector by dragAndDropSelector {
|
||||
|
||||
private var blocks: List<BlockView> = initialBlock
|
||||
val views: List<BlockView> get() = blocks
|
||||
|
@ -417,8 +418,11 @@ class BlockAdapter(
|
|||
Checkbox(
|
||||
binding = ItemBlockCheckboxBinding.inflate(
|
||||
inflater, parent, false
|
||||
), clicked = onClickListener
|
||||
)
|
||||
),
|
||||
clicked = onClickListener
|
||||
).apply {
|
||||
setCheckboxClickListener(onCheckboxClicked)
|
||||
}
|
||||
}
|
||||
HOLDER_BULLET -> {
|
||||
Bulleted(
|
||||
|
@ -438,8 +442,11 @@ class BlockAdapter(
|
|||
Toggle(
|
||||
binding = ItemBlockToggleBinding.inflate(
|
||||
inflater, parent, false
|
||||
), clicked = onClickListener
|
||||
)
|
||||
),
|
||||
clicked = onClickListener
|
||||
).apply {
|
||||
setupToggle(onToggleClicked, onTogglePlaceholderClicked)
|
||||
}
|
||||
}
|
||||
HOLDER_DESCRIPTION -> {
|
||||
Description(
|
||||
|
@ -590,7 +597,7 @@ class BlockAdapter(
|
|||
}
|
||||
HOLDER_BOOKMARK_UPLOAD -> {
|
||||
BookmarkUpload(
|
||||
ItemBlockBookmarkUploadingBinding.inflate(inflater, parent, false)
|
||||
ItemBlockBookmarkUploadingBinding.inflate(inflater, parent, false)
|
||||
)
|
||||
}
|
||||
HOLDER_PICTURE -> {
|
||||
|
@ -710,7 +717,7 @@ class BlockAdapter(
|
|||
else -> throw IllegalStateException("Unexpected view type: $viewType")
|
||||
}
|
||||
|
||||
if (holder is Text) {
|
||||
if (holder is Text<*>) {
|
||||
holder.content.setOnDragListener(onDragListener)
|
||||
holder.content.editorTouchProcessor.onLongClick = {
|
||||
val pos = holder.bindingAdapterPosition
|
||||
|
@ -747,6 +754,23 @@ class BlockAdapter(
|
|||
onSelectionChanged(view.id, selection)
|
||||
}
|
||||
}
|
||||
holder.setupViewHolder(
|
||||
onTextChanged = { editable ->
|
||||
holder.withBlock<BlockView.Text> { item ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
}
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onBackPressedCallback = onBackPressedCallback,
|
||||
)
|
||||
} else {
|
||||
if (holder !is SupportCustomTouchProcessor) {
|
||||
when (holder) {
|
||||
|
@ -823,33 +847,21 @@ class BlockAdapter(
|
|||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is Bulleted -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is Checkbox -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is Title.Document -> {
|
||||
|
@ -874,77 +886,49 @@ class BlockAdapter(
|
|||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
)
|
||||
}
|
||||
is HeaderOne -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is HeaderTwo -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
)
|
||||
}
|
||||
is HeaderThree -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
)
|
||||
}
|
||||
is Toggle -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is Highlight -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is Callout -> {
|
||||
holder.processChangePayload(
|
||||
payloads = payloads.typeOf(),
|
||||
item = blocks[position],
|
||||
onTextChanged = onTextBlockTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
clicked = onClickListener
|
||||
)
|
||||
}
|
||||
is File -> {
|
||||
|
@ -1140,130 +1124,16 @@ class BlockAdapter(
|
|||
override fun onBindViewHolder(holder: BlockViewHolder, position: Int) {
|
||||
if (isInDragAndDropMode) trySetDesiredAppearanceForDraggedItem(holder, position)
|
||||
when (holder) {
|
||||
is Paragraph -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Paragraph,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is HeaderOne -> {
|
||||
holder.bind(
|
||||
block = blocks[position] as BlockView.Text.Header.One,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is HeaderTwo -> {
|
||||
holder.bind(
|
||||
block = blocks[position] as BlockView.Text.Header.Two,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is HeaderThree -> {
|
||||
holder.bind(
|
||||
block = blocks[position] as BlockView.Text.Header.Three,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Checkbox -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Checkbox,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onCheckboxClicked = onCheckboxClicked,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Bulleted -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Bulleted,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Numbered -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Numbered,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Toggle -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Toggle,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onTogglePlaceholderClicked = onTogglePlaceholderClicked,
|
||||
onToggleClicked = onToggleClicked,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Highlight -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Highlight,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
clicked = onClickListener,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Callout -> {
|
||||
holder.bind(
|
||||
item = blocks[position] as BlockView.Text.Callout,
|
||||
onTextBlockTextChanged = onTextBlockTextChanged,
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
is Paragraph -> holder.bind(blocks[position] as BlockView.Text.Paragraph)
|
||||
is HeaderOne -> holder.bind(blocks[position] as BlockView.Text.Header.One)
|
||||
is HeaderTwo -> holder.bind(blocks[position] as BlockView.Text.Header.Two)
|
||||
is HeaderThree -> holder.bind(blocks[position] as BlockView.Text.Header.Three)
|
||||
is Checkbox -> holder.bind(blocks[position] as BlockView.Text.Checkbox )
|
||||
is Bulleted -> holder.bind(blocks[position] as BlockView.Text.Bulleted)
|
||||
is Numbered -> holder.bind(blocks[position] as BlockView.Text.Numbered)
|
||||
is Toggle -> holder.bind(item = blocks[position] as BlockView.Text.Toggle)
|
||||
is Highlight -> holder.bind(blocks[position] as BlockView.Text.Highlight)
|
||||
is Callout -> holder.bind(blocks[position] as BlockView.Text.Callout)
|
||||
is Title.Document -> {
|
||||
holder.apply {
|
||||
bind(
|
||||
|
@ -1542,7 +1412,7 @@ class BlockAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
if (holder is Text) {
|
||||
if (holder is Text<*>) {
|
||||
|
||||
val block = blocks[position]
|
||||
|
||||
|
@ -1592,4 +1462,8 @@ class BlockAdapter(
|
|||
holder.onDecorationsChanged(decorations = block.decorations)
|
||||
}
|
||||
}
|
||||
|
||||
override fun provide(pos: Int): BlockView {
|
||||
return blocks[pos]
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.core_utils.ext.PopupExtensions
|
|||
import com.anytypeio.anytype.presentation.editor.editor.BlockDimensions
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Viewholder for rendering different type of blocks (i.e its UI-models).
|
||||
|
@ -50,3 +51,33 @@ open class BlockViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
|||
clicked(ListenerType.LongClick(target, dimensions))
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified R : BlockView> BlockViewHolder.withBlock(block: (R) -> Unit) {
|
||||
val pos = bindingAdapterPosition
|
||||
val adapter = bindingAdapter
|
||||
if (pos != RecyclerView.NO_POSITION && adapter is ItemProviderAdapter<*>) {
|
||||
val view = adapter.provide(pos)
|
||||
if (view is R) {
|
||||
block(view)
|
||||
} else {
|
||||
if (view != null) {
|
||||
Timber.w("Unexpected type: ${view::class.simpleName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified R : BlockView> BlockViewHolder.provide() : R? {
|
||||
val pos = bindingAdapterPosition
|
||||
val adapter = bindingAdapter
|
||||
return if (pos != RecyclerView.NO_POSITION && adapter is ItemProviderAdapter<*>) {
|
||||
val view = adapter.provide(pos)
|
||||
if (view is R) {
|
||||
view
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor
|
||||
|
||||
interface ItemProviderAdapter<T> {
|
||||
fun provide(pos: Int): T
|
||||
}
|
|
@ -2,7 +2,6 @@ package com.anytypeio.anytype.core_ui.features.editor
|
|||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.text.Editable
|
||||
import android.text.Spannable
|
||||
import android.view.ActionMode
|
||||
import android.view.Menu
|
||||
|
@ -26,7 +25,6 @@ import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableViewH
|
|||
import com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.`interface`.TextHolder
|
||||
import com.anytypeio.anytype.core_ui.tools.DefaultSpannableFactory
|
||||
import com.anytypeio.anytype.core_ui.tools.DefaultTextWatcher
|
||||
import com.anytypeio.anytype.core_ui.tools.MentionTextWatcher
|
||||
import com.anytypeio.anytype.core_ui.tools.SlashTextWatcher
|
||||
import com.anytypeio.anytype.core_ui.tools.SlashTextWatcherState
|
||||
|
@ -219,41 +217,29 @@ interface TextBlockHolder : TextHolder {
|
|||
}
|
||||
}
|
||||
|
||||
fun setupTextWatcher(
|
||||
item: BlockView,
|
||||
onMentionEvent: ((MentionEvent) -> Unit),
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onTextChanged: (String, Editable) -> Unit,
|
||||
) {
|
||||
content.addTextChangedListener(
|
||||
DefaultTextWatcher { text ->
|
||||
onTextChanged(item.id, text)
|
||||
}
|
||||
)
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
fun setupMentionWatcher(
|
||||
onMentionEvent: ((MentionEvent) -> Unit)
|
||||
onMentionEvent: ((MentionEvent) -> Unit),
|
||||
itemProvider: () -> BlockView.Text?
|
||||
) {
|
||||
content.addTextChangedListener(
|
||||
MentionTextWatcher { state ->
|
||||
when (state) {
|
||||
is MentionTextWatcher.MentionTextWatcherState.Start -> {
|
||||
onMentionEvent.invoke(
|
||||
MentionEvent.MentionSuggestStart(
|
||||
cursorCoordinate = content.cursorYBottomCoordinate(),
|
||||
mentionStart = state.start
|
||||
itemProvider().performInEditMode { item ->
|
||||
when (state) {
|
||||
is MentionTextWatcher.MentionTextWatcherState.Start -> {
|
||||
onMentionEvent.invoke(
|
||||
MentionEvent.MentionSuggestStart(
|
||||
cursorCoordinate = content.cursorYBottomCoordinate(),
|
||||
mentionStart = state.start
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
MentionTextWatcher.MentionTextWatcherState.Stop -> {
|
||||
onMentionEvent.invoke(MentionEvent.MentionSuggestStop)
|
||||
}
|
||||
}
|
||||
MentionTextWatcher.MentionTextWatcherState.Stop -> {
|
||||
onMentionEvent.invoke(MentionEvent.MentionSuggestStop)
|
||||
}
|
||||
|
||||
is MentionTextWatcher.MentionTextWatcherState.Text -> {
|
||||
onMentionEvent.invoke(MentionEvent.MentionSuggestText(state.text))
|
||||
is MentionTextWatcher.MentionTextWatcherState.Text -> {
|
||||
onMentionEvent.invoke(MentionEvent.MentionSuggestText(state.text))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,24 +248,26 @@ interface TextBlockHolder : TextHolder {
|
|||
|
||||
fun setupSlashWatcher(
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
viewType: Int
|
||||
itemProvider: () -> BlockView.Text?
|
||||
) {
|
||||
content.addTextChangedListener(
|
||||
SlashTextWatcher { state ->
|
||||
when (state) {
|
||||
is SlashTextWatcherState.Start -> onSlashEvent(
|
||||
SlashEvent.Start(
|
||||
slashStart = state.start,
|
||||
cursorCoordinate = content.cursorYBottomCoordinate()
|
||||
itemProvider().performInEditMode { item ->
|
||||
when (state) {
|
||||
is SlashTextWatcherState.Start -> onSlashEvent(
|
||||
SlashEvent.Start(
|
||||
slashStart = state.start,
|
||||
cursorCoordinate = content.cursorYBottomCoordinate()
|
||||
)
|
||||
)
|
||||
)
|
||||
SlashTextWatcherState.Stop -> onSlashEvent(SlashEvent.Stop)
|
||||
is SlashTextWatcherState.Filter -> onSlashEvent(
|
||||
SlashEvent.Filter(
|
||||
filter = state.text,
|
||||
viewType = viewType
|
||||
SlashTextWatcherState.Stop -> onSlashEvent(SlashEvent.Stop)
|
||||
is SlashTextWatcherState.Filter -> onSlashEvent(
|
||||
SlashEvent.Filter(
|
||||
filter = state.text,
|
||||
viewType = item.getViewType()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -289,11 +277,7 @@ interface TextBlockHolder : TextHolder {
|
|||
fun processChangePayload(
|
||||
payloads: List<BlockViewDiffUtil.Payload>,
|
||||
item: BlockView,
|
||||
onTextChanged: (BlockView.Text) -> Unit,
|
||||
onSelectionChanged: (String, IntRange) -> Unit,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit
|
||||
) = payloads.forEach { payload ->
|
||||
|
||||
check(item is BlockView.Text)
|
||||
|
@ -347,19 +331,6 @@ interface TextBlockHolder : TextHolder {
|
|||
if (payload.readWriteModeChanged()) {
|
||||
content.pauseTextWatchers {
|
||||
if (item.mode == BlockView.Mode.EDIT) {
|
||||
content.clearTextWatchers()
|
||||
setupTextWatcher(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextChanged(item)
|
||||
},
|
||||
onMentionEvent = onMentionEvent,
|
||||
onSlashEvent = onSlashEvent
|
||||
)
|
||||
//content.selectionWatcher = { onSelectionChanged(item.id, it) }
|
||||
content.pauseTextWatchers {
|
||||
enableEditMode()
|
||||
|
@ -392,10 +363,6 @@ interface TextBlockHolder : TextHolder {
|
|||
}
|
||||
}
|
||||
|
||||
fun clearTextWatchers() {
|
||||
content.clearTextWatchers()
|
||||
}
|
||||
|
||||
fun resolveTextBlockThemedColor(color: ThemeColor): Int {
|
||||
return content.context.resolveThemedTextColor(color, getDefaultTextColor())
|
||||
}
|
||||
|
@ -500,4 +467,12 @@ interface TextBlockHolder : TextHolder {
|
|||
}
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
fun BlockView.Text?.performInEditMode(block: (BlockView.Text) -> Unit) {
|
||||
this?.let { item ->
|
||||
if (item.mode == BlockView.Mode.EDIT) {
|
||||
block(item)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor.holders.text
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Editable
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -17,18 +16,15 @@ import com.anytypeio.anytype.core_ui.extensions.dark
|
|||
import com.anytypeio.anytype.core_ui.features.editor.SupportNesting
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
|
||||
import com.anytypeio.anytype.core_ui.features.editor.marks
|
||||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.mention.MentionEvent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Bulleted(
|
||||
val binding: ItemBlockBulletedBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
) : Text<BlockView.Text.Bulleted>(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
|
||||
val indent: View = binding.bulletIndent
|
||||
val bullet = binding.bullet
|
||||
|
@ -75,33 +71,6 @@ class Bulleted(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
item: BlockView.Text.Bulleted,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
override fun getMentionIconSize(): Int = mentionIconSize
|
||||
override fun getMentionIconPadding(): Int = mentionIconPadding
|
||||
override fun getMentionCheckedIcon(): Drawable? = mentionCheckedIcon
|
||||
|
|
|
@ -30,7 +30,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
|||
class Callout(
|
||||
val binding: ItemBlockCalloutBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(
|
||||
) : Text <BlockView.Text.Callout>(
|
||||
view = binding.root,
|
||||
clicked = clicked
|
||||
), BlockViewHolder.IndentableHolder, SupportNesting, DecoratableViewHolder {
|
||||
|
@ -63,45 +63,21 @@ class Callout(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
item: BlockView.Text.Callout,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
override fun bind(
|
||||
item: BlockView.Text.Callout
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
item = item
|
||||
).also {
|
||||
icon.setIcon(item.icon)
|
||||
icon.setOnClickListener {
|
||||
clicked(ListenerType.Callout.Icon(item.id))
|
||||
}
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
override fun processChangePayload(
|
||||
payloads: List<BlockViewDiffUtil.Payload>,
|
||||
item: BlockView,
|
||||
onTextChanged: (BlockView.Text) -> Unit,
|
||||
onSelectionChanged: (String, IntRange) -> Unit,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit
|
||||
) {
|
||||
val callout = requireNotNull(item as? BlockView.Text.Callout) {
|
||||
"Failed to processChangePayload. $item must be Callout"
|
||||
|
@ -114,11 +90,7 @@ class Callout(
|
|||
super.processChangePayload(
|
||||
payloads,
|
||||
item,
|
||||
onTextChanged,
|
||||
onSelectionChanged,
|
||||
clicked,
|
||||
onMentionEvent,
|
||||
onSlashEvent
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor.holders.text
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Editable
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
|
@ -15,20 +14,18 @@ import com.anytypeio.anytype.core_ui.databinding.ItemBlockCheckboxBinding
|
|||
import com.anytypeio.anytype.core_ui.features.editor.SupportNesting
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
|
||||
import com.anytypeio.anytype.core_ui.features.editor.marks
|
||||
import com.anytypeio.anytype.core_ui.features.editor.performInEditMode
|
||||
import com.anytypeio.anytype.core_ui.features.editor.provide
|
||||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.mention.MentionEvent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
class Checkbox(
|
||||
val binding: ItemBlockCheckboxBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
|
||||
var mode = BlockView.Mode.EDIT
|
||||
clicked: (ListenerType) -> Unit
|
||||
) : Text<BlockView.Text.Checkbox>(binding.root, clicked), SupportNesting,
|
||||
DecoratableViewHolder {
|
||||
|
||||
val checkbox: ImageView = binding.checkboxIcon
|
||||
private val container = binding.graphicPlusTextContainer
|
||||
|
@ -74,42 +71,18 @@ class Checkbox(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
override fun bind(
|
||||
item: BlockView.Text.Checkbox,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onCheckboxClicked: (BlockView.Text.Checkbox) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
) = super.bind(item = item).also {
|
||||
checkbox.isActivated = item.isChecked
|
||||
setCheckboxClickListener(item, onCheckboxClicked)
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
private fun setCheckboxClickListener(
|
||||
item: BlockView.Text.Checkbox,
|
||||
fun setCheckboxClickListener(
|
||||
onCheckboxClicked: (BlockView.Text.Checkbox) -> Unit
|
||||
) {
|
||||
checkbox.setOnClickListener {
|
||||
if (mode == BlockView.Mode.EDIT) {
|
||||
val item = provide<BlockView.Text.Checkbox>() ?: return@setOnClickListener
|
||||
item.performInEditMode {
|
||||
item.isChecked = !item.isChecked
|
||||
checkbox.isActivated = !checkbox.isActivated
|
||||
applyCheckedCheckboxColorSpan(item.isChecked)
|
||||
|
@ -130,16 +103,6 @@ class Checkbox(
|
|||
}
|
||||
}
|
||||
|
||||
override fun enableEditMode() {
|
||||
super.enableEditMode()
|
||||
mode = BlockView.Mode.EDIT
|
||||
}
|
||||
|
||||
override fun enableReadMode() {
|
||||
super.enableReadMode()
|
||||
mode = BlockView.Mode.READ
|
||||
}
|
||||
|
||||
override fun select(item: BlockView.Selectable) {
|
||||
container.isSelected = item.isSelected
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor.holders.text
|
||||
|
||||
import android.text.Editable
|
||||
import android.view.View
|
||||
import androidx.core.view.updatePadding
|
||||
import com.anytypeio.anytype.core_ui.BuildConfig
|
||||
|
@ -8,52 +7,21 @@ import com.anytypeio.anytype.core_ui.R
|
|||
import com.anytypeio.anytype.core_ui.features.editor.BlockViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.TextBlockHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.marks
|
||||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.mention.MentionEvent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
abstract class Header(
|
||||
abstract class Header<T : BlockView.Text.Header>(
|
||||
view: View,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(view, clicked),
|
||||
) : Text<T>(view, clicked),
|
||||
TextBlockHolder,
|
||||
BlockViewHolder.IndentableHolder,
|
||||
DecoratableViewHolder
|
||||
{
|
||||
DecoratableViewHolder {
|
||||
|
||||
abstract val header: TextInputWidget
|
||||
|
||||
fun bind(
|
||||
block: BlockView.Text.Header,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = block,
|
||||
onTextChanged = { _, editable ->
|
||||
block.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(block)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, block.getViewType())
|
||||
}
|
||||
|
||||
override fun indentize(item: BlockView.Indentable) {
|
||||
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
|
||||
header.updatePadding(
|
||||
|
|
|
@ -16,7 +16,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
class HeaderOne(
|
||||
val binding: ItemBlockHeaderOneBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Header(binding.root, clicked) {
|
||||
) : Header<BlockView.Text.Header.One>(binding.root, clicked) {
|
||||
|
||||
override val header: TextInputWidget = binding.headerOne
|
||||
override val content: TextInputWidget get() = header
|
||||
|
|
|
@ -16,7 +16,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
class HeaderThree(
|
||||
val binding: ItemBlockHeaderThreeBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Header(binding.root, clicked) {
|
||||
) : Header<BlockView.Text.Header.Three>(binding.root, clicked) {
|
||||
|
||||
override val header: TextInputWidget = binding.headerThree
|
||||
override val content: TextInputWidget get() = header
|
||||
|
|
|
@ -16,7 +16,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
|||
class HeaderTwo(
|
||||
val binding: ItemBlockHeaderTwoBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Header(binding.root, clicked) {
|
||||
) : Header<BlockView.Text.Header.Two>(binding.root, clicked) {
|
||||
|
||||
override val header: TextInputWidget = binding.headerTwo
|
||||
override val content: TextInputWidget get() = header
|
||||
|
|
|
@ -27,7 +27,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
|||
class Highlight(
|
||||
val binding: ItemBlockHighlightBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(binding.root, clicked), BlockViewHolder.IndentableHolder, SupportNesting, DecoratableViewHolder {
|
||||
) : Text<BlockView.Text.Highlight>(binding.root, clicked), BlockViewHolder.IndentableHolder, SupportNesting, DecoratableViewHolder {
|
||||
|
||||
override val content: TextInputWidget = binding.highlightContent
|
||||
override val root: View = itemView
|
||||
|
@ -75,34 +75,6 @@ class Highlight(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
item: BlockView.Text.Highlight,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
override fun select(item: BlockView.Selectable) {
|
||||
container.isSelected = item.isSelected
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor.holders.text
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Editable
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
|
@ -19,7 +18,6 @@ import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil
|
|||
import com.anytypeio.anytype.core_ui.features.editor.SupportNesting
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
|
||||
import com.anytypeio.anytype.core_ui.features.editor.marks
|
||||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.addDot
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
|
@ -31,7 +29,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
|||
class Numbered(
|
||||
val binding: ItemBlockNumberedBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
) : Text<BlockView.Text.Numbered>(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
|
||||
private val container = binding.graphicPlusTextContainer
|
||||
val number = binding.number
|
||||
|
@ -77,32 +75,10 @@ class Numbered(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
item: BlockView.Text.Numbered,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
override fun bind(
|
||||
item: BlockView.Text.Numbered
|
||||
) = super.bind(item = item).also {
|
||||
setNumber(item)
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
private fun setNumber(item: BlockView.Text.Numbered) {
|
||||
|
@ -122,20 +98,12 @@ class Numbered(
|
|||
override fun processChangePayload(
|
||||
payloads: List<BlockViewDiffUtil.Payload>,
|
||||
item: BlockView,
|
||||
onTextChanged: (BlockView.Text) -> Unit,
|
||||
onSelectionChanged: (String, IntRange) -> Unit,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit
|
||||
clicked: (ListenerType) -> Unit
|
||||
) {
|
||||
super.processChangePayload(
|
||||
payloads,
|
||||
item,
|
||||
onTextChanged,
|
||||
onSelectionChanged,
|
||||
clicked,
|
||||
onMentionEvent,
|
||||
onSlashEvent
|
||||
clicked
|
||||
)
|
||||
payloads.forEach { payload ->
|
||||
if (payload.changes.contains(BlockViewDiffUtil.NUMBER_CHANGED))
|
||||
|
|
|
@ -25,7 +25,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
|||
class Paragraph(
|
||||
val binding: ItemBlockTextBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
) : Text<BlockView.Text.Paragraph>(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
|
||||
override val root: View = binding.root
|
||||
override val content: TextInputWidget = binding.textContent
|
||||
|
@ -64,33 +64,6 @@ class Paragraph(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
item: BlockView.Text.Paragraph,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
override fun getMentionIconSize(): Int = mentionIconSize
|
||||
override fun getMentionIconPadding(): Int = mentionIconPadding
|
||||
override fun getMentionCheckedIcon(): Drawable? = mentionCheckedIcon
|
||||
|
|
|
@ -2,31 +2,31 @@ package com.anytypeio.anytype.core_ui.features.editor.holders.text
|
|||
|
||||
import android.text.Editable
|
||||
import android.view.View
|
||||
import androidx.annotation.CallSuper
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.extensions.applyMovementMethod
|
||||
import com.anytypeio.anytype.core_ui.extensions.color
|
||||
import com.anytypeio.anytype.core_ui.features.editor.BlockViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.TextBlockHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.performInEditMode
|
||||
import com.anytypeio.anytype.core_ui.features.editor.provide
|
||||
import com.anytypeio.anytype.core_ui.features.editor.withBlock
|
||||
import com.anytypeio.anytype.core_ui.tools.DefaultTextWatcher
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.mention.MentionEvent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.Checkable
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
||||
|
||||
abstract class Text(
|
||||
abstract class Text<BlockTextType : BlockView.Text>(
|
||||
view: View,
|
||||
protected val clicked: (ListenerType) -> Unit,
|
||||
protected val clicked: (ListenerType) -> Unit
|
||||
) : BlockViewHolder(view), TextBlockHolder, BlockViewHolder.IndentableHolder,
|
||||
BlockViewHolder.DragAndDropHolder {
|
||||
|
||||
private val defTextColor: Int = itemView.context.resources.getColor(R.color.text_primary, null)
|
||||
|
||||
fun bind(
|
||||
item: BlockView.TextBlockProps,
|
||||
onTextChanged: (String, Editable) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: (() -> Boolean)? = null
|
||||
open fun bind(
|
||||
item: BlockTextType,
|
||||
) {
|
||||
indentize(item)
|
||||
select(item)
|
||||
|
@ -47,8 +47,6 @@ abstract class Text(
|
|||
|
||||
content.applyMovementMethod(item)
|
||||
|
||||
clearTextWatchers()
|
||||
|
||||
setContent(
|
||||
item = item,
|
||||
clicked = clicked
|
||||
|
@ -58,39 +56,6 @@ abstract class Text(
|
|||
if (item.isFocused) setCursor(item)
|
||||
|
||||
setFocus(item)
|
||||
|
||||
observe(
|
||||
item = item,
|
||||
onTextChanged = onTextChanged,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
)
|
||||
}
|
||||
|
||||
content.apply {
|
||||
enableEnterKeyDetector(
|
||||
onEnterClicked = { range ->
|
||||
content.text?.let { editable ->
|
||||
onSplitLineEnterClicked(
|
||||
item.id,
|
||||
editable,
|
||||
range
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
enableBackspaceDetector(
|
||||
onEmptyBlockBackspaceClicked = {
|
||||
onEmptyBlockBackspaceClicked(item.id)
|
||||
},
|
||||
onNonEmptyBlockBackspaceClicked = {
|
||||
content.text?.let { editable ->
|
||||
onNonEmptyBlockBackspaceClicked(
|
||||
item.id,
|
||||
editable
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,16 +84,16 @@ abstract class Text(
|
|||
setBackgroundColor(background = item.background)
|
||||
}
|
||||
|
||||
fun observe(
|
||||
item: BlockView.TextBlockProps,
|
||||
onTextChanged: (String, Editable) -> Unit,
|
||||
private fun observe(
|
||||
onTextChanged: (Editable) -> Unit,
|
||||
onBackPressedCallback: (() -> Boolean)? = null
|
||||
) {
|
||||
|
||||
content.apply {
|
||||
addTextChangedListener(
|
||||
DefaultTextWatcher { text ->
|
||||
onTextChanged(item.id, text)
|
||||
provide<BlockView.Text>().performInEditMode { item ->
|
||||
onTextChanged(text)
|
||||
}
|
||||
}
|
||||
)
|
||||
backButtonWatcher = onBackPressedCallback
|
||||
|
@ -144,4 +109,47 @@ abstract class Text(
|
|||
}
|
||||
|
||||
override fun getDefaultTextColor(): Int = defTextColor
|
||||
|
||||
@CallSuper
|
||||
open fun setupViewHolder(
|
||||
onTextChanged: (Editable) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onMentionEvent: ((MentionEvent) -> Unit),
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onBackPressedCallback: (() -> Boolean)? = null
|
||||
) {
|
||||
observe(onTextChanged, onBackPressedCallback)
|
||||
|
||||
content.apply {
|
||||
enableEnterKeyDetector(
|
||||
onEnterClicked = { range ->
|
||||
val id = provide<BlockView.Text>()?.id ?: return@enableEnterKeyDetector
|
||||
val editable = content.text ?: return@enableEnterKeyDetector
|
||||
onSplitLineEnterClicked(
|
||||
id,
|
||||
editable,
|
||||
range
|
||||
)
|
||||
}
|
||||
)
|
||||
enableBackspaceDetector(
|
||||
onEmptyBlockBackspaceClicked = {
|
||||
val id = provide<BlockView.Text>()?.id ?: return@enableBackspaceDetector
|
||||
onEmptyBlockBackspaceClicked(id)
|
||||
},
|
||||
onNonEmptyBlockBackspaceClicked = {
|
||||
val id = provide<BlockView.Text>()?.id ?: return@enableBackspaceDetector
|
||||
val editable = content.text ?: return@enableBackspaceDetector
|
||||
onNonEmptyBlockBackspaceClicked(
|
||||
id,
|
||||
editable
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
setupMentionWatcher(onMentionEvent) { provide() }
|
||||
setupSlashWatcher(onSlashEvent) { provide() }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor.holders.text
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Editable
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -16,7 +15,7 @@ import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil
|
|||
import com.anytypeio.anytype.core_ui.features.editor.SupportNesting
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
|
||||
import com.anytypeio.anytype.core_ui.features.editor.marks
|
||||
import com.anytypeio.anytype.core_ui.features.editor.provide
|
||||
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
|
@ -27,7 +26,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
|||
class Toggle(
|
||||
val binding: ItemBlockToggleBinding,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
) : Text(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
) : Text<BlockView.Text.Toggle>(binding.root, clicked), SupportNesting, DecoratableViewHolder {
|
||||
|
||||
private var mode = BlockView.Mode.EDIT
|
||||
|
||||
|
@ -77,41 +76,29 @@ class Toggle(
|
|||
}
|
||||
}
|
||||
|
||||
fun bind(
|
||||
item: BlockView.Text.Toggle,
|
||||
onTextBlockTextChanged: (BlockView.Text) -> Unit,
|
||||
onToggleClicked: (String) -> Unit,
|
||||
onTogglePlaceholderClicked: (String) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit,
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit,
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit,
|
||||
onBackPressedCallback: () -> Boolean
|
||||
) = super.bind(
|
||||
item = item,
|
||||
onTextChanged = { _, editable ->
|
||||
item.apply {
|
||||
text = editable.toString()
|
||||
marks = editable.marks()
|
||||
}
|
||||
onTextBlockTextChanged(item)
|
||||
},
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onBackPressedCallback = onBackPressedCallback
|
||||
).also {
|
||||
override fun bind(
|
||||
item: BlockView.Text.Toggle
|
||||
) = super.bind(item = item).also {
|
||||
toggle.rotation = if (item.toggled) EXPANDED_ROTATION else COLLAPSED_ROTATION
|
||||
if (item.mode == BlockView.Mode.READ) {
|
||||
placeholder.isVisible = false
|
||||
} else {
|
||||
placeholder.isVisible = item.isEmpty && item.toggled
|
||||
}
|
||||
placeholder.setOnClickListener { onTogglePlaceholderClicked(item.id) }
|
||||
toggle.setOnClickListener { onToggleClicked(item.id) }
|
||||
setupMentionWatcher(onMentionEvent)
|
||||
setupSlashWatcher(onSlashEvent, item.getViewType())
|
||||
}
|
||||
|
||||
fun setupToggle(
|
||||
onToggleClicked: (String) -> Unit,
|
||||
onTogglePlaceholderClicked: (String) -> Unit
|
||||
) {
|
||||
placeholder.setOnClickListener {
|
||||
val id = provide<BlockView.Text.Toggle>()?.id ?: return@setOnClickListener
|
||||
onTogglePlaceholderClicked(id)
|
||||
}
|
||||
toggle.setOnClickListener {
|
||||
val id = provide<BlockView.Text.Toggle>()?.id ?: return@setOnClickListener
|
||||
onToggleClicked(id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMentionIconSize(): Int = mentionIconSize
|
||||
|
@ -143,21 +130,13 @@ class Toggle(
|
|||
override fun processChangePayload(
|
||||
payloads: List<BlockViewDiffUtil.Payload>,
|
||||
item: BlockView,
|
||||
onTextChanged: (BlockView.Text) -> Unit,
|
||||
onSelectionChanged: (String, IntRange) -> Unit,
|
||||
clicked: (ListenerType) -> Unit,
|
||||
onMentionEvent: (MentionEvent) -> Unit,
|
||||
onSlashEvent: (SlashEvent) -> Unit
|
||||
clicked: (ListenerType) -> Unit
|
||||
) {
|
||||
check(item is BlockView.Text.Toggle) { "Expected a toggle block, but was: $item" }
|
||||
super.processChangePayload(
|
||||
payloads,
|
||||
item,
|
||||
onTextChanged,
|
||||
onSelectionChanged,
|
||||
clicked,
|
||||
onMentionEvent,
|
||||
onSlashEvent
|
||||
)
|
||||
payloads.forEach { payload ->
|
||||
if (payload.isToggleStateChanged) {
|
||||
|
|
|
@ -119,7 +119,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -145,7 +145,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -180,7 +180,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -218,7 +218,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -244,11 +244,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(TEXT_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -275,7 +271,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -301,11 +297,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(BACKGROUND_COLOR_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
|
||||
|
@ -334,7 +326,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -360,11 +352,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(TEXT_COLOR_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val expected = context.resources.getColor(R.color.palette_dark_lime)
|
||||
|
@ -392,7 +380,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -428,11 +416,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(CURSOR_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -465,7 +449,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -518,7 +502,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
val adapter = givenAdapter(
|
||||
views = views,
|
||||
onTextChanged = { id, editable ->
|
||||
events.add(Pair(id, editable.toString()))
|
||||
|
@ -561,7 +545,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
val adapter = givenAdapter(
|
||||
views = views,
|
||||
onTextChanged = { id, editable ->
|
||||
events.add(Pair(id, editable.toString()))
|
||||
|
@ -587,11 +571,7 @@ class BlockAdapterTest {
|
|||
)
|
||||
),
|
||||
item = updated,
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -611,7 +591,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -638,7 +618,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -677,7 +657,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -726,7 +706,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
val adapter = givenAdapter(
|
||||
views = views,
|
||||
onFocusChanged = { id, hasFocus ->
|
||||
events.add(Pair(id, hasFocus))
|
||||
|
@ -775,7 +755,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
val adapter = givenAdapter(
|
||||
views = views,
|
||||
onTextChanged = { id, editable ->
|
||||
events.add(Pair(id, editable.toString()))
|
||||
|
@ -819,7 +799,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_PARAGRAPH)
|
||||
|
||||
|
@ -853,7 +833,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_HEADER_ONE)
|
||||
|
||||
|
@ -886,7 +866,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_HEADER_TWO)
|
||||
|
||||
|
@ -921,7 +901,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_HEADER_THREE)
|
||||
|
||||
|
@ -951,7 +931,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_CHECKBOX)
|
||||
|
||||
|
@ -984,7 +964,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_TOGGLE)
|
||||
|
||||
|
@ -1013,7 +993,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_FILE_PLACEHOLDER)
|
||||
|
||||
|
@ -1046,7 +1026,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_FILE_ERROR)
|
||||
|
||||
|
@ -1075,7 +1055,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_FILE_UPLOAD)
|
||||
|
||||
|
@ -1102,7 +1082,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO)
|
||||
|
||||
|
@ -1129,7 +1109,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO_PLACEHOLDER)
|
||||
|
||||
|
@ -1161,7 +1141,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO_UPLOAD)
|
||||
|
||||
|
@ -1194,7 +1174,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO_ERROR)
|
||||
|
||||
|
@ -1226,7 +1206,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_OBJECT_LINK_DEFAULT)
|
||||
|
||||
|
@ -1252,7 +1232,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_BOOKMARK_PLACEHOLDER)
|
||||
|
||||
|
@ -1262,7 +1242,8 @@ class BlockAdapterTest {
|
|||
|
||||
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
|
||||
val actual = holder.itemView.findViewById<ViewGroup>(R.id.root).paddingLeft
|
||||
val expected = view.indent * holder.dimen(R.dimen.indent) + holder.dimen(R.dimen.default_document_item_padding_start)
|
||||
val expected =
|
||||
view.indent * holder.dimen(R.dimen.indent) + holder.dimen(R.dimen.default_document_item_padding_start)
|
||||
assertEquals(expected, actual)
|
||||
} else {
|
||||
val actual = holder.itemView.findViewById<ViewGroup>(R.id.root).paddingLeft
|
||||
|
@ -1291,7 +1272,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_PICTURE)
|
||||
|
||||
|
@ -1320,7 +1301,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_PICTURE_PLACEHOLDER)
|
||||
|
||||
|
@ -1353,7 +1334,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_PICTURE_ERROR)
|
||||
|
||||
|
@ -1384,7 +1365,7 @@ class BlockAdapterTest {
|
|||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_PICTURE_UPLOAD)
|
||||
|
||||
|
@ -1394,7 +1375,8 @@ class BlockAdapterTest {
|
|||
|
||||
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
|
||||
val actual = holder.itemView.marginLeft
|
||||
val expected = holder.dimen(R.dimen.bookmark_default_margin_start) + view.indent * holder.dimen(R.dimen.indent)
|
||||
val expected =
|
||||
holder.dimen(R.dimen.bookmark_default_margin_start) + view.indent * holder.dimen(R.dimen.indent)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
@ -1416,7 +1398,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1467,7 +1449,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1606,7 +1588,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1652,7 +1634,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(firstParagraph, secondParagraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1686,7 +1668,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1730,7 +1712,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(paragraph)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1763,11 +1745,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -1795,7 +1773,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1836,7 +1814,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1879,7 +1857,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(title)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -1951,7 +1929,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views: List<BlockView> = listOf(h1, h2, h3)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2064,7 +2042,7 @@ class BlockAdapterTest {
|
|||
h3Notselected
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2135,7 +2113,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views: List<BlockView> = listOf(h1, h2, h3)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2226,7 +2204,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views: List<BlockView> = listOf(h1, h2, h3)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2265,11 +2243,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2301,11 +2275,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2337,11 +2307,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2369,7 +2335,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(highlight)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2411,7 +2377,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(highlight)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2437,11 +2403,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(TEXT_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2463,7 +2425,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(highlight)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2505,7 +2467,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(highlight)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2536,11 +2498,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2568,7 +2526,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(bullet)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2607,7 +2565,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(bullet)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2650,7 +2608,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(bullet)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2681,11 +2639,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2713,7 +2667,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(checkbox)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2752,7 +2706,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(checkbox)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2795,7 +2749,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(checkbox)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2826,11 +2780,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -2859,7 +2809,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(numbered)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2899,7 +2849,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(numbered)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2943,7 +2893,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(numbered)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -2974,11 +2924,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -3008,7 +2954,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(toggle)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -3049,7 +2995,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(toggle)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -3094,7 +3040,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(toggle)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -3125,11 +3071,7 @@ class BlockAdapterTest {
|
|||
changes = listOf(READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
),
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -3173,7 +3115,7 @@ class BlockAdapterTest {
|
|||
)
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -3214,7 +3156,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(file)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -3257,7 +3199,7 @@ class BlockAdapterTest {
|
|||
|
||||
val views = listOf(file)
|
||||
|
||||
val adapter = buildAdapter(views)
|
||||
val adapter = givenAdapter(views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
@ -3296,7 +3238,7 @@ class BlockAdapterTest {
|
|||
|
||||
val lifecycle = TestLifecycle()
|
||||
|
||||
val adapter = buildAdapter(listOf(givenVideo()), lifecycle = lifecycle)
|
||||
val adapter = givenAdapter(listOf(givenVideo()), lifecycle = lifecycle)
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO)
|
||||
|
||||
|
@ -3318,7 +3260,7 @@ class BlockAdapterTest {
|
|||
|
||||
val recycler = givenRecycler()
|
||||
|
||||
val adapter = buildAdapter(listOf(givenVideo()))
|
||||
val adapter = givenAdapter(listOf(givenVideo()))
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO)
|
||||
|
||||
|
@ -3345,7 +3287,7 @@ class BlockAdapterTest {
|
|||
|
||||
val recycler = givenRecycler()
|
||||
|
||||
val adapter = buildAdapter(listOf(givenVideo()))
|
||||
val adapter = givenAdapter(listOf(givenVideo()))
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO)
|
||||
|
||||
|
@ -3372,7 +3314,7 @@ class BlockAdapterTest {
|
|||
|
||||
val recycler = givenRecycler()
|
||||
|
||||
val adapter = buildAdapter(listOf(givenVideo()))
|
||||
val adapter = givenAdapter(listOf(givenVideo()))
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, Types.HOLDER_VIDEO)
|
||||
|
||||
|
@ -3403,7 +3345,7 @@ class BlockAdapterTest {
|
|||
val runs = mutableListOf<PerformanceTestsResults>()
|
||||
|
||||
givenPerformancePackageList().forEach { pack ->
|
||||
val adapter = buildAdapter(listOf(pack.block))
|
||||
val adapter = givenAdapter(listOf(pack.block))
|
||||
val holder = adapter.onCreateViewHolder(recycler, pack.holderId)
|
||||
|
||||
check(holder.javaClass.canonicalName == pack.className)
|
||||
|
@ -3440,7 +3382,12 @@ class BlockAdapterTest {
|
|||
givenPicture(),
|
||||
Picture::class.qualifiedName!!
|
||||
),
|
||||
PerformancePackage(Types.HOLDER_TITLE, "Title", givenTitle(), Document::class.qualifiedName!!)
|
||||
PerformancePackage(
|
||||
Types.HOLDER_TITLE,
|
||||
"Title",
|
||||
givenTitle(),
|
||||
Document::class.qualifiedName!!
|
||||
)
|
||||
)
|
||||
|
||||
private fun givenRecycler() = RecyclerView(context).apply {
|
||||
|
@ -3476,12 +3423,13 @@ class BlockAdapterTest {
|
|||
decorations = emptyList()
|
||||
)
|
||||
|
||||
private fun buildAdapter(
|
||||
private fun givenAdapter(
|
||||
views: List<BlockView>,
|
||||
onSplitLineEnterClicked: (String, Editable, IntRange) -> Unit = { _, _, _ -> },
|
||||
onFocusChanged: (String, Boolean) -> Unit = { _, _ -> },
|
||||
onTitleBlockTextChanged: (Id, String) -> Unit = { _, _ -> },
|
||||
onTextChanged: (String, Editable) -> Unit = { _, _ -> },
|
||||
onToggleClicked: (String) -> Unit = {},
|
||||
lifecycle: Lifecycle = TestLifecycle()
|
||||
): BlockAdapter {
|
||||
return BlockAdapter(
|
||||
|
@ -3498,7 +3446,7 @@ class BlockAdapterTest {
|
|||
onTextInputClicked = {},
|
||||
onPageIconClicked = {},
|
||||
onTogglePlaceholderClicked = {},
|
||||
onToggleClicked = {},
|
||||
onToggleClicked = onToggleClicked,
|
||||
onTextBlockTextChanged = {},
|
||||
onTitleBlockTextChanged = onTitleBlockTextChanged,
|
||||
onTitleTextInputClicked = {},
|
||||
|
|
|
@ -237,11 +237,7 @@ class HeaderBlockTest {
|
|||
)
|
||||
),
|
||||
item = updated,
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -295,11 +291,7 @@ class HeaderBlockTest {
|
|||
)
|
||||
),
|
||||
item = updated,
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -353,11 +345,7 @@ class HeaderBlockTest {
|
|||
)
|
||||
),
|
||||
item = updated,
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
clicked = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
|
|
@ -129,49 +129,6 @@ class BlockAdapterCheckboxTest : BlockAdapterTestSetup() {
|
|||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should not have checkboxhighlight span when turn ckeckbox from true to false`() {
|
||||
|
||||
val checkbox = BlockView.Text.Checkbox(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
text = MockDataFactory.randomString(),
|
||||
isFocused = true,
|
||||
isChecked = true
|
||||
)
|
||||
|
||||
val views = listOf(checkbox)
|
||||
|
||||
val adapter = buildAdapter(views = views)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_CHECKBOX)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
// TESTING
|
||||
|
||||
check(holder is Checkbox)
|
||||
|
||||
val spans = holder.content.text!!.getSpans<CheckedCheckboxColorSpan>(0)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = spans.size
|
||||
)
|
||||
|
||||
holder.checkbox.performClick()
|
||||
|
||||
val spansAfter = holder.content.text!!.getSpans<CheckedCheckboxColorSpan>(0)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = spansAfter.size
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should have checkboxhighlight when payload text changed and is checked`() {
|
||||
|
||||
|
@ -209,10 +166,6 @@ class BlockAdapterCheckboxTest : BlockAdapterTestSetup() {
|
|||
payloads = listOf(BlockViewDiffUtil.Payload(changes = listOf(BlockViewDiffUtil.TEXT_CHANGED))),
|
||||
item = checkbox.copy(text = "$text Second"),
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -266,10 +219,6 @@ class BlockAdapterCheckboxTest : BlockAdapterTestSetup() {
|
|||
)
|
||||
),
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -323,10 +272,6 @@ class BlockAdapterCheckboxTest : BlockAdapterTestSetup() {
|
|||
)
|
||||
),
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -372,10 +317,6 @@ class BlockAdapterCheckboxTest : BlockAdapterTestSetup() {
|
|||
payloads = listOf(BlockViewDiffUtil.Payload(changes = listOf(BlockViewDiffUtil.TEXT_CHANGED))),
|
||||
item = checkbox.copy(text = "$text Second"),
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
@ -420,10 +361,6 @@ class BlockAdapterCheckboxTest : BlockAdapterTestSetup() {
|
|||
payloads = listOf(BlockViewDiffUtil.Payload(changes = listOf(BlockViewDiffUtil.TEXT_CHANGED))),
|
||||
item = checkbox.copy(text = "$text Second"),
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
|
|
|
@ -264,10 +264,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -338,10 +334,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -412,10 +404,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -487,10 +475,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -561,10 +545,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -636,10 +616,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -716,10 +692,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -797,10 +769,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -879,10 +847,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = updated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
@ -949,10 +913,6 @@ class BlockAdapterMovementMethodTest : BlockAdapterTestSetup() {
|
|||
),
|
||||
item = paragraphUpdated,
|
||||
clicked = {},
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextChanged = {},
|
||||
onMentionEvent = {},
|
||||
onSlashEvent = {}
|
||||
)
|
||||
|
||||
val testMM = holder.content.movementMethod
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.anytypeio.anytype.test_utils.MockDataFactory
|
|||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
|
@ -27,348 +28,6 @@ import kotlin.test.assertTrue
|
|||
@Config(sdk = [Build.VERSION_CODES.P])
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class BlockAdapterReadWriteModeTest : BlockAdapterTestSetup() {
|
||||
|
||||
@Test
|
||||
fun `endline-enter press listener should be enabled when switching from read to edit mode`() {
|
||||
|
||||
// Setup
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val block = BlockView.Text.Paragraph(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = MockDataFactory.randomString(),
|
||||
id = MockDataFactory.randomUuid()
|
||||
)
|
||||
|
||||
val views = listOf(block)
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = block.text.length,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
views = views,
|
||||
onSplitLineEnterClicked = { _, _, _ -> trigger += 1 }
|
||||
)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
this.adapter = adapter
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_PARAGRAPH)
|
||||
|
||||
check(holder is Paragraph)
|
||||
|
||||
// Testing
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
val payloads: MutableList<Any> = mutableListOf(
|
||||
BlockViewDiffUtil.Payload(
|
||||
changes = listOf(
|
||||
BlockViewDiffUtil.READ_WRITE_MODE_CHANGED,
|
||||
BlockViewDiffUtil.FOCUS_CHANGED,
|
||||
BlockViewDiffUtil.CURSOR_CHANGED
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0, payloads = payloads)
|
||||
|
||||
holder.content.onEditorAction(EditorInfo.IME_ACTION_GO)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `split-line-enter press listener should be enabled when switching from read to edit mode`() {
|
||||
|
||||
// Setup
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val block = BlockView.Text.Paragraph(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = MockDataFactory.randomString(),
|
||||
id = MockDataFactory.randomUuid(),
|
||||
cursor = null
|
||||
)
|
||||
|
||||
val views = listOf(block)
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = 5,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
views = views,
|
||||
onSplitLineEnterClicked = { _, _, _ -> trigger += 1 }
|
||||
)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
this.adapter = adapter
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_PARAGRAPH)
|
||||
|
||||
check(holder is Paragraph)
|
||||
|
||||
// Testing
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
val payloads: MutableList<Any> = mutableListOf(
|
||||
BlockViewDiffUtil.Payload(
|
||||
changes = listOf(
|
||||
BlockViewDiffUtil.READ_WRITE_MODE_CHANGED,
|
||||
BlockViewDiffUtil.FOCUS_CHANGED,
|
||||
BlockViewDiffUtil.CURSOR_CHANGED
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0, payloads = payloads)
|
||||
|
||||
assertEquals(
|
||||
expected = 5,
|
||||
actual = holder.content.selectionStart
|
||||
)
|
||||
|
||||
holder.content.onEditorAction(EditorInfo.IME_ACTION_GO)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on-non-empty-block-backspace-press listener should be enabled when switching from read to edit mode`() {
|
||||
|
||||
// Setup
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val block = BlockView.Text.Paragraph(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = MockDataFactory.randomString(),
|
||||
id = MockDataFactory.randomUuid(),
|
||||
cursor = null
|
||||
)
|
||||
|
||||
val views = listOf(block)
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = 0,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
views = views,
|
||||
onNonEmptyBlockBackspaceClicked = { _, _ -> trigger += 1 }
|
||||
)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
this.adapter = adapter
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_PARAGRAPH)
|
||||
|
||||
check(holder is Paragraph)
|
||||
|
||||
// Testing
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
val payloads: MutableList<Any> = mutableListOf(
|
||||
BlockViewDiffUtil.Payload(
|
||||
changes = listOf(
|
||||
BlockViewDiffUtil.READ_WRITE_MODE_CHANGED,
|
||||
BlockViewDiffUtil.FOCUS_CHANGED,
|
||||
BlockViewDiffUtil.CURSOR_CHANGED
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0, payloads = payloads)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = holder.content.selectionStart
|
||||
)
|
||||
|
||||
holder.content.dispatchKeyEvent(
|
||||
KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on-empty-block-backspace-press listener should be enabled when switching from read to edit mode`() {
|
||||
|
||||
// Setup
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val block = BlockView.Text.Paragraph(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = "",
|
||||
id = MockDataFactory.randomUuid(),
|
||||
cursor = null
|
||||
)
|
||||
|
||||
val views = listOf(block)
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = 0,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
views = views,
|
||||
onEmptyBlockBackspaceClicked = { trigger += 1 }
|
||||
)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
this.adapter = adapter
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_PARAGRAPH)
|
||||
|
||||
check(holder is Paragraph)
|
||||
|
||||
// Testing
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
val payloads: MutableList<Any> = mutableListOf(
|
||||
BlockViewDiffUtil.Payload(
|
||||
changes = listOf(
|
||||
BlockViewDiffUtil.READ_WRITE_MODE_CHANGED,
|
||||
BlockViewDiffUtil.FOCUS_CHANGED,
|
||||
BlockViewDiffUtil.CURSOR_CHANGED
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0, payloads = payloads)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = holder.content.selectionStart
|
||||
)
|
||||
|
||||
holder.content.dispatchKeyEvent(
|
||||
KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkbox-clicked listener should be enabled when switching from read to edit mode`() {
|
||||
|
||||
// Setup
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val block = BlockView.Text.Checkbox(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = MockDataFactory.randomString(),
|
||||
id = MockDataFactory.randomUuid(),
|
||||
isChecked = false
|
||||
)
|
||||
|
||||
val views = listOf(block)
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT
|
||||
)
|
||||
)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
views = views,
|
||||
onCheckboxClicked = { trigger += 1 }
|
||||
)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
this.adapter = adapter
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_CHECKBOX)
|
||||
|
||||
check(holder is Checkbox)
|
||||
|
||||
// Testing
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
holder.checkbox.performClick()
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = trigger
|
||||
)
|
||||
|
||||
val payloads: MutableList<Any> = mutableListOf(
|
||||
BlockViewDiffUtil.Payload(
|
||||
changes = listOf(
|
||||
BlockViewDiffUtil.READ_WRITE_MODE_CHANGED
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0, payloads = payloads)
|
||||
|
||||
holder.checkbox.performClick()
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario:
|
||||
* 1. Text block[bold, link spans] EDIT mode
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
package com.anytypeio.anytype.core_ui.features.editor
|
||||
|
||||
import android.os.Build
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.text.Toggle
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_TOGGLE
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
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 BlockAdapterToggleTest : BlockAdapterTestSetup() {
|
||||
|
||||
@Test
|
||||
fun `toggle click should be intercepted when switching from read to edit mode`() {
|
||||
|
||||
// Setup
|
||||
|
||||
var triggerCount = 0
|
||||
|
||||
val text = MockDataFactory.randomString()
|
||||
|
||||
val block = BlockView.Text.Toggle(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = text,
|
||||
id = MockDataFactory.randomUuid(),
|
||||
isFocused = false
|
||||
)
|
||||
|
||||
val views = listOf(block)
|
||||
|
||||
val adapter = buildAdapter(
|
||||
views = views,
|
||||
onToggleClicked = { triggerCount = triggerCount.inc() }
|
||||
)
|
||||
|
||||
val recycler = RecyclerView(context).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
val holder = adapter.onCreateViewHolder(recycler, HOLDER_TOGGLE)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0)
|
||||
|
||||
// TESTING
|
||||
|
||||
check(holder is Toggle)
|
||||
|
||||
// Performing click in read-mode
|
||||
|
||||
holder.toggle.performClick()
|
||||
|
||||
assertEquals(
|
||||
actual = triggerCount,
|
||||
expected = 1
|
||||
)
|
||||
|
||||
// Updating views
|
||||
|
||||
adapter.updateWithDiffUtil(
|
||||
listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val payload: MutableList<Any> = mutableListOf(
|
||||
BlockViewDiffUtil.Payload(
|
||||
changes = listOf(BlockViewDiffUtil.READ_WRITE_MODE_CHANGED)
|
||||
)
|
||||
)
|
||||
|
||||
adapter.onBindViewHolder(holder, 0, payload)
|
||||
|
||||
// Performing click in edit mode
|
||||
|
||||
holder.toggle.performClick()
|
||||
|
||||
assertEquals(
|
||||
actual = triggerCount,
|
||||
expected = 2
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package com.anytypeio.anytype.core_ui.uitests
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.widget.EditText
|
||||
import androidx.core.text.getSpans
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.testing.FragmentScenario
|
||||
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.CheckedCheckboxColorSpan
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import com.anytypeio.anytype.test_utils.TestFragment
|
||||
import com.anytypeio.anytype.test_utils.utils.onItemView
|
||||
import com.anytypeio.anytype.test_utils.utils.performClick
|
||||
import com.anytypeio.anytype.test_utils.utils.rVMatcher
|
||||
import com.anytypeio.anytype.test_utils.utils.view_action.extractView
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.assertEquals
|
||||
import com.anytypeio.anytype.test_utils.R as R_test
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(
|
||||
manifest = Config.NONE,
|
||||
sdk = [Build.VERSION_CODES.P],
|
||||
instrumentedPackages = [
|
||||
// required to access final members on androidx.loader.content.ModernAsyncTask
|
||||
"androidx.loader.content"
|
||||
]
|
||||
)
|
||||
class BlockAdapterCheckboxTest {
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
lateinit var scenario: FragmentScenario<TestFragment>
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context.setTheme(R.style.Theme_MaterialComponents)
|
||||
scenario = launchFragmentInContainer()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should not have checkbox highlight span - when turn checkbox from true to false`() {
|
||||
scenario.onFragment {
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenCheckbox()
|
||||
|
||||
val adapter = givenAdapter(listOf(block))
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
val spans =
|
||||
onItemView(
|
||||
0,
|
||||
R.id.checkboxContent
|
||||
).extractView<EditText>().text.getSpans<CheckedCheckboxColorSpan>(0)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = spans.size
|
||||
)
|
||||
|
||||
onItemView(0, R.id.checkboxIcon).performClick()
|
||||
|
||||
val spansAfter =
|
||||
onItemView(0, R.id.checkboxContent).extractView<EditText>().text
|
||||
.getSpans<CheckedCheckboxColorSpan>(0)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = spansAfter.size
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `checkbox-clicked listener should be enabled - when switching from read to edit mode`() {
|
||||
scenario.onFragment {
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenCheckbox(BlockView.Mode.READ)
|
||||
|
||||
val adapter = givenAdapter(
|
||||
views = listOf(block),
|
||||
onCheckboxClicked = { trigger++ }
|
||||
)
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.checkboxIcon).performClick()
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.checkboxIcon).performClick()
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun givenRecycler(it: Fragment): RecyclerView =
|
||||
it.view!!.findViewById<RecyclerView>(R_test.id.recycler).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
private fun givenCheckbox(mode: BlockView.Mode = BlockView.Mode.EDIT) = BlockView.Text.Checkbox(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
text = MockDataFactory.randomString(),
|
||||
isFocused = true,
|
||||
isChecked = true,
|
||||
mode = mode
|
||||
)
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
package com.anytypeio.anytype.core_ui.uitests
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.view.KeyEvent
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.testing.FragmentScenario
|
||||
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import com.anytypeio.anytype.test_utils.TestFragment
|
||||
import com.anytypeio.anytype.test_utils.utils.onItemView
|
||||
import com.anytypeio.anytype.test_utils.utils.rVMatcher
|
||||
import com.anytypeio.anytype.test_utils.utils.view_action.extractView
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.assertEquals
|
||||
import com.anytypeio.anytype.test_utils.R as R_test
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(
|
||||
manifest = Config.NONE,
|
||||
sdk = [Build.VERSION_CODES.P],
|
||||
instrumentedPackages = [
|
||||
// required to access final members on androidx.loader.content.ModernAsyncTask
|
||||
"androidx.loader.content"
|
||||
]
|
||||
)
|
||||
class BlockAdapterReadWriteModeTest {
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
lateinit var scenario: FragmentScenario<TestFragment>
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context.setTheme(R.style.Theme_MaterialComponents)
|
||||
scenario = launchFragmentInContainer()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `split-line-enter press listener should be enabled - when switching from read to edit mode`() {
|
||||
scenario.onFragment {
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenParagraph()
|
||||
|
||||
val adapter = givenAdapter(
|
||||
views = listOf(block),
|
||||
onSplitLineEnterClicked = { _, _, _ -> trigger++ }
|
||||
)
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = 5,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
val selectionStart =
|
||||
onItemView(0, R.id.textContent).extractView<TextView>().selectionStart
|
||||
|
||||
assertEquals(
|
||||
expected = 5,
|
||||
actual = selectionStart
|
||||
)
|
||||
|
||||
onItemView(0, R.id.textContent).perform(ViewActions.pressImeActionButton())
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `endline-enter press listener should be enabled - when switching from read to edit mode`() {
|
||||
scenario.onFragment {
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenParagraph()
|
||||
|
||||
val adapter = givenAdapter(
|
||||
views = listOf(block),
|
||||
onSplitLineEnterClicked = { _, _, _ -> trigger++ }
|
||||
)
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = block.text.length,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.textContent).perform(ViewActions.pressImeActionButton())
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on-non-empty-block-backspace-press listener should be enabled - when switching from read to edit mode`() {
|
||||
scenario.onFragment {
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenParagraph()
|
||||
|
||||
val adapter = givenAdapter(
|
||||
views = listOf(block),
|
||||
onNonEmptyBlockBackspaceClicked = { _, _ -> trigger++ }
|
||||
)
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.textContent).perform(ViewActions.pressKey(KeyEvent.KEYCODE_DEL))
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = 0,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.textContent).perform(ViewActions.pressKey(KeyEvent.KEYCODE_DEL))
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on-empty-block-backspace-press listener should be enabled - when switching from read to edit mode`() {
|
||||
scenario.onFragment {
|
||||
|
||||
var trigger = 0
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenParagraph()
|
||||
|
||||
val adapter = givenAdapter(
|
||||
views = listOf(block),
|
||||
onEmptyBlockBackspaceClicked = { trigger++ }
|
||||
)
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.textContent).perform(ViewActions.pressKey(KeyEvent.KEYCODE_DEL))
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
|
||||
val updated = listOf(
|
||||
block.copy(
|
||||
text = "",
|
||||
mode = BlockView.Mode.EDIT,
|
||||
cursor = 0,
|
||||
isFocused = true
|
||||
)
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(items = updated)
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
|
||||
onItemView(0, R.id.textContent).perform(ViewActions.pressKey(KeyEvent.KEYCODE_DEL))
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = trigger
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun givenRecycler(it: Fragment): RecyclerView =
|
||||
it.view!!.findViewById<RecyclerView>(R_test.id.recycler).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
private fun givenParagraph() = BlockView.Text.Paragraph(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = MockDataFactory.randomString(),
|
||||
id = MockDataFactory.randomUuid(),
|
||||
cursor = null
|
||||
)
|
||||
}
|
|
@ -25,24 +25,28 @@ fun givenAdapter(
|
|||
onTitleCheckboxClicked: (BlockView.Title.Todo) -> Unit = {},
|
||||
onTitleBlockTextChanged: (Id, String) -> Unit = { _, _ -> },
|
||||
onTextChanged: (String, Editable) -> Unit = { _, _ -> },
|
||||
onToggleClicked: (String) -> Unit = {},
|
||||
onNonEmptyBlockBackspaceClicked: (String, Editable) -> Unit = { _, _ -> },
|
||||
onEmptyBlockBackspaceClicked: (String) -> Unit = {},
|
||||
onCheckboxClicked: (BlockView.Text.Checkbox) -> Unit = {},
|
||||
lifecycle: Lifecycle = BlockAdapterTest.TestLifecycle(),
|
||||
): BlockAdapter {
|
||||
return BlockAdapter(
|
||||
restore = LinkedList(),
|
||||
initialBlock = views,
|
||||
onNonEmptyBlockBackspaceClicked = { _, _ -> },
|
||||
onEmptyBlockBackspaceClicked = {},
|
||||
onNonEmptyBlockBackspaceClicked = onNonEmptyBlockBackspaceClicked,
|
||||
onEmptyBlockBackspaceClicked = onEmptyBlockBackspaceClicked,
|
||||
onSplitLineEnterClicked = onSplitLineEnterClicked,
|
||||
onSplitDescription = { _, _, _ -> },
|
||||
onTextChanged = onTextChanged,
|
||||
onCheckboxClicked = {},
|
||||
onCheckboxClicked = onCheckboxClicked,
|
||||
onTitleCheckboxClicked = onTitleCheckboxClicked,
|
||||
onFocusChanged = onFocusChanged,
|
||||
onSelectionChanged = { _, _ -> },
|
||||
onTextInputClicked = {},
|
||||
onPageIconClicked = {},
|
||||
onTogglePlaceholderClicked = {},
|
||||
onToggleClicked = {},
|
||||
onToggleClicked = onToggleClicked,
|
||||
onTextBlockTextChanged = {},
|
||||
onTitleBlockTextChanged = onTitleBlockTextChanged,
|
||||
onTitleTextInputClicked = {},
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package com.anytypeio.anytype.core_ui.uitests
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.testing.FragmentScenario
|
||||
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import com.anytypeio.anytype.test_utils.TestFragment
|
||||
import com.anytypeio.anytype.test_utils.utils.checkHasTextColor
|
||||
import com.anytypeio.anytype.test_utils.utils.checkIsDisplayed
|
||||
import com.anytypeio.anytype.test_utils.utils.onItemView
|
||||
import com.anytypeio.anytype.test_utils.utils.performClick
|
||||
import com.anytypeio.anytype.test_utils.utils.rVMatcher
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.assertEquals
|
||||
import com.anytypeio.anytype.test_utils.R as R_test
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(
|
||||
manifest = Config.NONE,
|
||||
sdk = [Build.VERSION_CODES.P],
|
||||
instrumentedPackages = [
|
||||
// required to access final members on androidx.loader.content.ModernAsyncTask
|
||||
"androidx.loader.content"
|
||||
]
|
||||
)
|
||||
class BlockAdapterToggleTest {
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
lateinit var scenario: FragmentScenario<TestFragment>
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context.setTheme(R.style.Theme_MaterialComponents)
|
||||
scenario = launchFragmentInContainer()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should intercept toggle click - when switching from read to edit mode`() {
|
||||
scenario.onFragment {
|
||||
|
||||
var triggeredTimes = 0
|
||||
|
||||
val recycler = givenRecycler(it)
|
||||
|
||||
val block = givenToggle()
|
||||
|
||||
val adapter = givenAdapter(
|
||||
views = listOf(block),
|
||||
onToggleClicked = { triggeredTimes++ }
|
||||
)
|
||||
|
||||
recycler.adapter = adapter
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
onItemView(0, R.id.toggle).checkIsDisplayed()
|
||||
onItemView(0, R.id.toggle).performClick()
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
actual = triggeredTimes,
|
||||
expected = 1
|
||||
)
|
||||
|
||||
adapter.updateWithDiffUtil(
|
||||
listOf(
|
||||
block.copy(
|
||||
mode = BlockView.Mode.EDIT
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
R_test.id.recycler.rVMatcher().apply {
|
||||
onItemView(0, R.id.toggle).performClick()
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
actual = triggeredTimes,
|
||||
expected = 2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun givenRecycler(it: Fragment): RecyclerView =
|
||||
it.view!!.findViewById<RecyclerView>(R_test.id.recycler).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
|
||||
private fun givenToggle() = BlockView.Text.Toggle(
|
||||
mode = BlockView.Mode.READ,
|
||||
text = MockDataFactory.randomString(),
|
||||
id = MockDataFactory.randomUuid(),
|
||||
isFocused = false
|
||||
)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.anytypeio.anytype.test_utils.utils.view_action
|
||||
|
||||
import android.view.View
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
|
||||
import org.hamcrest.Matcher
|
||||
|
||||
class ExtractViewAction <V: View> : ViewAction {
|
||||
|
||||
lateinit var view: V
|
||||
|
||||
override fun getConstraints(): Matcher<View> {
|
||||
return isAssignableFrom(View::class.java)
|
||||
}
|
||||
|
||||
override fun getDescription(): String {
|
||||
return "Text of the view"
|
||||
}
|
||||
|
||||
override fun perform(uiController: UiController, view: View) {
|
||||
this.view = view as V
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified V: View> ViewInteraction.extractView(): V {
|
||||
val viewAction = ExtractViewAction<V>()
|
||||
perform(viewAction)
|
||||
return viewAction.view
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue