From 9eeea1e722ca81c14a0b8d43f4a697a3409d0df8 Mon Sep 17 00:00:00 2001 From: Konstantin Ivanov <54908981+konstantiniiv@users.noreply.github.com> Date: Thu, 5 May 2022 09:25:52 +0300 Subject: [PATCH] Editor | Feature | Code block, design and clicks (#2231) * code block update * code block, holder design * block list extension + tests * only background style menu for text blocks * code block fixes * update gradle * rename fun * back android 7 fix Co-authored-by: konstantiniiv --- build.gradle | 2 +- .../anytype/core_models/ext/BlockExt.kt | 7 +- .../features/editor/holders/other/Code.kt | 24 ++-- .../res/layout/item_block_code_snippet.xml | 56 +++++---- core-ui/src/main/res/values/styles.xml | 41 ++++--- .../anytype/domain/ext/BlockExtensionTest.kt | 107 ++++++++++++++++++ .../presentation/editor/EditorViewModel.kt | 3 +- 7 files changed, 176 insertions(+), 64 deletions(-) diff --git a/build.gradle b/build.gradle index 339cb30049..eb01b7186b 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.1.1' + classpath 'com.android.tools.build:gradle:7.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" classpath 'com.google.gms:google-services:4.3.10' diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/ext/BlockExt.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/ext/BlockExt.kt index 24a8e2f772..e851ad81e8 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/ext/BlockExt.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/ext/BlockExt.kt @@ -271,4 +271,9 @@ fun Document.updateTextContent( fun List.getChildrenIdsList(parent: Id): List { val root = this.firstOrNull { it.id == parent } return root?.children ?: emptyList() -} \ No newline at end of file +} + +fun List.isAllTextAndNoneCodeBlocks(): Boolean = + all { block -> + block.content is Content.Text && block.content.style != Content.Text.Style.CODE_SNIPPET + } \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Code.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Code.kt index d82f77333e..ff60528e6f 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Code.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Code.kt @@ -1,16 +1,15 @@ package com.anytypeio.anytype.core_ui.features.editor.holders.other -import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.ColorDrawable import android.os.Build import android.os.Build.VERSION_CODES.N import android.os.Build.VERSION_CODES.N_MR1 import android.text.Editable import android.view.View import android.view.inputmethod.InputMethodManager -import android.widget.FrameLayout -import android.widget.LinearLayout import android.widget.TextView import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.RecyclerView import com.anytypeio.anytype.core_ui.R import com.anytypeio.anytype.core_ui.databinding.ItemBlockCodeSnippetBinding import com.anytypeio.anytype.core_ui.extensions.lighter @@ -38,15 +37,13 @@ class Code(val binding: ItemBlockCodeSnippetBinding) : BlockViewHolder(binding.r get() = itemView val content: CodeTextInputWidget get() = binding.snippet - val container: LinearLayout - get() = binding.snippetContainer val editorTouchProcessor = EditorTouchProcessor( fallback = { e -> itemView.onTouchEvent(e) } ) init { - itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) } + content.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) } } fun bind( @@ -97,7 +94,7 @@ class Code(val binding: ItemBlockCodeSnippetBinding) : BlockViewHolder(binding.r content.selectionWatcher = { onSelectionChanged(item.id, it) } } - itemView.setOnClickListener { + content.setOnClickListener { onTextInputClicked(item.id) if (Build.VERSION.SDK_INT == N || Build.VERSION.SDK_INT == N_MR1) { content.context.imm().showSoftInput(content, InputMethodManager.SHOW_FORCED) @@ -118,11 +115,8 @@ class Code(val binding: ItemBlockCodeSnippetBinding) : BlockViewHolder(binding.r } fun indentize(item: BlockView.Indentable) { - binding.snippetContainer.updateLayoutParams { - apply { - val extra = item.indent * dimen(R.dimen.indent) - leftMargin = 0 + extra - } + root.updateLayoutParams { + leftMargin = item.indent * dimen(R.dimen.indent) } } @@ -174,7 +168,7 @@ class Code(val binding: ItemBlockCodeSnippetBinding) : BlockViewHolder(binding.r } fun select(item: BlockView.Selectable) { - root.isSelected = item.isSelected + binding.selected.isSelected = item.isSelected } fun setFocus(item: Focusable) { @@ -206,11 +200,11 @@ class Code(val binding: ItemBlockCodeSnippetBinding) : BlockViewHolder(binding.r Timber.d("Setting background color: $color") val value = ThemeColor.values().find { value -> value.title == color } if (value != null && value != ThemeColor.DEFAULT) { - (container.background as? GradientDrawable)?.setColor(root.resources.lighter(value, 0)) + (root.background as? ColorDrawable)?.color = root.resources.lighter(value, 0) } else { val defaultBackgroundColor = content.context.resources.getColor(R.color.shape_tertiary, null) - (container.background as? GradientDrawable)?.setColor(defaultBackgroundColor) + (root.background as? ColorDrawable)?.color = defaultBackgroundColor } } diff --git a/core-ui/src/main/res/layout/item_block_code_snippet.xml b/core-ui/src/main/res/layout/item_block_code_snippet.xml index 43a3f0015d..e53f99677e 100644 --- a/core-ui/src/main/res/layout/item_block_code_snippet.xml +++ b/core-ui/src/main/res/layout/item_block_code_snippet.xml @@ -1,58 +1,56 @@ + android:background="@color/shape_tertiary"> + android:orientation="vertical"> + android:layout_height="wrap_content" + android:fillViewport="true" + android:overScrollMode="never" + android:scrollbars="none"> - + + + \ No newline at end of file diff --git a/core-ui/src/main/res/values/styles.xml b/core-ui/src/main/res/values/styles.xml index b441acef80..8a7fd99bc1 100644 --- a/core-ui/src/main/res/values/styles.xml +++ b/core-ui/src/main/res/values/styles.xml @@ -148,23 +148,6 @@ 4dp - - - - + + + + + + + \ No newline at end of file diff --git a/domain/src/test/java/com/anytypeio/anytype/domain/ext/BlockExtensionTest.kt b/domain/src/test/java/com/anytypeio/anytype/domain/ext/BlockExtensionTest.kt index 09e375f564..3ce84f70b1 100644 --- a/domain/src/test/java/com/anytypeio/anytype/domain/ext/BlockExtensionTest.kt +++ b/domain/src/test/java/com/anytypeio/anytype/domain/ext/BlockExtensionTest.kt @@ -5,7 +5,9 @@ import com.anytypeio.anytype.domain.common.MockDataFactory import com.anytypeio.anytype.core_models.ext.* import org.junit.Test import kotlin.test.assertEquals +import kotlin.test.assertFalse import kotlin.test.assertNull +import kotlin.test.assertTrue class BlockExtensionTest { @@ -1015,4 +1017,109 @@ class BlockExtensionTest { assertNull(result) } + + @Test + fun `should return true on all non code and texted blocks`() { + + val root = MockDataFactory.randomUuid() + + val a = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.Text( + text = MockDataFactory.randomString(), + marks = emptyList(), + style = Block.Content.Text.Style.NUMBERED + ) + ) + + val b = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.Text( + text = MockDataFactory.randomString(), + marks = emptyList(), + style = (Block.Content.Text.Style.P) + ) + ) + + val document = listOf(a, b) + + val result = document.isAllTextAndNoneCodeBlocks() + + assertTrue(result) + } + + @Test + fun `should return false on texted blocks and code block`() { + + val root = MockDataFactory.randomUuid() + + val a = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.Text( + text = MockDataFactory.randomString(), + marks = emptyList(), + style = Block.Content.Text.Style.NUMBERED + ) + ) + + val b = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.Text( + text = MockDataFactory.randomString(), + marks = emptyList(), + style = (Block.Content.Text.Style.P) + ) + ) + + val c = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.Text( + text = MockDataFactory.randomString(), + marks = emptyList(), + style = (Block.Content.Text.Style.CODE_SNIPPET) + ) + ) + + val document = listOf(a, b, c) + + val result = document.isAllTextAndNoneCodeBlocks() + + assertFalse(result) + } + + @Test + fun `should return false on media blocks`() { + + val root = MockDataFactory.randomUuid() + + val a = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.File() + ) + + val b = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.File() + ) + + val document = listOf(a, b) + + val result = document.isAllTextAndNoneCodeBlocks() + + assertFalse(result) + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt index a7e2828679..2ed1e2d68f 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt @@ -29,6 +29,7 @@ import com.anytypeio.anytype.core_models.ext.asMap import com.anytypeio.anytype.core_models.ext.content import com.anytypeio.anytype.core_models.ext.descendants import com.anytypeio.anytype.core_models.ext.getFirstLinkOrObjectMarkupParam +import com.anytypeio.anytype.core_models.ext.isAllTextAndNoneCodeBlocks import com.anytypeio.anytype.core_models.ext.parents import com.anytypeio.anytype.core_models.ext.process import com.anytypeio.anytype.core_models.ext.sortByType @@ -2339,7 +2340,7 @@ class EditorViewModel( private fun proceedWithMultiStyleToolbarEvent() { val selected = blocks.filter { currentSelection().contains(it.id) } - val isAllSelectedText = selected.all { it.content is Content.Text } + val isAllSelectedText = selected.isAllTextAndNoneCodeBlocks() mode = EditorMode.Styling.Multi(currentSelection()) if (isAllSelectedText) { controlPanelInteractor.onEvent(