diff --git a/app/src/main/assets/syntax/color_scheme.json b/app/src/main/assets/syntax/color_scheme.json index 3ffb343ffd..02e0f2dd90 100644 --- a/app/src/main/assets/syntax/color_scheme.json +++ b/app/src/main/assets/syntax/color_scheme.json @@ -4,7 +4,7 @@ "function": "#6f42c1", "number": "#0366d6", "boolean": "#0366d6", - "operator": "#0366d6", + "operator": "#d73a49", "string": "#05264c", "property": "#0366d6" } \ No newline at end of file diff --git a/app/src/main/assets/syntax/generic.json b/app/src/main/assets/syntax/generic.json new file mode 100644 index 0000000000..f010285967 --- /dev/null +++ b/app/src/main/assets/syntax/generic.json @@ -0,0 +1,38 @@ +{ + "keywords": [ + { + "pattern": "\\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\\b", + "color": "#d73a49", + "key": "keyword" + } + ], + "operators": [ + { + "pattern": "(^|[^.])(?:<<=?|>>>?=?|->|--|\\+\\+|&&|\\|\\||::|[?:~]|[-+*/%&|^!=<>]=?)", + "color": "#d73a49", + "key": "operator" + } + ], + "other": [ + { + "pattern": "(^|[^\\\\])#.*", + "color": "#6a737d", + "key": "comment" + }, + { + "pattern": "(?:\\b(?=\\d)|\\B(?=\\.))(?:0[bo])?(?:(?:\\d|0x[\\da-f])[\\da-f]*\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?j?\\b", + "color": "#0366d6", + "key": "number" + }, + { + "pattern": "(?:[rub]|rb|br)?(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1", + "color": "#05264c", + "key": "string" + }, + { + "pattern": "(\\/\\/).*", + "color": "#6a737d", + "key": "comment" + } + ] +} \ No newline at end of file diff --git a/app/src/main/assets/syntax/go.json b/app/src/main/assets/syntax/go.json index b49f3e0130..73da414b3c 100644 --- a/app/src/main/assets/syntax/go.json +++ b/app/src/main/assets/syntax/go.json @@ -9,7 +9,7 @@ "operators": [ { "pattern": "[*\\/%^!=]=?|\\+[=+]?|-[=-]?|\\|[=|]?|&(?:=|&|\\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\\.\\.\\.", - "color": "#0366d6", + "color": "#d73a49", "key": "operator" } ], diff --git a/app/src/main/assets/syntax/java.json b/app/src/main/assets/syntax/java.json index b545d7aec9..a384342b44 100644 --- a/app/src/main/assets/syntax/java.json +++ b/app/src/main/assets/syntax/java.json @@ -6,12 +6,18 @@ "key": "keyword" } ], - "operators": [], + "operators": [ + { + "pattern": "(^|[^.])(?:<<=?|>>>?=?|->|--|\\+\\+|&&|\\|\\||::|[?:~]|[-+*/%&|^!=<>]=?)", + "color": "#d73a49", + "key": "operator" + } + ], "other": [ { - "pattern": "\\(|\\)|\\[|\\]|:|;|\\.|\\||;|\\&|\\{|\\}", - "color": "#b71c1c", - "key": "" + "pattern": "\\w+(?=\\s*\\()", + "color": "#6f42c1", + "key": "function" }, { "pattern": "@\\w+", @@ -19,19 +25,24 @@ "key": "annotation" }, { - "pattern": "\\b\\d+[\\.]?\\d*([eE]\\-?\\d+)?[lLdDfF]?\\b|\\b0x[a-fA-F\\d]+\\b", - "color": "#f4511e", - "key:": "" + "pattern": "\\b0b[01][01_]*L?\\b|\\b0x[\\da-f_]*\\.?[\\da-f_p+-]+\\b|(?:\\b\\d[\\d_]*\\.?[\\d_]*|\\B\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[dfl]?", + "color": "#0366d6", + "key": "number" }, { - "pattern": "(\\\"(.*)\\\"|\\\"(.*)\\\")", - "color": "#ff0000", - "key": "" - }, - { - "pattern": "\\b[A-Z](?:\\w*[a-z]\\w*)?\\b", + "pattern": "\\b[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])", "color": "#6e5494", "key": "class" + }, + { + "pattern": "(?:[rub]|rb|br)?(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1", + "color": "#05264c", + "key": "string" + }, + { + "pattern": "(\\/\\/).*", + "color": "#6a737d", + "key": "comment" } ] } \ No newline at end of file diff --git a/app/src/main/assets/syntax/kotlin.json b/app/src/main/assets/syntax/kotlin.json index d75aaaff99..2f246c6ba4 100644 --- a/app/src/main/assets/syntax/kotlin.json +++ b/app/src/main/assets/syntax/kotlin.json @@ -1,37 +1,48 @@ { "keywords": [ - { - "pattern": "\\w+(?=\\s*\\()", - "color": "#6f42c1", - "key": "function" - }, { "pattern": "(^|[^.])\\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\\b", "color": "#d73a49", "key": "keyword" } ], - "operators": [], + "operators": [ + { + "pattern": "\\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\\/*%<>]=?|[?:]:?|\\.\\.|&&|\\|\\||\\b(?:and|inv|or|shl|shr|ushr|xor)\\b", + "color": "#d73a49", + "key": "operator" + } + ], "other": [ { - "pattern": "@\\w+", + "pattern": "\\w+(?=\\s*\\()", + "color": "#6f42c1", + "key": "function" + }, + { + "pattern": "\\B@(?:\\w+:)?(?:[A-Z]\\w*|\\[[^\\]]+\\])", "color": "#b87333", "key": "annotation" }, { - "pattern": "\\b\\d+[\\.]?\\d*([eE]\\-?\\d+)?[lLdDfF]?\\b|\\b0x[a-fA-F\\d]+\\b", + "pattern": "\\b(?:0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\\d+(?:_\\d+)*(?:\\.\\d+(?:_\\d+)*)?(?:[eE][+-]?\\d+(?:_\\d+)*)?[fFL]?)\\b", "color": "#0366d6", "key": "number" }, - { - "pattern": "(\\\"(.*)\\\"|\\\"(.*)\\\")", - "color": "#ff0000", - "key": "" - }, { "pattern": "\\b[A-Z](?:\\w*[a-z]\\w*)?\\b", "color": "#6e5494", "key": "class" + }, + { + "pattern": "(?:[rub]|rb|br)?(\"|')(?:\\\\.|(?!\\1)[^\\\\\\r\\n])*\\1", + "color": "#05264c", + "key": "string" + }, + { + "pattern": "(\\/\\/).*", + "color": "#6a737d", + "key": "comment" } ] } \ No newline at end of file diff --git a/app/src/main/assets/syntax/languages.json b/app/src/main/assets/syntax/languages.json new file mode 100644 index 0000000000..69ab05d6c7 --- /dev/null +++ b/app/src/main/assets/syntax/languages.json @@ -0,0 +1,67 @@ +{ + "abap": "ABAP", + "arduino": "Arduino", + "bash": "Bash", + "basic": "BASIC", + "c": "C", + "csharp": "C#", + "cpp": "C++", + "clojure": "Clojure", + "coffeescript": "CoffeeScript", + "css": "CSS", + "dart": "Dart", + "diff": "Diff", + "docker": "Docker", + "elixir": "Elixir", + "elm": "Elm", + "erlang": "Erlang", + "flow": "Flow", + "fortran": "Fortran", + "fsharp": "F#", + "gherkin": "Gherkin", + "graphql": "GraphQL", + "groovy": "Groovy", + "go": "Go", + "haskell": "Haskell", + "html": "HTML", + "json": "JSON", + "javascript": "JavaScript", + "java": "Java", + "kotlin": "Kotlin", + "latex": "LaTeX", + "less": "Less", + "lisp": "Lisp", + "livescript": "LiveScript", + "lua": "Lua", + "markup": "Markup", + "markdown": "Markdown", + "makefile": "Makefile", + "matlab": "MATLAB", + "nginx": "Nginx", + "objc": "Objective-C", + "ocaml": "OCaml", + "pascal": "Pascal", + "perl": "Perl", + "php": "PHP", + "powershell": "Power Shell", + "prolog": "Prolog", + "python": "Python", + "reason": "Reason", + "ruby": "Ruby", + "rust": "Rust", + "sass": "Sass", + "scala": "Scala", + "scheme": "Scheme", + "scss": "SСSS", + "shell": "Shell", + "sql": "SQL", + "swift": "Swift", + "typescript": "TypeScript", + "vbnet": "Vb.Net", + "verilog": "Verilog", + "vhdl": "VHDL", + "vb": "Visual Basic", + "wasm": "WebAssembly", + "xml": "XML", + "yaml": "YAML" +} \ No newline at end of file diff --git a/app/src/main/assets/syntax/python.json b/app/src/main/assets/syntax/python.json index b37e7a1b8b..cc3bfe0070 100644 --- a/app/src/main/assets/syntax/python.json +++ b/app/src/main/assets/syntax/python.json @@ -9,8 +9,8 @@ "operators": [ { "pattern": "[-+%=]=?|!=|\\*\\*?=?|\\/\\/?=?|<[<=>]?|>[=>]?|[&|^~]", - "color": "#0366d6", - "key": "keyword" + "color": "#d73a49", + "key": "operator" } ], "other": [ diff --git a/app/src/main/assets/syntax/typescript.json b/app/src/main/assets/syntax/typescript.json index 1be07c2710..e7e4b7768b 100644 --- a/app/src/main/assets/syntax/typescript.json +++ b/app/src/main/assets/syntax/typescript.json @@ -14,8 +14,8 @@ "operators": [ { "pattern": "--|\\+\\+|\\*\\*=?|=>|&&=?|\\|\\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\\.{3}|\\?\\?=?|\\?\\.?|[~:]", - "color": "#bd2c00", - "key": "keyword" + "color": "#d73a49", + "key": "operator" } ], "other": [ diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/PageDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/PageDI.kt index c199eae860..0cb1c1af63 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/PageDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/PageDI.kt @@ -167,6 +167,7 @@ object EditorSessionModule { updateTitle: UpdateTitle, updateText: UpdateText, uploadBlock: UploadBlock, + updateFields: UpdateFields, updateAlignment: UpdateAlignment, setupBookmark: SetupBookmark, turnIntoDocument: TurnIntoDocument, @@ -209,7 +210,8 @@ object EditorSessionModule { move = move, paste = paste, copy = copy, - analytics = analytics + analytics = analytics, + updateFields = updateFields ) } @@ -520,4 +522,11 @@ object EditorUseCaseModule { ): TurnIntoDocument = TurnIntoDocument( repo = repo ) + + @JvmStatic + @Provides + @PerScreen + fun provideUpdateFieldsUseCase( + repo: BlockRepository + ): UpdateFields = UpdateFields(repo) } \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/ui/page/PageFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/page/PageFragment.kt index 2f2997e074..9afdfd47d3 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/page/PageFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/page/PageFragment.kt @@ -60,6 +60,7 @@ import com.anytypeio.anytype.core_utils.ext.PopupExtensions.calculateRectInWindo import com.anytypeio.anytype.di.common.componentManager import com.anytypeio.anytype.domain.block.model.Block import com.anytypeio.anytype.domain.block.model.Block.Content.Text +import com.anytypeio.anytype.domain.common.Id import com.anytypeio.anytype.domain.ext.getFirstLinkMarkupParam import com.anytypeio.anytype.domain.ext.getSubstring import com.anytypeio.anytype.emojifier.Emojifier @@ -98,6 +99,7 @@ open class PageFragment : OnFragmentInteractionListener, AddBlockFragment.AddBlockActionReceiver, TurnIntoActionReceiver, + SelectProgrammingLanguageReceiver, ClipboardInterceptor, PickiTCallbacks { @@ -730,6 +732,10 @@ open class PageFragment : is Command.ClearSearchInput -> { searchToolbar.clear() } + is Command.Dialog.SelectLanguage -> { + SelectProgrammingLanguageFragment.new(command.target) + .show(childFragmentManager, null) + } } } } @@ -1179,6 +1185,11 @@ open class PageFragment : vm.navigateToDesktop() } + override fun onLanguageSelected(target: Id, key: String) { + Timber.d("key: $key") + vm.onSelectProgrammingLanguageClicked(target, key) + } + //------------ End of Anytype Custom Context Menu ------------ companion object { diff --git a/app/src/main/java/com/anytypeio/anytype/ui/page/modals/SelectProgrammingLanguageFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/page/modals/SelectProgrammingLanguageFragment.kt new file mode 100644 index 0000000000..386cb004bd --- /dev/null +++ b/app/src/main/java/com/anytypeio/anytype/ui/page/modals/SelectProgrammingLanguageFragment.kt @@ -0,0 +1,74 @@ +package com.anytypeio.anytype.ui.page.modals + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import androidx.core.os.bundleOf +import androidx.recyclerview.widget.LinearLayoutManager +import com.anytypeio.anytype.R +import com.anytypeio.anytype.core_ui.extensions.color +import com.anytypeio.anytype.core_ui.features.page.modal.SelectProgrammingLanguageAdapter +import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment +import com.anytypeio.anytype.domain.common.Id +import com.anytypeio.anytype.library_syntax_highlighter.obtainLanguages +import com.google.android.material.bottomsheet.BottomSheetDialog +import kotlinx.android.synthetic.main.fragment_select_programming_language.* +import timber.log.Timber + +class SelectProgrammingLanguageFragment : BaseBottomSheetFragment() { + + private val selectLangAdapter by lazy { + SelectProgrammingLanguageAdapter( + items = requireContext().obtainLanguages() + ) { lang -> + val parent = parentFragment + check(parent is SelectProgrammingLanguageReceiver) + parent.onLanguageSelected(target, lang) + dismiss() + } + } + + private val target: String + get() = requireArguments() + .getString(ARG_TARGET) + ?: throw IllegalStateException(MISSING_TARGET_ERROR) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? = inflater.inflate(R.layout.fragment_select_programming_language, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + Timber.d("onViewCreated") + dialog?.setOnShowListener { dg -> + val bottomSheet = (dg as? BottomSheetDialog)?.findViewById( + com.google.android.material.R.id.design_bottom_sheet + ) + bottomSheet?.setBackgroundColor(requireContext().color(android.R.color.transparent)) + } + recycler.apply { + layoutManager = LinearLayoutManager(context) + adapter = selectLangAdapter + } + } + + override fun injectDependencies() {} + override fun releaseDependencies() {} + + companion object { + fun new(target: Id) = SelectProgrammingLanguageFragment().apply { + arguments = bundleOf(ARG_TARGET to target) + } + + private const val ARG_TARGET = "arg.select_language.target" + private const val MISSING_TARGET_ERROR = "Target missing in args" + } +} + +interface SelectProgrammingLanguageReceiver { + fun onLanguageSelected(target: Id, key: String) +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_select_programming_language.xml b/app/src/main/res/layout/fragment_select_programming_language.xml new file mode 100644 index 0000000000..316aa233b8 --- /dev/null +++ b/app/src/main/res/layout/fragment_select_programming_language.xml @@ -0,0 +1,12 @@ + + + + + \ 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 7b52646855..34f57b45cf 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 @@ -9,6 +9,7 @@ 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 com.anytypeio.anytype.core_ui.R import com.anytypeio.anytype.core_ui.common.Focusable @@ -22,11 +23,14 @@ import com.anytypeio.anytype.core_ui.widgets.text.CodeTextInputWidget import com.anytypeio.anytype.core_ui.widgets.text.EditorLongClickListener import com.anytypeio.anytype.core_utils.ext.dimen import com.anytypeio.anytype.core_utils.ext.imm +import com.anytypeio.anytype.library_syntax_highlighter.Syntaxes import kotlinx.android.synthetic.main.item_block_code_snippet.view.* import timber.log.Timber class Code(view: View) : BlockViewHolder(view) { + val menu: TextView + get() = itemView.code_menu val root: View get() = itemView val content: CodeTextInputWidget @@ -92,6 +96,18 @@ class Code(view: View) : BlockViewHolder(view) { content.setOnClickListener { onTextInputClicked(item.id) } + + menu.setOnClickListener { + clicked(ListenerType.Code.SelectLanguage(item.id)) + } + + if (!item.lang.isNullOrEmpty()) { + content.setupSyntax(item.lang) + menu.text = item.lang.capitalize() + } else { + content.setupSyntax(Syntaxes.GENERIC) + menu.setText(R.string.block_code_menu_title) + } } fun indentize(item: BlockView.Indentable) { diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/BlockView.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/BlockView.kt index 83b0f807d9..0dd1154016 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/BlockView.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/BlockView.kt @@ -472,7 +472,8 @@ sealed class BlockView : ViewType, Parcelable { override val isSelected: Boolean = false, override val color: String? = null, override val backgroundColor: String? = null, - override val indent: Int = 0 + override val indent: Int = 0, + val lang: String? = null ) : BlockView(), Permission, Selectable, Focusable, Indentable, TextSupport { override fun getViewType() = HOLDER_CODE_SNIPPET } diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/ListenerType.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/ListenerType.kt index 4cc12a7771..ed04a8dc53 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/ListenerType.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/ListenerType.kt @@ -22,21 +22,25 @@ sealed class ListenerType { data class Error(val target: String) : Picture() } - sealed class Video: ListenerType() { + sealed class Video : ListenerType() { data class View(val target: String) : Video() data class Placeholder(val target: String) : Video() data class Upload(val target: String) : Video() data class Error(val target: String) : Video() } + sealed class Code : ListenerType() { + data class SelectLanguage(val target: String) : Code() + } + data class LongClick(val target: String, val dimensions: BlockDimensions) : ListenerType() data class EditableBlock(val target: String) : ListenerType() object TitleBlock : ListenerType() - data class Page(val target: String): ListenerType() + data class Page(val target: String) : ListenerType() - data class Mention(val target: String): ListenerType() + data class Mention(val target: String) : ListenerType() data class DividerClick(val target: String) : ListenerType() } \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/modal/SelectProgrammingLanguageAdapter.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/modal/SelectProgrammingLanguageAdapter.kt new file mode 100644 index 0000000000..dfbb353b37 --- /dev/null +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/page/modal/SelectProgrammingLanguageAdapter.kt @@ -0,0 +1,42 @@ +package com.anytypeio.anytype.core_ui.features.page.modal + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.anytypeio.anytype.core_ui.R +import com.anytypeio.anytype.core_ui.features.page.modal.SelectProgrammingLanguageAdapter.Holder +import kotlinx.android.synthetic.main.item_select_programming_language.view.* + +class SelectProgrammingLanguageAdapter( + private val items: List>, + private val onLangSelected: (String) -> Unit +) : RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val inflater = LayoutInflater.from(parent.context) + return Holder( + view = inflater.inflate( + R.layout.item_select_programming_language, + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val (key, value) = items[position] + holder.bind(value) { onLangSelected(key) } + } + + override fun getItemCount(): Int = items.size + + class Holder(view: View) : RecyclerView.ViewHolder(view) { + val lang: TextView = itemView.lang + fun bind(value: String, onClick: () -> Unit) { + lang.text = value + itemView.setOnClickListener { onClick() } + } + } +} \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/CodeTextInputWidget.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/CodeTextInputWidget.kt index 596baac8d0..5590772421 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/CodeTextInputWidget.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/text/CodeTextInputWidget.kt @@ -103,4 +103,19 @@ class CodeTextInputWidget : AppCompatEditText, SyntaxHighlighter { } super.onSelectionChanged(selStart, selEnd) } + + override fun setupSyntax(lang: String?) { + if (lang == null) { + rules.clear() + clearHighlights() + } else { + val result = context.obtainSyntaxRules(lang) + if (result.isEmpty()) { + addRules(context.obtainGenericSyntaxRules()) + } else { + addRules(result) + } + highlight() + } + } } \ No newline at end of file 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 e656fb9ec1..7206912a53 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 @@ -5,25 +5,25 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:background="@drawable/item_block_code_multi_select_mode_selector" - android:paddingTop="6dp" android:layout_marginTop="1dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="1dp" - android:paddingBottom="6dp" + android:background="@drawable/item_block_code_multi_select_mode_selector" android:paddingStart="12dp" - android:paddingEnd="12dp"> + android:paddingTop="6dp" + android:paddingEnd="12dp" + android:paddingBottom="6dp"> + android:background="@drawable/item_block_code_multi_select_unselected" + android:orientation="vertical" + android:paddingStart="20dp" + android:paddingEnd="20dp"> - + android:layout_height="wrap_content"> + + + \ No newline at end of file diff --git a/core-ui/src/main/res/layout/item_select_programming_language.xml b/core-ui/src/main/res/layout/item_select_programming_language.xml new file mode 100644 index 0000000000..96a72d6c16 --- /dev/null +++ b/core-ui/src/main/res/layout/item_select_programming_language.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/model/CommandEntity.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/model/CommandEntity.kt index b881dd7ebe..bd07fc6ec3 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/model/CommandEntity.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/model/CommandEntity.kt @@ -168,4 +168,9 @@ class CommandEntity { val targets: List, val style: BlockEntity.Content.Divider.Style ) + + data class SetFields( + val context: String, + val fields: List> + ) } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt index f1dd82227c..f596139368 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt @@ -3,6 +3,8 @@ package com.anytypeio.anytype.data.auth.repo.block import com.anytypeio.anytype.data.auth.exception.BackwardCompatilityNotSupportedException import com.anytypeio.anytype.data.auth.mapper.toDomain import com.anytypeio.anytype.data.auth.mapper.toEntity +import com.anytypeio.anytype.data.auth.model.BlockEntity +import com.anytypeio.anytype.data.auth.model.CommandEntity import com.anytypeio.anytype.data.auth.model.PositionEntity import com.anytypeio.anytype.domain.base.Result import com.anytypeio.anytype.domain.block.model.Command @@ -34,7 +36,8 @@ class BlockDataRepository( Result.Failure(Error.BackwardCompatibility) } - override suspend fun openProfile(id: String): Payload = factory.remote.openProfile(id).toDomain() + override suspend fun openProfile(id: String): Payload = + factory.remote.openProfile(id).toDomain() override suspend fun closeDashboard(id: String) { factory.remote.closeDashboard(id) @@ -42,7 +45,7 @@ class BlockDataRepository( override suspend fun updateAlignment( command: Command.UpdateAlignment - ) : Payload = factory.remote.updateAlignment(command.toEntity()).toDomain() + ): Payload = factory.remote.updateAlignment(command.toEntity()).toDomain() override suspend fun createPage(parentId: String, emoji: String?) = factory.remote.createPage(parentId, emoji) @@ -61,7 +64,7 @@ class BlockDataRepository( override suspend fun updateTextStyle( command: Command.UpdateStyle - ) : Payload = factory.remote.updateTextStyle(command.toEntity()).toDomain() + ): Payload = factory.remote.updateTextStyle(command.toEntity()).toDomain() override suspend fun updateTextColor( command: Command.UpdateTextColor @@ -144,11 +147,11 @@ class BlockDataRepository( override suspend fun undo( command: Command.Undo - ) : Payload = factory.remote.undo(command.toEntity()).toDomain() + ): Payload = factory.remote.undo(command.toEntity()).toDomain() override suspend fun redo( command: Command.Redo - ) : Payload = factory.remote.redo(command.toEntity()).toDomain() + ): Payload = factory.remote.redo(command.toEntity()).toDomain() override suspend fun archiveDocument( command: Command.ArchiveDocument @@ -190,6 +193,18 @@ class BlockDataRepository( position = PositionEntity.valueOf(position.name) ).toDomain() - override suspend fun updateDivider(command: Command.UpdateDivider): Payload = - factory.remote.updateDivider(command = command.toEntity()).toDomain() + override suspend fun updateDivider( + command: Command.UpdateDivider + ): Payload = factory.remote.updateDivider(command = command.toEntity()).toDomain() + + override suspend fun setFields( + command: Command.SetFields + ): Payload = factory.remote.setFields( + command = CommandEntity.SetFields( + context = command.context, + fields = command.fields.map { (id, fields) -> + id to BlockEntity.Fields(fields.map.toMutableMap()) + } + ) + ).toDomain() } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataStore.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataStore.kt index 523517d91f..975bcca029 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataStore.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataStore.kt @@ -56,5 +56,7 @@ interface BlockDataStore { position: PositionEntity ): PayloadEntity - suspend fun updateDivider(command: CommandEntity.UpdateDivider) : PayloadEntity + suspend fun updateDivider(command: CommandEntity.UpdateDivider): PayloadEntity + + suspend fun setFields(command: CommandEntity.SetFields): PayloadEntity } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt index 4a79829eda..9c674fd266 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt @@ -56,5 +56,7 @@ interface BlockRemote { position: PositionEntity ): PayloadEntity - suspend fun updateDivider(command: CommandEntity.UpdateDivider) : PayloadEntity + suspend fun updateDivider(command: CommandEntity.UpdateDivider): PayloadEntity + + suspend fun setFields(command: CommandEntity.SetFields): PayloadEntity } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt index d2e3bef586..ce03207c31 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt @@ -148,6 +148,11 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore { position = position ) - override suspend fun updateDivider(command: CommandEntity.UpdateDivider): PayloadEntity = - remote.updateDivider(command) + override suspend fun updateDivider( + command: CommandEntity.UpdateDivider + ): PayloadEntity = remote.updateDivider(command) + + override suspend fun setFields( + command: CommandEntity.SetFields + ): PayloadEntity = remote.setFields(command) } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/interactor/UpdateFields.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/interactor/UpdateFields.kt new file mode 100644 index 0000000000..3a01f8d200 --- /dev/null +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/interactor/UpdateFields.kt @@ -0,0 +1,26 @@ +package com.anytypeio.anytype.domain.block.interactor + +import com.anytypeio.anytype.domain.base.BaseUseCase +import com.anytypeio.anytype.domain.block.model.Block +import com.anytypeio.anytype.domain.block.model.Command +import com.anytypeio.anytype.domain.block.repo.BlockRepository +import com.anytypeio.anytype.domain.common.Id +import com.anytypeio.anytype.domain.event.model.Payload + +class UpdateFields(private val repo: BlockRepository) : + BaseUseCase() { + + override suspend fun run(params: Params) = safe { + repo.setFields( + command = Command.SetFields( + context = params.context, + fields = params.fields + ) + ) + } + + data class Params( + val context: Id, + val fields: List> + ) +} \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Block.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Block.kt index 2789868ad4..6d86256315 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Block.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Block.kt @@ -32,6 +32,7 @@ data class Block( val iconEmoji: String? by default val iconImage: String? by default val isArchived: Boolean? by default + val lang: String? by default companion object { fun empty(): Fields = Fields(emptyMap()) diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Command.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Command.kt index ef71921b65..604d85c13d 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Command.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/model/Command.kt @@ -317,4 +317,9 @@ sealed class Command { val targets: List, val style: Block.Content.Divider.Style ) + + data class SetFields( + val context: Id, + val fields: List> + ) } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt index 9ca09f068e..098c25a01d 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt @@ -112,4 +112,6 @@ interface BlockRepository { ): Payload suspend fun updateDivider(command: Command.UpdateDivider): Payload + + suspend fun setFields(command: Command.SetFields): Payload } \ No newline at end of file diff --git a/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxHighlighter.kt b/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxHighlighter.kt index 5ff96becac..222926b7f8 100644 --- a/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxHighlighter.kt +++ b/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxHighlighter.kt @@ -12,6 +12,8 @@ interface SyntaxHighlighter { val source: Editable val rules: MutableList + fun setupSyntax(lang: String?) + fun addRules(new: List) { rules.apply { clear() @@ -20,7 +22,7 @@ interface SyntaxHighlighter { } fun highlight() { - clear() + clearHighlights() rules.forEach { syntax -> val matcher = syntax.matcher(source.toString()) while (matcher.find()) { @@ -34,7 +36,7 @@ interface SyntaxHighlighter { } } - fun clear() { + fun clearHighlights() { val current = source.getSpans(0, source.length, SyntaxColorSpan::class.java) current.forEach { span -> source.removeSpan(span) } } diff --git a/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/Syntaxes.kt b/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/Syntaxes.kt index a836e6292e..f6ea9b4037 100644 --- a/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/Syntaxes.kt +++ b/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/Syntaxes.kt @@ -3,4 +3,5 @@ package com.anytypeio.anytype.library_syntax_highlighter object Syntaxes { const val KOTLIN = "kotlin" const val PYTHON = "python" + const val GENERIC = "generic" } \ No newline at end of file diff --git a/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxtHighlighterExt.kt b/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxtHighlighterExt.kt index 912bd6622a..c509ccf527 100644 --- a/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxtHighlighterExt.kt +++ b/library-syntax-highlighter/src/main/java/com/anytypeio/anytype/library_syntax_highlighter/SyntaxtHighlighterExt.kt @@ -4,19 +4,36 @@ import android.content.Context import android.graphics.Color import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive import java.io.IOException fun Context.obtainSyntaxRules(language: String): List { val path = "syntax/${language}.json" val json = obtainJsonDataFromAsset(path) - checkNotNull(json) { "Could not deserialize syntax rules from path: $path" } - val descriptor = Json.decodeFromString(json) - val rules = descriptor.let { it.keywords + it.operators + it.other } - return rules.map { s -> - Syntax( - regex = s.pattern, - color = Color.parseColor(s.color) - ) + return if (json != null) { + val descriptor = Json.decodeFromString(json) + val rules = descriptor.let { it.keywords + it.operators + it.other } + rules.map { s -> + Syntax( + regex = s.pattern, + color = Color.parseColor(s.color) + ) + } + } else { + emptyList() + } +} + +fun Context.obtainGenericSyntaxRules(): List { + return obtainSyntaxRules(Syntaxes.GENERIC) +} + +fun Context.obtainLanguages(): List> { + val json = obtainJsonDataFromAsset("syntax/languages.json") + checkNotNull(json) { "Json data for languages is missing" } + return Json.parseToJsonElement(json).jsonObject.map { (key, element) -> + key to element.jsonPrimitive.content } } diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt index c01a8fa5b7..64d0fd070f 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt @@ -165,6 +165,11 @@ class BlockMiddleware( position: PositionEntity ): PayloadEntity = middleware.linkToObject(context, target, block, replace, position) - override suspend fun updateDivider(command: CommandEntity.UpdateDivider): PayloadEntity = - middleware.updateDividerStyle(command) + override suspend fun updateDivider( + command: CommandEntity.UpdateDivider + ): PayloadEntity = middleware.updateDividerStyle(command) + + override suspend fun setFields( + command: CommandEntity.SetFields + ): PayloadEntity = middleware.setFields(command) } \ No newline at end of file diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.java b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.java index 7bce00b28c..7b1653172d 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.java +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.java @@ -14,6 +14,7 @@ import com.anytypeio.anytype.middleware.service.MiddlewareService; import com.google.protobuf.Struct; import com.google.protobuf.Value; +import java.util.ArrayList; import java.util.List; import anytype.Commands; @@ -1193,4 +1194,36 @@ public class Middleware { return mapper.toPayload(response.getEvent()); } + + public PayloadEntity setFields(CommandEntity.SetFields command) throws Exception { + + List fields = new ArrayList<>(); + + for (int i = 0; i < command.getFields().size(); i++) { + Pair item = command.getFields().get(i); + BlockList.Set.Fields.Request.BlockField field = BlockList.Set.Fields.Request.BlockField + .newBuilder() + .setBlockId(item.getFirst()) + .setFields(mapper.toMiddleware(item.getSecond())) + .build(); + fields.add(field); + } + + BlockList.Set.Fields.Request request = BlockList.Set.Fields.Request.newBuilder() + .setContextId(command.getContext()) + .addAllBlockFields(fields) + .build(); + + if (BuildConfig.DEBUG) { + Timber.d(request.getClass().getName() + "\n" + request.toString()); + } + + BlockList.Set.Fields.Response response = service.blockListSetFields(request); + + if (BuildConfig.DEBUG) { + Timber.d(response.getClass().getName() + "\n" + response.toString()); + } + + return mapper.toPayload(response.getEvent()); + } } diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/MiddlewareMapper.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/MiddlewareMapper.kt index e842273e41..9bdd78099e 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/MiddlewareMapper.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/MiddlewareMapper.kt @@ -8,7 +8,9 @@ import com.anytypeio.anytype.data.auth.model.PayloadEntity import com.anytypeio.anytype.data.auth.model.PositionEntity import com.anytypeio.anytype.middleware.converters.block import com.anytypeio.anytype.middleware.converters.blocks +import com.anytypeio.anytype.middleware.converters.fields import com.anytypeio.anytype.middleware.converters.toMiddleware +import com.google.protobuf.Struct class MiddlewareMapper { @@ -46,7 +48,11 @@ class MiddlewareMapper { return alignment.toMiddleware() } - fun toEntity(blocks: List) : List { + fun toEntity(blocks: List): List { return blocks.blocks() } + + fun toMiddleware(fields: BlockEntity.Fields): Struct { + return fields.fields() + } } \ No newline at end of file diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/DefaultMiddlewareService.java b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/DefaultMiddlewareService.java index 747b841e1b..6e5a07d139 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/DefaultMiddlewareService.java +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/DefaultMiddlewareService.java @@ -424,4 +424,15 @@ public class DefaultMiddlewareService implements MiddlewareService { return response; } } + + @Override + public BlockList.Set.Fields.Response blockListSetFields(BlockList.Set.Fields.Request request) throws Exception { + byte[] encoded = Service.blockListSetFields(request.toByteArray()); + BlockList.Set.Fields.Response response = BlockList.Set.Fields.Response.parseFrom(encoded); + if (response.getError() != null && response.getError().getCode() != BlockList.Set.Fields.Response.Error.Code.NULL) { + throw new Exception(response.getError().getDescription()); + } else { + return response; + } + } } diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.java b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.java index 477bc195c3..a5575e9265 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.java +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.java @@ -86,4 +86,6 @@ public interface MiddlewareService { Commands.Rpc.Page.Create.Response pageCreate(Commands.Rpc.Page.Create.Request request) throws Exception; Commands.Rpc.Version.Get.Response getVersion(Commands.Rpc.Version.Get.Request request) throws Exception; + + BlockList.Set.Fields.Response blockListSetFields(BlockList.Set.Fields.Request request) throws Exception; } diff --git a/middleware/src/test/java/com/anytypeio/anytype/MiddlewareTest.kt b/middleware/src/test/java/com/anytypeio/anytype/MiddlewareTest.kt index 1c032b7b46..bc61b8aa25 100644 --- a/middleware/src/test/java/com/anytypeio/anytype/MiddlewareTest.kt +++ b/middleware/src/test/java/com/anytypeio/anytype/MiddlewareTest.kt @@ -587,4 +587,70 @@ class MiddlewareTest { verify(service, times(1)).uploadFile(request) verifyNoMoreInteractions(service) } + + @Test + fun `should create request for setting block fields`() { + + // SETUP + + val ctx = MockDataFactory.randomUuid() + + val block1 = MockDataFactory.randomUuid() + val block2 = MockDataFactory.randomUuid() + + val command = CommandEntity.SetFields( + context = ctx, + fields = listOf( + Pair( + block1, + BlockEntity.Fields( + map = mutableMapOf( + "lang" to "kotlin" + ) + ) + ), + Pair( + block2, + BlockEntity.Fields( + map = mutableMapOf( + "lang" to "python" + ) + ) + ) + ) + ) + + val fields = listOf( + BlockList.Set.Fields.Request.BlockField.newBuilder() + .setBlockId(block1) + .setFields( + Struct.newBuilder() + .putFields("lang", Value.newBuilder().setStringValue("kotlin").build()) + ) + .build(), + BlockList.Set.Fields.Request.BlockField.newBuilder() + .setBlockId(block2) + .setFields( + Struct.newBuilder() + .putFields("lang", Value.newBuilder().setStringValue("python").build()) + ) + .build() + ) + + val request = BlockList.Set.Fields.Request.newBuilder() + .setContextId(ctx) + .addAllBlockFields(fields) + .build() + + service.stub { + on { blockListSetFields(request) } doReturn BlockList.Set.Fields.Response.getDefaultInstance() + } + + // TESTING + + middleware.setFields(command) + + verify(service, times(1)).blockListSetFields(request) + verifyNoMoreInteractions(service) + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/PageViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/PageViewModel.kt index 7daae671bc..0cce61a641 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/PageViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/PageViewModel.kt @@ -2632,6 +2632,12 @@ class PageViewModel( else -> Unit } } + is ListenerType.Code.SelectLanguage -> { + when (mode) { + EditorMode.EDITING -> dispatch(Command.Dialog.SelectLanguage(clicked.target)) + else -> Unit + } + } } fun onPlusButtonPressed() { @@ -2924,6 +2930,24 @@ class PageViewModel( } ?: run { false } } + fun onSelectProgrammingLanguageClicked(target: Id, key: String) { + viewModelScope.launch { + orchestrator.proxies.intents.send( + Intent.CRUD.UpdateFields( + context = context, + fields = listOf( + Pair( + target, + Block.Fields( + mapOf("lang" to key) + ) + ) + ) + ) + ) + } + } + companion object { const val NO_SEARCH_RESULT_POSITION = -1 const val EMPTY_TEXT = "" diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Command.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Command.kt index 64fc18694c..aae93c8f75 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Command.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Command.kt @@ -76,4 +76,8 @@ sealed class Command { val target: Id, val url: Url ) : Command() + + sealed class Dialog : Command() { + data class SelectLanguage(val target: String) : Dialog() + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Intent.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Intent.kt index 961411e0b9..d70896fae3 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Intent.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Intent.kt @@ -63,6 +63,11 @@ sealed class Intent { val next: Id?, val effects: List = emptyList() ) : CRUD() + + class UpdateFields( + val context: Id, + val fields: List> + ) : CRUD() } sealed class Clipboard : Intent() { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Orchestrator.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Orchestrator.kt index b8af2ec4c9..ecac5fd768 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Orchestrator.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/editor/Orchestrator.kt @@ -64,6 +64,7 @@ class Orchestrator( private val uploadBlock: UploadBlock, private val setupBookmark: SetupBookmark, private val turnIntoDocument: TurnIntoDocument, + private val updateFields: UpdateFields, private val move: Move, private val copy: Copy, private val paste: Paste, @@ -201,6 +202,17 @@ class Orchestrator( } ) } + is Intent.CRUD.UpdateFields -> { + updateFields( + params = UpdateFields.Params( + context = intent.context, + fields = intent.fields + ) + ).proceed( + failure = {}, + success = { proxies.payloads.send(it) } + ) + } is Intent.Text.Split -> { val startTime = System.currentTimeMillis() splitBlock( diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/render/DefaultBlockViewRenderer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/render/DefaultBlockViewRenderer.kt index 29f5cc30de..167a3238d5 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/page/render/DefaultBlockViewRenderer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/page/render/DefaultBlockViewRenderer.kt @@ -477,7 +477,8 @@ class DefaultBlockViewRenderer( backgroundColor = content.backgroundColor, color = content.color, isFocused = block.id == focus.id, - indent = indent + indent = indent, + lang = block.fields.lang ) private fun highlight( diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/page/PageViewModelTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/page/PageViewModelTest.kt index dc9e49f58d..cc40d5dd10 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/page/PageViewModelTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/page/PageViewModelTest.kt @@ -174,7 +174,10 @@ open class PageViewModelTest { lateinit var turnIntoDocument: TurnIntoDocument @Mock - lateinit var gateway : Gateway + lateinit var updateFields: UpdateFields + + @Mock + lateinit var gateway: Gateway @Mock lateinit var analytics: Analytics @@ -3857,7 +3860,8 @@ open class PageViewModelTest { copy = copy, move = move, turnIntoDocument = turnIntoDocument, - analytics = analytics + analytics = analytics, + updateFields = updateFields ), bridge = Bridge() ) diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/page/editor/EditorPresentationTestSetup.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/page/editor/EditorPresentationTestSetup.kt index 47ac856cf3..da1a8784a1 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/page/editor/EditorPresentationTestSetup.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/page/editor/EditorPresentationTestSetup.kt @@ -105,6 +105,9 @@ open class EditorPresentationTestSetup { @Mock lateinit var uploadBlock: UploadBlock + @Mock + lateinit var updateFields: UpdateFields + @Mock lateinit var paste: Paste @@ -205,7 +208,8 @@ open class EditorPresentationTestSetup { copy = copy, move = move, turnIntoDocument = turnIntoDocument, - analytics = analytics + analytics = analytics, + updateFields = updateFields ), bridge = Bridge() )