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