1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

Editor | Feature | Table of Contents, indents + dnd (#2236)

* update table of contents items depth + test

* set untitled if header name is empty

* fix clicks on toc

Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
Konstantin Ivanov 2022-05-05 15:00:37 +03:00 committed by GitHub
parent 06d865a9dc
commit 6e5d0dc3d7
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 199 additions and 32 deletions

View file

@ -33,10 +33,6 @@ class TableOfContents(
fallback = { e -> itemView.onTouchEvent(e) }
)
init {
itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
}
fun bind(item: BlockView.TableOfContents, clicked: (ListenerType) -> Unit) {
cleanup()
selected.isSelected = item.isSelected
@ -45,6 +41,7 @@ class TableOfContents(
id = generateViewId()
setPadding(getPadding(header.depth), 0, 0, 0)
setName(header.name)
setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
setOnClickListener {
clicked.invoke(
ListenerType.TableOfContentsItem(
@ -53,10 +50,6 @@ class TableOfContents(
)
)
}
setOnLongClickListener {
clicked.invoke(ListenerType.LongClick(item.id))
true
}
}
container.addView(textview)
}

View file

@ -5,6 +5,7 @@ import android.graphics.Paint
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.databinding.TvTableOfContentsBinding
class TableOfContentsItemWidget @JvmOverloads constructor(
@ -23,6 +24,6 @@ class TableOfContentsItemWidget @JvmOverloads constructor(
}
fun setName(name: String) {
textView.text = name
textView.text = name.ifBlank { resources.getString(R.string.untitled) }
}
}

View file

@ -543,7 +543,6 @@ class DefaultBlockViewRenderer @Inject constructor(
result.add(
toc(
block = block,
indent = indent,
mode = mode,
selection = selection,
blocks = children
@ -1455,17 +1454,30 @@ class DefaultBlockViewRenderer @Inject constructor(
private fun toc(
block: Block,
blocks: List<Block>,
indent: Int,
mode: EditorMode,
selection: Set<Id>
): BlockView.TableOfContents {
val headers = blocks.filter { (it.content as? Content.Text)?.isHeader() ?: false }
var depth = 0
var isH1Present = false
var isH2Present = false
val items = mutableListOf<BlockView.TableOfContentsItem>()
headers.forEachIndexed { index, b ->
val content = b.content<Content.Text>()
if (content.style == Content.Text.Style.H1) {
depth = 0
var depth = 0
when (content.style) {
Content.Text.Style.H1 -> {
isH1Present = true
isH2Present = false
}
Content.Text.Style.H2 -> {
isH2Present = true
if (isH1Present) depth += 1
}
Content.Text.Style.H3 -> {
if (isH1Present) depth += 1
if (isH2Present) depth += 1
}
else -> {}
}
val item = BlockView.TableOfContentsItem(
id = b.id,
@ -1473,24 +1485,6 @@ class DefaultBlockViewRenderer @Inject constructor(
depth = depth
)
items.add(item)
val next = if (index + 1 < headers.size) {
headers[index + 1]
} else {
null
}
if (next != null) {
val contentNext = next.content<Content.Text>()
if (content.style == Content.Text.Style.H1 && (
contentNext.style == Content.Text.Style.H2
|| contentNext.style == Content.Text.Style.H3
)
) {
depth += 1
}
if (content.style == Content.Text.Style.H2 && contentNext.style == Content.Text.Style.H3) {
depth += 1
}
}
}
val toc = BlockView.TableOfContents(

View file

@ -597,4 +597,183 @@ class EditorTableOfContentsBlockTest : EditorPresentationTestSetup() {
assertEquals(expected, result)
}
@Test
fun `should have proper depth for headers`() {
val title = MockTypicalDocumentFactory.title
val header = MockTypicalDocumentFactory.header
val blockHeaderOne1 = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.Text(
text = MockDataFactory.randomString(),
marks = emptyList(),
style = Block.Content.Text.Style.H1
),
children = emptyList()
)
val blockHeaderTwo1 = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.Text(
text = "",
marks = emptyList(),
style = Block.Content.Text.Style.H2
),
children = emptyList()
)
val blockHeaderTwo2 = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.Text(
text = "",
marks = emptyList(),
style = Block.Content.Text.Style.H2
),
children = emptyList()
)
val blockHeaderThree = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.Text(
text = "",
marks = emptyList(),
style = Block.Content.Text.Style.H3
),
children = emptyList()
)
val blockHeaderThree2 = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.Text(
text = "",
marks = emptyList(),
style = Block.Content.Text.Style.H3
),
children = emptyList()
)
val blockToC = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.TableOfContents,
children = emptyList()
)
val page = Block(
id = root,
fields = Block.Fields(emptyMap()),
content = Block.Content.Smart(SmartBlockType.PAGE),
children = listOf(
header.id,
blockToC.id,
blockHeaderOne1.id,
blockHeaderTwo1.id,
blockHeaderThree.id,
blockHeaderTwo2.id,
blockHeaderThree2.id
)
)
val doc = listOf(
page, header, title,
blockToC,
blockHeaderOne1,
blockHeaderTwo1,
blockHeaderThree,
blockHeaderTwo2,
blockHeaderThree2
)
stubInterceptEvents()
stubInterceptThreadStatus()
stubGetObjectTypes(objectTypes = listOf())
stubOpenDocument(
document = doc,
details = Block.Details(),
relations = listOf()
)
stubUpdateText()
val vm = buildViewModel()
//TESTING
vm.apply { onStart(root) }
val expected = ViewState.Success(
blocks = listOf(
BlockView.Title.Basic(
id = title.id,
isFocused = false,
text = title.content<TXT>().text,
mode = BlockView.Mode.EDIT
),
BlockView.TableOfContents(
id = blockToC.id,
backgroundColor = blockToC.backgroundColor,
isSelected = false,
items = listOf(
BlockView.TableOfContentsItem(
id = blockHeaderOne1.id,
name = blockHeaderOne1.content.asText().text,
depth = 0
),
BlockView.TableOfContentsItem(
id = blockHeaderTwo1.id,
name = blockHeaderTwo1.content.asText().text,
depth = 1
),
BlockView.TableOfContentsItem(
id = blockHeaderThree.id,
name = blockHeaderThree.content.asText().text,
depth = 2
),
BlockView.TableOfContentsItem(
id = blockHeaderTwo2.id,
name = blockHeaderTwo2.content.asText().text,
depth = 1
),
BlockView.TableOfContentsItem(
id = blockHeaderThree2.id,
name = blockHeaderThree2.content.asText().text,
depth = 2
)
)
),
BlockView.Text.Header.One(
id = blockHeaderOne1.id,
indent = 0,
text = blockHeaderOne1.content.asText().text
),
BlockView.Text.Header.Two(
id = blockHeaderTwo1.id,
indent = 0,
text = blockHeaderTwo1.content.asText().text
),
BlockView.Text.Header.Three(
id = blockHeaderThree.id,
indent = 0,
text = blockHeaderThree.content.asText().text
),
BlockView.Text.Header.Two(
id = blockHeaderTwo2.id,
indent = 0,
text = blockHeaderTwo2.content.asText().text
),
BlockView.Text.Header.Three(
id = blockHeaderThree2.id,
indent = 0,
text = blockHeaderThree2.content.asText().text
)
)
)
val result = vm.state.test().value()
assertEquals(expected, result)
}
}