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

New protocol module setup with Wire + kotlinized proto-based models (#1062)

This commit is contained in:
Evgenii Kozlov 2020-11-06 14:33:23 +02:00 committed by GitHub
parent 212a9f801a
commit d89c0d14f8
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 2093 additions and 2575 deletions

View file

@ -94,6 +94,7 @@ dependencies {
def devDependencies = rootProject.ext.development
def databaseDependencies = rootProject.ext.db
def analyticsDependencies = rootProject.ext.analytics
def protobufDependencies = rootProject.ext.protobuf
//Compile time dependencies
@ -158,6 +159,8 @@ dependencies {
androidTestImplementation unitTestDependencies.coroutineTesting
debugImplementation acceptanceTesting.fragmentTesting
implementation protobufDependencies.wireRuntime
}
apply plugin: 'com.google.gms.google-services'

View file

@ -20,8 +20,8 @@ import com.anytypeio.anytype.middleware.block.BlockMiddleware
import com.anytypeio.anytype.middleware.interactor.Middleware
import com.anytypeio.anytype.middleware.interactor.MiddlewareFactory
import com.anytypeio.anytype.middleware.interactor.MiddlewareMapper
import com.anytypeio.anytype.middleware.service.DefaultMiddlewareService
import com.anytypeio.anytype.middleware.service.MiddlewareService
import com.anytypeio.anytype.middleware.service.MiddlewareServiceImplementation
import com.anytypeio.anytype.persistence.db.AnytypeDatabase
import com.anytypeio.anytype.persistence.repo.DefaultAuthCache
import com.anytypeio.anytype.persistence.repo.DefaultDebugSettingsCache
@ -210,7 +210,7 @@ object DataModule {
@JvmStatic
@Provides
@Singleton
fun provideMiddlewareService(): MiddlewareService = DefaultMiddlewareService()
fun provideMiddlewareService(): MiddlewareService = MiddlewareServiceImplementation()
@JvmStatic
@Provides

View file

@ -29,10 +29,10 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
classpath 'com.google.gms:google-services:4.3.4'
classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.12"
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath 'com.squareup.wire:wire-gradle-plugin:3.5.0'
}
}

View file

@ -167,7 +167,7 @@ fun Block.toEntity(): BlockEntity {
return BlockEntity(
id = id,
children = children,
fields = BlockEntity.Fields(map = fields.map.toMutableMap()),
fields = BlockEntity.Fields(map = fields.map),
content = content.toEntity()
)
}
@ -249,7 +249,7 @@ fun Block.Content.Link.toEntity(): BlockEntity.Content.Link {
return BlockEntity.Content.Link(
target = target,
type = BlockEntity.Content.Link.Type.valueOf(type.name),
fields = BlockEntity.Fields(map = fields.map.toMutableMap())
fields = BlockEntity.Fields(map = fields.map)
)
}

View file

@ -9,7 +9,7 @@ data class BlockEntity(
val content: Content,
val fields: Fields
) {
data class Fields(val map: MutableMap<String?, Any?> = mutableMapOf())
data class Fields(val map: Map<String, Any?>)
data class Details(val details: Map<String, Fields>)
sealed class Content {

View file

@ -203,7 +203,7 @@ class BlockDataRepository(
command = CommandEntity.SetFields(
context = command.context,
fields = command.fields.map { (id, fields) ->
id to BlockEntity.Fields(fields.map.toMutableMap())
id to BlockEntity.Fields(fields.map)
}
)
).toDomain()

View file

@ -80,6 +80,7 @@ ext {
protobuf_java_version = '3.9.2'
protoc_version = '3.9.0'
wire_version = '3.5.0'
// DB
@ -176,7 +177,8 @@ ext {
protobuf = [
protobufJava: "com.google.protobuf:protobuf-java:$protobuf_java_version",
protoc: "com.google.protobuf:protoc:$protoc_version"
protoc: "com.google.protobuf:protoc:$protoc_version",
wireRuntime: "com.squareup.wire:wire-runtime:$wire_version"
]
db = [

View file

@ -24,7 +24,7 @@ data class Block(
* Block fields containing useful block properties.
* @property map map containing fields
*/
data class Fields(val map: Map<String?, Any?>) {
data class Fields(val map: Map<String, Any?>) {
private val default = map.withDefault { null }

View file

@ -1,6 +1,5 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
@ -31,19 +30,16 @@ dependencies {
def libraryPath = project.rootProject.file(props.getProperty('middleware.path'))
implementation(files(libraryPath))
implementation project(':protobuf')
implementation project(':protocol')
implementation project(':data')
def applicationDependencies = rootProject.ext.mainApplication
def unitTestDependencies = rootProject.ext.unitTesting
def protobufDependencies = rootProject.ext.protobuf
implementation applicationDependencies.kotlin
implementation applicationDependencies.timber
implementation applicationDependencies.coroutines
implementation protobufDependencies.protobufJava
testImplementation unitTestDependencies.junit
testImplementation unitTestDependencies.kotlinTest
testImplementation unitTestDependencies.mockitoKotlin

View file

@ -1,11 +0,0 @@
package com.anytypeio.anytype.middleware
sealed class Event {
class AccountAdd(
val index: Int,
val id: String,
val name: String
) : Event()
}

View file

@ -1,8 +1,8 @@
package com.anytypeio.anytype.middleware
import anytype.Events
import anytype.Event
import kotlinx.coroutines.flow.Flow
interface EventProxy {
fun flow(): Flow<Events.Event>
fun flow(): Flow<Event>
}

View file

@ -1,7 +1,5 @@
package com.anytypeio.anytype.middleware.auth
import anytype.Events
import anytype.model.Models
import com.anytypeio.anytype.data.auth.model.AccountEntity
import com.anytypeio.anytype.data.auth.model.WalletEntity
import com.anytypeio.anytype.data.auth.repo.AuthRemote
@ -26,8 +24,7 @@ class AuthMiddleware(
AccountEntity(
id = response.id,
name = response.name,
color = if (response.avatar.avatarCase == Models.Account.Avatar.AvatarCase.COLOR)
response.avatar.color else null
color = response.avatar?.color
)
}
@ -40,8 +37,7 @@ class AuthMiddleware(
AccountEntity(
id = response.id,
name = response.name,
color = if (response.avatar.avatarCase == Models.Account.Avatar.AvatarCase.COLOR)
response.avatar.color else null
color = response.avatar?.color
)
}
}
@ -53,17 +49,21 @@ class AuthMiddleware(
override fun observeAccounts() = events
.flow()
.filter { event ->
event.messagesList.any { message ->
message.valueCase == Events.Event.Message.ValueCase.ACCOUNTSHOW
event.messages.any { message ->
message.accountShow != null
}
}
.map { event ->
event.messagesList.filter { message ->
message.valueCase == Events.Event.Message.ValueCase.ACCOUNTSHOW
event.messages.filter { message ->
message.accountShow != null
}
}
.flatMapConcat { messages -> messages.asFlow() }
.map { event -> event.accountShow.toAccountEntity() }
.map {
val event = it.accountShow
checkNotNull(event)
event.toAccountEntity()
}
override suspend fun createWallet(
path: String
@ -80,6 +80,6 @@ class AuthMiddleware(
}
override suspend fun getVersion(): String {
return middleware.middlewareVersion.version
return middleware.getMiddlewareVersion().version
}
}

View file

@ -10,7 +10,7 @@ class BlockMiddleware(
private val middleware: Middleware
) : BlockRemote {
override suspend fun getConfig(): ConfigEntity = middleware.config
override suspend fun getConfig(): ConfigEntity = middleware.getConfig()
override suspend fun openDashboard(
contextId: String,
@ -155,7 +155,7 @@ class BlockMiddleware(
middleware.getPageInfoWithLinks(pageId).toEntity()
override suspend fun getListPages(): List<DocumentInfoEntity> =
middleware.listPages.map { it.toEntity() }
middleware.getListPages().map { it.toEntity() }
override suspend fun linkToObject(
context: String,

View file

@ -1,6 +1,6 @@
package com.anytypeio.anytype.middleware.config
import anytype.Commands.Rpc.Config
import anytype.Rpc.Config
import com.anytypeio.anytype.data.auth.model.ConfigEntity
import com.anytypeio.anytype.data.auth.repo.config.Configurator
import service.Service
@ -33,15 +33,16 @@ class DefaultConfigurator : Configurator {
}
private fun fetchConfig(): Config.Get.Response {
val request = Config.Get.Request.newBuilder().build()
val encoded = Service.configGet(request.toByteArray())
val response = Config.Get.Response.parseFrom(encoded)
val request = Config.Get.Request()
val encoded = Service.configGet(Config.Get.Request.ADAPTER.encode(request))
val response = Config.Get.Response.ADAPTER.decode(encoded)
return parseResponse(response)
}
private fun parseResponse(response: Config.Get.Response): Config.Get.Response {
return if (response.error != null && response.error.code != Config.Get.Response.Error.Code.NULL) {
throw Exception(response.error.description)
val error = response.error
return if (error != null && error.code != Config.Get.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
response
}

View file

@ -1,6 +1,6 @@
package com.anytypeio.anytype.middleware.converters
import anytype.clipboard.ClipboardOuterClass.Clipboard
import anytype.clipboard.Clipboard
import com.anytypeio.anytype.data.auth.mapper.Serializer
import com.anytypeio.anytype.data.auth.model.BlockEntity
@ -8,11 +8,11 @@ class ClipboardSerializer : Serializer {
override fun serialize(blocks: List<BlockEntity>): ByteArray {
val models = blocks.map { it.block() }
val clipboard = Clipboard.newBuilder().addAllBlocks(models).build()
return clipboard.toByteArray()
val clipboard = Clipboard(blocks = models)
return Clipboard.ADAPTER.encode(clipboard)
}
override fun deserialize(blob: ByteArray): List<BlockEntity> {
return Clipboard.parseFrom(blob).blocksList.blocks()
return Clipboard.ADAPTER.decode(blob).blocks.blocks()
}
}

View file

@ -1,68 +1,56 @@
package com.anytypeio.anytype.middleware.converters
import anytype.Events
import anytype.model.Localstore
import anytype.model.Models.Account
import anytype.model.Models.Block
import anytype.Event
import anytype.SmartBlockType
import anytype.model.Block
import anytype.model.PageInfo
import anytype.model.PageInfoWithLinks
import anytype.model.PageLinksInfo
import com.anytypeio.anytype.data.auth.model.*
import com.google.protobuf.Struct
import com.google.protobuf.Value
import timber.log.Timber
fun Events.Event.Account.Show.toAccountEntity(): AccountEntity {
fun Event.Account.Show.toAccountEntity(): AccountEntity {
val acc = account
checkNotNull(acc)
return AccountEntity(
id = account.id,
name = account.name,
color = if (account.avatar.avatarCase == Account.Avatar.AvatarCase.COLOR)
account.avatar.color
else null
id = acc.id,
name = acc.name,
color = acc.avatar?.color
)
}
fun Block.fields(): BlockEntity.Fields = BlockEntity.Fields().also { result ->
fields.fieldsMap.forEach { (key, value) ->
result.map[key] = when (val case = value.kindCase) {
Value.KindCase.NUMBER_VALUE -> value.numberValue
Value.KindCase.STRING_VALUE -> value.stringValue
else -> throw IllegalStateException("$case is not supported.")
}
}
}
fun Block.fields(): BlockEntity.Fields = BlockEntity.Fields(fields?.toMap().orEmpty())
fun Events.SmartBlockType.entity(): BlockEntity.Content.Smart.Type = when (this) {
Events.SmartBlockType.Archive -> BlockEntity.Content.Smart.Type.ARCHIVE
Events.SmartBlockType.Page -> BlockEntity.Content.Smart.Type.PAGE
Events.SmartBlockType.Breadcrumbs -> BlockEntity.Content.Smart.Type.BREADCRUMBS
Events.SmartBlockType.Home -> BlockEntity.Content.Smart.Type.HOME
Events.SmartBlockType.ProfilePage -> BlockEntity.Content.Smart.Type.PROFILE
fun SmartBlockType.entity(): BlockEntity.Content.Smart.Type = when (this) {
SmartBlockType.Archive -> BlockEntity.Content.Smart.Type.ARCHIVE
SmartBlockType.Page -> BlockEntity.Content.Smart.Type.PAGE
SmartBlockType.Breadcrumbs -> BlockEntity.Content.Smart.Type.BREADCRUMBS
SmartBlockType.Home -> BlockEntity.Content.Smart.Type.HOME
SmartBlockType.ProfilePage -> BlockEntity.Content.Smart.Type.PROFILE
else -> throw IllegalStateException("Unexpected smart block type: $this")
}
fun Struct.fields(): BlockEntity.Fields = BlockEntity.Fields().also { result ->
fieldsMap.forEach { (key, value) ->
result.map[key] = when (val case = value.kindCase) {
Value.KindCase.NUMBER_VALUE -> value.numberValue
Value.KindCase.STRING_VALUE -> value.stringValue
Value.KindCase.BOOL_VALUE -> value.boolValue
else -> throw IllegalStateException("$case is not supported.")
}
}
fun Map<String, *>?.fields() : BlockEntity.Fields = BlockEntity.Fields(this?.toMap().orEmpty())
fun Block.text(): BlockEntity.Content.Text {
val t = checkNotNull(text)
return BlockEntity.Content.Text(
text = t.text,
marks = t.marks?.marks?.marks().orEmpty(),
style = t.style.entity(),
isChecked = t.checked,
color = if (t.color.isNotEmpty()) t.color else null,
backgroundColor = if (backgroundColor.isNotEmpty()) backgroundColor else null,
align = align.entity()
)
}
fun Block.text(): BlockEntity.Content.Text = BlockEntity.Content.Text(
text = text.text,
marks = text.marks.marksList.marks(),
style = text.style.entity(),
isChecked = text.checked,
color = if (text.color.isNotEmpty()) text.color else null,
backgroundColor = if (backgroundColor.isNotEmpty()) backgroundColor else null,
align = if (align != null) align.entity() else null
)
fun List<Block.Content.Text.Mark>.marks(): List<BlockEntity.Content.Text.Mark> = map { mark ->
val range = mark.range
checkNotNull(range) {"mark range is null"}
BlockEntity.Content.Text.Mark(
range = IntRange(mark.range.from, mark.range.to),
param = if (mark.param.isNotEmpty()) mark.param else null,
range = IntRange(range.from, range.to),
param = if (mark.param_.isNotEmpty()) mark.param_ else null,
type = when (mark.type) {
Block.Content.Text.Mark.Type.Bold -> {
BlockEntity.Content.Text.Mark.Type.BOLD
@ -97,55 +85,46 @@ fun List<Block.Content.Text.Mark>.marks(): List<BlockEntity.Content.Text.Mark> =
}
fun Block.layout(): BlockEntity.Content.Layout = BlockEntity.Content.Layout(
type = when (layout.style) {
type = when (layout?.style) {
Block.Content.Layout.Style.Column -> BlockEntity.Content.Layout.Type.COLUMN
Block.Content.Layout.Style.Row -> BlockEntity.Content.Layout.Type.ROW
Block.Content.Layout.Style.Div -> BlockEntity.Content.Layout.Type.DIV
Block.Content.Layout.Style.Header -> BlockEntity.Content.Layout.Type.HEADER
else -> throw IllegalStateException("Unexpected layout style: ${layout.style}")
else -> throw IllegalStateException("Unexpected layout style: ${layout?.style}")
}
)
fun Block.link(): BlockEntity.Content.Link = BlockEntity.Content.Link(
type = when (link.style) {
type = when (link?.style) {
Block.Content.Link.Style.Page -> BlockEntity.Content.Link.Type.PAGE
Block.Content.Link.Style.Dataview -> BlockEntity.Content.Link.Type.DATA_VIEW
Block.Content.Link.Style.Archive -> BlockEntity.Content.Link.Type.ARCHIVE
Block.Content.Link.Style.Dashboard -> BlockEntity.Content.Link.Type.DASHBOARD
else -> throw IllegalStateException("Unexpected link style: ${link.style}")
else -> throw IllegalStateException("Unexpected link style: ${link?.style}")
},
target = link.targetBlockId,
fields = BlockEntity.Fields().also { result ->
link.fields.fieldsMap.forEach { (key, value) ->
result.map[key] = when (val case = value.kindCase) {
Value.KindCase.NUMBER_VALUE -> value.numberValue
Value.KindCase.STRING_VALUE -> value.stringValue
Value.KindCase.BOOL_VALUE -> value.boolValue
else -> throw IllegalStateException("$case is not supported.")
}
}
}
target = link?.targetBlockId.orEmpty(),
fields = BlockEntity.Fields(link?.fields?.toMap().orEmpty())
)
fun Block.divider(): BlockEntity.Content.Divider = BlockEntity.Content.Divider(
style = when (div.style) {
style = when (div?.style) {
Block.Content.Div.Style.Line -> BlockEntity.Content.Divider.Style.LINE
Block.Content.Div.Style.Dots -> BlockEntity.Content.Divider.Style.DOTS
else -> throw IllegalStateException("Unexpected div style: ${div.style}")
else -> throw IllegalStateException("Unexpected div style: ${div?.style}")
}
)
fun Block.icon(): BlockEntity.Content.Icon = BlockEntity.Content.Icon(
name = icon.name
name = icon?.name.orEmpty()
)
fun Block.file(): BlockEntity.Content.File = BlockEntity.Content.File(
hash = file.hash,
name = file.name,
size = file.size,
mime = file.mime,
type = file.type.entity(),
state = file.state.entity()
hash = file_?.hash,
name = file_?.name,
size = file_?.size,
mime = file_?.mime,
type = file_?.type?.entity(),
state = file_?.state?.entity()
)
fun Block.Align.entity(): BlockEntity.Align = when (this) {
@ -172,42 +151,42 @@ fun Block.Content.File.State.entity(): BlockEntity.Content.File.State = when (th
}
fun Block.bookmark(): BlockEntity.Content.Bookmark = BlockEntity.Content.Bookmark(
url = bookmark.url.ifEmpty { null },
description = bookmark.description.ifEmpty { null },
title = bookmark.title.ifEmpty { null },
image = bookmark.imageHash.ifEmpty { null },
favicon = bookmark.faviconHash.ifEmpty { null }
url = bookmark?.url?.ifEmpty { null },
description = bookmark?.description?.ifEmpty { null },
title = bookmark?.title?.ifEmpty { null },
image = bookmark?.imageHash?.ifEmpty { null },
favicon = bookmark?.faviconHash?.ifEmpty { null }
)
fun List<Block>.blocks(
types: Map<String, Events.SmartBlockType> = emptyMap()
types: Map<String, SmartBlockType> = emptyMap()
): List<BlockEntity> = mapNotNull { block ->
when (block.contentCase) {
Block.ContentCase.TEXT -> {
when {
block.text != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList.toList(),
children = block.childrenIds,
fields = block.fields(),
content = block.text()
)
}
Block.ContentCase.LAYOUT -> {
block.layout != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList,
children = block.childrenIds,
fields = block.fields(),
content = block.layout()
)
}
Block.ContentCase.LINK -> {
block.link != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList,
children = block.childrenIds,
fields = block.fields(),
content = block.link()
)
}
Block.ContentCase.DIV -> {
block.div != null -> {
BlockEntity(
id = block.id,
children = emptyList(),
@ -215,34 +194,34 @@ fun List<Block>.blocks(
content = block.divider()
)
}
Block.ContentCase.FILE -> {
block.file_ != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList,
children = block.childrenIds,
fields = block.fields(),
content = block.file()
)
}
Block.ContentCase.ICON -> {
block.icon != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList,
children = block.childrenIds,
fields = block.fields(),
content = block.icon()
)
}
Block.ContentCase.BOOKMARK -> {
block.bookmark != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList,
children = block.childrenIds,
fields = block.fields(),
content = block.bookmark()
)
}
Block.ContentCase.SMARTBLOCK -> {
block.smartblock != null -> {
BlockEntity(
id = block.id,
children = block.childrenIdsList,
children = block.childrenIds,
content = BlockEntity.Content.Smart(
type = types[block.id]?.entity() ?: throw IllegalStateException("Type missing")
),
@ -250,7 +229,7 @@ fun List<Block>.blocks(
)
}
else -> {
Timber.d("Ignoring content type: ${block.contentCase}")
Timber.d("Ignoring content type: ${block}")
null
}
}
@ -315,30 +294,36 @@ fun BlockEntity.Align.toMiddleware(): Block.Align = when (this) {
BlockEntity.Align.AlignRight -> Block.Align.AlignRight
}
fun Localstore.PageInfo.toEntity(): DocumentInfoEntity = DocumentInfoEntity(
fun PageInfo.fields(): BlockEntity.Fields = BlockEntity.Fields(details?.toMap().orEmpty())
fun PageInfo.toEntity(): DocumentInfoEntity = DocumentInfoEntity(
id = id,
fields = details.fields(),
fields = fields(),
hasInboundLinks = hasInboundLinks,
snippet = snippet,
type = pageType.let { type ->
when (type) {
Localstore.PageInfo.Type.Page -> DocumentInfoEntity.Type.PAGE
Localstore.PageInfo.Type.Archive -> DocumentInfoEntity.Type.ARCHIVE
Localstore.PageInfo.Type.ProfilePage -> DocumentInfoEntity.Type.PROFILE_PAGE
Localstore.PageInfo.Type.Home -> DocumentInfoEntity.Type.HOME
Localstore.PageInfo.Type.Set -> DocumentInfoEntity.Type.SET
PageInfo.Type.Page -> DocumentInfoEntity.Type.PAGE
PageInfo.Type.Archive -> DocumentInfoEntity.Type.ARCHIVE
PageInfo.Type.ProfilePage -> DocumentInfoEntity.Type.PROFILE_PAGE
PageInfo.Type.Home -> DocumentInfoEntity.Type.HOME
PageInfo.Type.Set -> DocumentInfoEntity.Type.SET
else -> throw IllegalStateException("Unexpected page info type: $type")
}
}
)
fun Localstore.PageLinksInfo.toEntity() = PageLinksEntity(
inbound = inboundList.map { it.toEntity() },
outbound = outboundList.map { it.toEntity() }
fun PageLinksInfo.toEntity() = PageLinksEntity(
inbound = inbound.map { it.toEntity() },
outbound = outbound.map { it.toEntity() }
)
fun Localstore.PageInfoWithLinks.toEntity() = PageInfoWithLinksEntity(
id = id,
docInfo = info.toEntity(),
links = links.toEntity()
)
fun PageInfoWithLinks.toEntity(): PageInfoWithLinksEntity {
checkNotNull(info) { "info property is null" }
checkNotNull(links) { "links property is null" }
return PageInfoWithLinksEntity(
id = id,
docInfo = info!!.toEntity(),
links = links!!.toEntity()
)
}

View file

@ -1,10 +1,8 @@
package com.anytypeio.anytype.middleware.converters
import anytype.model.Models.Block
import anytype.model.Models.Range
import anytype.model.Block
import anytype.model.Range
import com.anytypeio.anytype.data.auth.model.BlockEntity
import com.google.protobuf.Struct
import com.google.protobuf.Value
typealias Mark = Block.Content.Text.Mark
typealias File = Block.Content.File
@ -23,118 +21,99 @@ typealias DividerStyle = Block.Content.Div.Style
//region block mapping
fun BlockEntity.block(): Block {
val builder = Block.newBuilder()
builder.id = id
when (val content = content) {
return when (val content = content) {
is BlockEntity.Content.Text -> {
if (content.backgroundColor != null) {
builder.backgroundColor = content.backgroundColor
}
if (content.align != null) {
builder.align = content.align?.toMiddleware()
}
builder.text = content.text()
Block(
text = content.text(),
backgroundColor = content.backgroundColor.orEmpty(),
align = content.align?.toMiddleware() ?: Block.Align.AlignLeft
)
}
is BlockEntity.Content.Bookmark -> {
builder.bookmark = content.bookmark()
Block(bookmark = content.bookmark())
}
is BlockEntity.Content.File -> {
builder.file = content.file()
Block(file_ = content.file())
}
is BlockEntity.Content.Link -> {
builder.link = content.link()
Block(link = content.link())
}
is BlockEntity.Content.Layout -> {
builder.layout = content.layout()
Block(layout = content.layout())
}
is BlockEntity.Content.Divider -> {
builder.div = content.divider()
Block(div = content.divider())
}
else -> Block()
}
return builder.build()
}
//endregion
//region text block mapping
fun BlockEntity.Content.Text.text(): Text {
val builder = Text.newBuilder()
builder.text = text
builder.marks = marks()
builder.style = style.toMiddleware()
if (color != null) {
builder.color = color
}
isChecked?.let {
builder.checked = it
}
return builder.build()
}
fun BlockEntity.Content.Text.text(): Text = Text(
text = text,
marks = marks(),
style = style.toMiddleware(),
color = color.orEmpty(),
checked = isChecked ?: false
)
fun BlockEntity.Content.Text.marks(): Marks {
return Marks
.newBuilder()
.addAllMarks(marks.map { it.mark() })
.build()
}
fun BlockEntity.Content.Text.marks(): Marks = Marks(marks = marks.map { it.mark() })
fun BlockEntity.Content.Text.Mark.mark(): Mark = when (type) {
BlockEntity.Content.Text.Mark.Type.BOLD -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.Bold)
.setRange(range.range())
.build()
Mark(
type = Block.Content.Text.Mark.Type.Bold,
range = range.range()
)
}
BlockEntity.Content.Text.Mark.Type.ITALIC -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.Italic)
.setRange(range.range())
.build()
Mark(
type = Block.Content.Text.Mark.Type.Italic,
range = range.range()
)
}
BlockEntity.Content.Text.Mark.Type.STRIKETHROUGH -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.Strikethrough)
.setRange(range.range())
.build()
Mark(
type = Block.Content.Text.Mark.Type.Strikethrough,
range = range.range()
)
}
BlockEntity.Content.Text.Mark.Type.TEXT_COLOR -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.TextColor)
.setRange(range.range())
.setParam(param)
.build()
Mark(
type = Block.Content.Text.Mark.Type.TextColor,
range = range.range(),
param_ = param.orEmpty()
)
}
BlockEntity.Content.Text.Mark.Type.LINK -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.Link)
.setRange(range.range())
.setParam(param)
.build()
Mark(
type = Block.Content.Text.Mark.Type.Link,
range = range.range(),
param_ = param.orEmpty()
)
}
BlockEntity.Content.Text.Mark.Type.BACKGROUND_COLOR -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.BackgroundColor)
.setRange(range.range())
.setParam(param)
.build()
Mark(
type = Block.Content.Text.Mark.Type.BackgroundColor,
range = range.range(),
param_ = param.orEmpty()
)
}
BlockEntity.Content.Text.Mark.Type.KEYBOARD -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.Keyboard)
.setRange(range.range())
.build()
Mark(
type = Block.Content.Text.Mark.Type.Keyboard,
range = range.range(),
)
}
BlockEntity.Content.Text.Mark.Type.MENTION -> {
Mark.newBuilder()
.setType(Block.Content.Text.Mark.Type.Mention)
.setRange(range.range())
.setParam(param)
.build()
Mark(
type = Block.Content.Text.Mark.Type.Mention,
range = range.range(),
param_ = param.orEmpty()
)
}
else -> throw IllegalStateException("Unsupported mark type: ${type.name}")
}
@ -143,30 +122,26 @@ fun BlockEntity.Content.Text.Mark.mark(): Mark = when (type) {
//region bookmark block mapping
fun BlockEntity.Content.Bookmark.bookmark(): Bookmark {
val builder = Bookmark.newBuilder()
description?.let { builder.setDescription(it) }
favicon?.let { builder.setFaviconHash(it) }
title?.let { builder.setTitle(it) }
url?.let { builder.setUrl(it) }
image?.let { builder.setImageHash(it) }
return builder.build()
}
fun BlockEntity.Content.Bookmark.bookmark(): Bookmark = Bookmark(
description = description.orEmpty(),
faviconHash = favicon.orEmpty(),
title = title.orEmpty(),
url = url.orEmpty(),
imageHash = image.orEmpty()
)
//endregion
//region file block mapping
fun BlockEntity.Content.File.file(): File {
val builder = File.newBuilder()
hash?.let { builder.setHash(it) }
name?.let { builder.setName(it) }
mime?.let { builder.setMime(it) }
size?.let { builder.setSize(it) }
state?.let { builder.setState(it.state()) }
type?.let { builder.setType(it.type()) }
return builder.build()
}
fun BlockEntity.Content.File.file(): File = File(
hash = hash.orEmpty(),
name = name.orEmpty(),
mime = mime.orEmpty(),
size = size ?: 0,
state = state?.state() ?: Block.Content.File.State.Empty,
type = type?.type() ?: Block.Content.File.Type.None
)
fun BlockEntity.Content.File.State.state(): FileState = when (this) {
BlockEntity.Content.File.State.EMPTY -> FileState.Empty
@ -186,13 +161,11 @@ fun BlockEntity.Content.File.Type.type(): FileType = when (this) {
//region link mapping
fun BlockEntity.Content.Link.link(): Link {
return Link.newBuilder()
.setTargetBlockId(target)
.setStyle(type.type())
.setFields(fields.fields())
.build()
}
fun BlockEntity.Content.Link.link(): Link = Link(
targetBlockId = target,
style = type.type(),
fields = fields.map
)
fun BlockEntity.Content.Link.Type.type() : LinkType = when(this) {
BlockEntity.Content.Link.Type.ARCHIVE -> LinkType.Archive
@ -205,54 +178,26 @@ fun BlockEntity.Content.Link.Type.type() : LinkType = when(this) {
//region layout mapping
fun BlockEntity.Content.Layout.layout() : Layout {
val builder = Layout.newBuilder()
when(type) {
BlockEntity.Content.Layout.Type.ROW -> builder.style = LayoutStyle.Row
BlockEntity.Content.Layout.Type.COLUMN -> builder.style = LayoutStyle.Column
BlockEntity.Content.Layout.Type.DIV -> builder.style = LayoutStyle.Div
BlockEntity.Content.Layout.Type.HEADER -> builder.style = LayoutStyle.Header
}
return builder.build()
fun BlockEntity.Content.Layout.layout(): Layout = when (type) {
BlockEntity.Content.Layout.Type.ROW -> Layout(style = LayoutStyle.Row)
BlockEntity.Content.Layout.Type.COLUMN -> Layout(style = LayoutStyle.Column)
BlockEntity.Content.Layout.Type.DIV -> Layout(style = LayoutStyle.Div)
BlockEntity.Content.Layout.Type.HEADER -> Layout(style = LayoutStyle.Header)
}
//endregion
//region divider mapping
fun BlockEntity.Content.Divider.divider(): Divider {
val builder = Divider.newBuilder()
when (style) {
BlockEntity.Content.Divider.Style.LINE -> builder.style = Block.Content.Div.Style.Line
BlockEntity.Content.Divider.Style.DOTS -> builder.style = Block.Content.Div.Style.Dots
}
return builder.build()
fun BlockEntity.Content.Divider.divider(): Divider = when (style) {
BlockEntity.Content.Divider.Style.LINE -> Divider(style = Block.Content.Div.Style.Line)
BlockEntity.Content.Divider.Style.DOTS -> Divider(style = Block.Content.Div.Style.Dots)
}
//endregion
//region other mapping
fun BlockEntity.Fields.fields() : Struct {
val builder = Struct.newBuilder()
map.forEach { (key, value) ->
if (key != null && value != null)
when(value) {
is String -> {
builder.putFields(key, Value.newBuilder().setStringValue(value).build())
}
is Boolean -> {
builder.putFields(key, Value.newBuilder().setBoolValue(value).build())
}
is Double-> {
builder.putFields(key, Value.newBuilder().setNumberValue(value).build())
}
else -> throw IllegalStateException("Unexpected value type: ${value::class.java}")
}
}
return builder.build()
}
fun IntRange.range(): Range = Range.newBuilder().setFrom(first).setTo(last).build()
fun IntRange.range(): Range = Range(from = first, to = last)
//endregion

View file

@ -1,9 +1,8 @@
package com.anytypeio.anytype.middleware.interactor
import anytype.Events
import anytype.Event
import com.anytypeio.anytype.middleware.BuildConfig
import com.anytypeio.anytype.middleware.EventProxy
import com.google.protobuf.InvalidProtocolBufferException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.BroadcastChannel
@ -12,12 +11,13 @@ import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.launch
import service.Service.setEventHandlerMobile
import timber.log.Timber
import java.io.IOException
class EventHandler(
private val scope: CoroutineScope = GlobalScope
) : EventProxy {
private val channel = BroadcastChannel<Events.Event>(1)
private val channel = BroadcastChannel<Event>(1)
init {
scope.launch {
@ -31,18 +31,18 @@ class EventHandler(
private suspend fun handle(bytes: ByteArray) {
try {
Events.Event.parseFrom(bytes).let {
Event.ADAPTER.decode(bytes).let {
logEvent(it)
channel.send(it)
}
} catch (e: InvalidProtocolBufferException) {
} catch (e: IOException) {
Timber.e(e, "Error while deserializing message")
}
}
private fun logEvent(it: Events.Event?) {
private fun logEvent(it: Event?) {
if (BuildConfig.DEBUG) Timber.d("New event from middleware:\n$it")
}
override fun flow(): Flow<Events.Event> = channel.asFlow()
override fun flow(): Flow<Event> = channel.asFlow()
}

View file

@ -0,0 +1,877 @@
package com.anytypeio.anytype.middleware.interactor
import anytype.Rpc
import anytype.Rpc.BlockList
import anytype.Rpc.BlockList.Set.Fields.Request.BlockField
import anytype.model.Block
import anytype.model.PageInfo
import anytype.model.PageInfoWithLinks
import anytype.model.Range
import com.anytypeio.anytype.data.auth.model.*
import com.anytypeio.anytype.middleware.BuildConfig
import com.anytypeio.anytype.middleware.model.CreateAccountResponse
import com.anytypeio.anytype.middleware.model.CreateWalletResponse
import com.anytypeio.anytype.middleware.model.SelectAccountResponse
import com.anytypeio.anytype.middleware.service.MiddlewareService
import timber.log.Timber
import java.util.*
import kotlin.jvm.Throws
class Middleware(
private val service: MiddlewareService,
private val factory: MiddlewareFactory,
private val mapper: MiddlewareMapper
) {
private val iconEmojiKey = "iconEmoji"
private val iconImageKey = "iconImage"
private val nameKey = "name"
@Throws(Exception::class)
fun getConfig(): ConfigEntity {
val request = Rpc.Config.Get.Request()
if (BuildConfig.DEBUG) {
Timber.d(request.toString())
}
val response = service.configGet(request)
if (BuildConfig.DEBUG) {
Timber.d(response.toString())
}
return ConfigEntity(
response.homeBlockId,
response.profileBlockId,
response.gatewayUrl
)
}
@Throws(Exception::class)
fun createWallet(path: String): CreateWalletResponse {
val request = Rpc.Wallet.Create.Request(rootPath = path)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.walletCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
return CreateWalletResponse(response.mnemonic)
}
@Throws(Exception::class)
fun createAccount(
name: String,
path: String?,
invitationCode: String
): CreateAccountResponse {
val request = Rpc.Account.Create.Request(
name = name,
alphaInviteCode = invitationCode,
avatarLocalPath = path
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.accountCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
val acc = response.account
checkNotNull(acc)
return CreateAccountResponse(
acc.id,
acc.name,
acc.avatar
)
}
@Throws(Exception::class)
fun recoverWallet(path: String, mnemonic: String) {
val request = Rpc.Wallet.Recover.Request(
mnemonic = mnemonic,
rootPath = path
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.walletRecover(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun convertWallet(entropy: String): String {
val request = Rpc.Wallet.Convert.Request(entropy = entropy)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.walletConvert(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.mnemonic
}
@Throws(Exception::class)
fun logout() {
val request: Rpc.Account.Stop.Request = Rpc.Account.Stop.Request()
if (BuildConfig.DEBUG) logRequest(request)
val response = service.accountStop(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun recoverAccount() {
val request = Rpc.Account.Recover.Request()
if (BuildConfig.DEBUG) logRequest(request)
val response = service.accountRecover(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun selectAccount(id: String, path: String): SelectAccountResponse {
val request = Rpc.Account.Select.Request(
id = id,
rootPath = path
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.accountSelect(request)
if (BuildConfig.DEBUG) logResponse(response)
val acc = response.account
checkNotNull(acc)
return SelectAccountResponse(
acc.id,
acc.name,
acc.avatar
)
}
@Throws(Exception::class)
fun openDashboard(contextId: String, id: String): PayloadEntity {
val request: Rpc.Block.Open.Request = Rpc.Block.Open.Request(
contextId = contextId,
blockId = id
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockOpen(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun openBlock(id: String): PayloadEntity {
val request = Rpc.Block.Open.Request(blockId = id)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockOpen(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun createPage(parentId: String, emoji: String?): String {
val details = if (emoji != null)
mapOf(iconEmojiKey to emoji)
else
emptyMap()
val request = Rpc.Block.CreatePage.Request(
contextId = parentId,
details = details,
position = Block.Position.Inner
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockCreatePage(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.targetId
}
@Throws(Exception::class)
fun closePage(id: String) {
val request = Rpc.Block.Close.Request(blockId = id)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockClose(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun closeDashboard(id: String) {
val request = Rpc.Block.Close.Request(blockId = id)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockClose(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun updateDocumentTitle(command: CommandEntity.UpdateTitle) {
val detail = Rpc.Block.Set.Details.Detail(
key = nameKey,
value = command.title
)
val request = Rpc.Block.Set.Details.Request(
contextId = command.context,
details = listOf(detail)
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSetDetails(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun updateText(
contextId: String,
blockId: String,
text: String,
marks: List<Block.Content.Text.Mark>
) {
val markup: Block.Content.Text.Marks = Block.Content.Text.Marks(marks)
val request = Rpc.Block.Set.Text.TText.Request(
contextId = contextId,
blockId = blockId,
text = text,
marks = markup
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSetTextText(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun updateCheckbox(
context: String,
target: String,
isChecked: Boolean
): PayloadEntity {
val request = Rpc.Block.Set.Text.Checked.Request(
contextId = context,
blockId = target,
checked = isChecked
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSetTextChecked(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun updateTextStyle(command: CommandEntity.UpdateStyle): PayloadEntity {
val style = mapper.toMiddleware(command.style)
val request: BlockList.Set.Text.Style.Request = BlockList.Set.Text.Style.Request(
style = style,
blockIds = command.targets,
contextId = command.context
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListSetTextStyle(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun updateTextColor(command: CommandEntity.UpdateTextColor): PayloadEntity {
val request = Rpc.Block.Set.Text.Color.Request(
contextId = command.context,
color = command.color,
blockId = command.target
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSetTextColor(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun updateBackgroundColor(command: CommandEntity.UpdateBackgroundColor): PayloadEntity {
val request = BlockList.Set.BackgroundColor.Request(
contextId = command.context,
blockIds = command.targets,
color = command.color
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListSetBackgroundColor(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun updateAlignment(command: CommandEntity.UpdateAlignment): PayloadEntity {
val align: Block.Align = mapper.toMiddleware(command.alignment)
val request = BlockList.Set.Align.Request(
contextId = command.context,
blockIds = command.targets,
align = align
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListSetAlign(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun uploadBlock(command: CommandEntity.UploadBlock): PayloadEntity {
val request = Rpc.Block.Upload.Request(
filePath = command.filePath,
url = command.url,
contextId = command.contextId,
blockId = command.blockId
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockUpload(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun createBlock(
contextId: String,
targetId: String,
position: PositionEntity,
prototype: BlockEntity.Prototype
): Pair<String, PayloadEntity> {
val request = Rpc.Block.Create.Request(
contextId = contextId,
targetId = targetId,
position = mapper.toMiddleware(position),
block = factory.create(prototype)
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
return Pair(response.blockId, mapper.toPayload(response.event))
}
@Throws(Exception::class)
fun replace(command: CommandEntity.Replace): Pair<String, PayloadEntity> {
val model: Block = factory.create(command.prototype)
val request = Rpc.Block.Create.Request(
contextId = command.context,
targetId = command.target,
position = Block.Position.Replace,
block = model
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
return Pair(response.blockId, mapper.toPayload(response.event))
}
@Throws(Exception::class)
fun createDocument(command: CommandEntity.CreateDocument): Triple<String, String, PayloadEntity> {
val details = if (command.emoji != null) {
mapOf(iconEmojiKey to command.emoji)
} else {
mapOf()
}
val position: Block.Position = mapper.toMiddleware(command.position)
val request = Rpc.Block.CreatePage.Request(
contextId = command.context,
targetId = command.target,
position = position,
details = details
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockCreatePage(request)
if (BuildConfig.DEBUG) logResponse(response)
return Triple(
response.blockId,
response.targetId,
mapper.toPayload(response.event)
)
}
@Throws(Exception::class)
fun createPage(command: CommandEntity.CreatePage): String {
val details: MutableMap<String, Any> = mutableMapOf()
command.emoji?.let { details[iconEmojiKey] = it }
command.name?.let { details[nameKey] = it }
val request = Rpc.Page.Create.Request(details = details.toMap())
if (BuildConfig.DEBUG) logRequest(request)
val response = service.pageCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.pageId
}
@Throws(Exception::class)
fun move(command: CommandEntity.Move): PayloadEntity {
val position: Block.Position = mapper.toMiddleware(command.position)
val request: BlockList.Move.Request = BlockList.Move.Request(
contextId = command.contextId,
targetContextId = command.dropTargetContextId,
position = position,
blockIds = command.blockIds,
dropTargetId = command.dropTargetId
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListMove(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun duplicate(command: CommandEntity.Duplicate): Pair<String, PayloadEntity> {
val request = BlockList.Duplicate.Request(
contextId = command.context,
targetId = command.original,
blockIds = listOf(command.original),
position = Block.Position.Bottom
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListDuplicate(request)
if (BuildConfig.DEBUG) logResponse(response)
return Pair(response.blockIds.first(), mapper.toPayload(response.event))
}
@Throws(Exception::class)
fun unlink(command: CommandEntity.Unlink): PayloadEntity {
val request = Rpc.Block.Unlink.Request(
contextId = command.context,
blockIds = command.targets
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockUnlink(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun merge(command: CommandEntity.Merge): PayloadEntity {
val request = Rpc.Block.Merge.Request(
contextId = command.context,
firstBlockId = command.pair.first,
secondBlockId = command.pair.second
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockMerge(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun split(command: CommandEntity.Split): Pair<String, PayloadEntity> {
val style = mapper.toMiddleware(command.style)
val range = Range(
from = command.range.first,
to = command.range.last
)
val mode = mapper.toMiddleware(command.mode)
val request: Rpc.Block.Split.Request = Rpc.Block.Split.Request(
contextId = command.context,
blockId = command.target,
style = style,
range = range,
mode = mode
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSplit(request)
if (BuildConfig.DEBUG) logResponse(response)
return Pair(response.blockId, mapper.toPayload(response.event))
}
@Throws(Exception::class)
fun setDocumentEmojiIcon(command: CommandEntity.SetDocumentEmojiIcon): PayloadEntity {
val emojiDetail = Rpc.Block.Set.Details.Detail(
key = iconEmojiKey,
value = command.emoji
)
val imageDetail = Rpc.Block.Set.Details.Detail(
key = iconImageKey,
value = null
)
val request = Rpc.Block.Set.Details.Request(
contextId = command.context,
details = listOf(emojiDetail, imageDetail)
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSetDetails(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun setDocumentImageIcon(command: CommandEntity.SetDocumentImageIcon): PayloadEntity {
val imageDetail = Rpc.Block.Set.Details.Detail(
key = iconImageKey,
value = command.hash
)
val emojiDetail = Rpc.Block.Set.Details.Detail(
key = iconEmojiKey,
value = null
)
val request = Rpc.Block.Set.Details.Request(
contextId = command.context,
details = listOf(imageDetail, emojiDetail)
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockSetDetails(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun setupBookmark(command: CommandEntity.SetupBookmark): PayloadEntity {
val request: Rpc.Block.Bookmark.Fetch.Request = Rpc.Block.Bookmark.Fetch.Request(
contextId = command.context,
blockId = command.target,
url = command.url
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockBookmarkFetch(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun undo(command: CommandEntity.Undo): PayloadEntity {
val request = Rpc.Block.Undo.Request(contextId = command.context)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockUndo(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun redo(command: CommandEntity.Redo): PayloadEntity {
val request = Rpc.Block.Redo.Request(contextId = command.context)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockRedo(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun archiveDocument(command: CommandEntity.ArchiveDocument) {
val request: BlockList.Set.Page.IsArchived.Request = BlockList.Set.Page.IsArchived.Request(
contextId = command.context,
blockIds = command.target,
isArchived = command.isArchived
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListSetPageIsArchived(request)
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun turnIntoDocument(command: CommandEntity.TurnIntoDocument): List<String> {
val request = BlockList.ConvertChildrenToPages.Request(
contextId = command.context,
blockIds = command.targets
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.convertChildrenToPages(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.linkIds
}
@Throws(Exception::class)
fun paste(command: CommandEntity.Paste): Response.Clipboard.Paste {
val range = Range(
from = command.range.first,
to = command.range.last
)
val blocks: List<Block> = mapper.toMiddleware(command.blocks)
val request: Rpc.Block.Paste.Request = Rpc.Block.Paste.Request(
contextId = command.context,
focusedBlockId = command.focus,
textSlot = command.text,
htmlSlot = command.html.orEmpty(),
selectedTextRange = range,
anySlot = blocks,
selectedBlockIds = command.selected
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockPaste(request)
if (BuildConfig.DEBUG) logResponse(response)
return Response.Clipboard.Paste(
response.caretPosition,
response.isSameBlockCaret,
response.blockIds,
mapper.toPayload(response.event)
)
}
@Throws(Exception::class)
fun copy(command: CommandEntity.Copy): Response.Clipboard.Copy {
val range: Range? = command.range?.let {
Range(
from = it.first,
to = it.last
)
}
val blocks: List<Block> = mapper.toMiddleware(command.blocks)
val request = Rpc.Block.Copy.Request(
contextId = command.context,
selectedTextRange = range,
blocks = blocks
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockCopy(request)
if (BuildConfig.DEBUG) logResponse(response)
return Response.Clipboard.Copy(
response.textSlot,
response.htmlSlot,
mapper.toEntity(response.anySlot)
)
}
@Throws(Exception::class)
fun uploadFile(command: CommandEntity.UploadFile): Response.Media.Upload {
val type = when (command.type) {
BlockEntity.Content.File.Type.FILE -> Block.Content.File.Type.File
BlockEntity.Content.File.Type.IMAGE -> Block.Content.File.Type.Image
BlockEntity.Content.File.Type.VIDEO -> Block.Content.File.Type.Video
BlockEntity.Content.File.Type.NONE -> Block.Content.File.Type.None
}
val request = Rpc.UploadFile.Request(
localPath = command.path,
type = type
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.uploadFile(request)
if (BuildConfig.DEBUG) logResponse(response)
return Response.Media.Upload(response.hash)
}
@Throws(Exception::class)
fun getMiddlewareVersion(): Rpc.Version.Get.Response {
val request = Rpc.Version.Get.Request()
if (BuildConfig.DEBUG) logRequest(request)
val response = service.versionGet(request)
if (BuildConfig.DEBUG) logResponse(response)
return response
}
@Throws(Exception::class)
fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks {
val request = Rpc.Navigation.GetPageInfoWithLinks.Request(
pageId = pageId
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.pageInfoWithLinks(request)
if (BuildConfig.DEBUG) logResponse(response)
val info = response.page
checkNotNull(info) { "Empty result" }
return info
}
fun getListPages(): List<PageInfo> {
val request = Rpc.Navigation.ListPages.Request()
if (BuildConfig.DEBUG) logRequest(request)
val response = service.listPages(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.pages
}
@Throws(Exception::class)
fun linkToObject(
contextId: String,
targetId: String,
blockId: String,
replace: Boolean,
positionEntity: PositionEntity
): PayloadEntity {
val position: Block.Position = if (replace) {
Block.Position.Replace
} else {
mapper.toMiddleware(positionEntity)
}
val link = Block.Content.Link(targetBlockId = blockId)
val model = Block(link = link)
val request: Rpc.Block.Create.Request = Rpc.Block.Create.Request(
contextId = contextId,
targetId = targetId,
position = position,
block = model
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun updateDividerStyle(command: CommandEntity.UpdateDivider): PayloadEntity {
val style = when (command.style) {
BlockEntity.Content.Divider.Style.LINE -> Block.Content.Div.Style.Line
BlockEntity.Content.Divider.Style.DOTS -> Block.Content.Div.Style.Dots
}
val request: BlockList.Set.Div.Style.Request = BlockList.Set.Div.Style.Request(
contextId = command.context,
blockIds = command.targets,
style = style
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListSetDivStyle(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
@Throws(Exception::class)
fun setFields(command: CommandEntity.SetFields): PayloadEntity {
val fields: MutableList<BlockField> = ArrayList()
for (i in command.fields.indices) {
val (first, second) = command.fields[i]
val field = BlockField(
blockId = first,
fields = second.map
)
fields.add(field)
}
val request = BlockList.Set.Fields.Request(
contextId = command.context,
blockFields = fields
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockListSetFields(request)
if (BuildConfig.DEBUG) logResponse(response)
return mapper.toPayload(response.event)
}
private fun logRequest(any: Any) {
val message = "===> " + any::class.java.canonicalName + ":" + "\n" + any.toString()
Timber.d(message)
}
private fun logResponse(any: Any) {
val message = "<=== " + any::class.java.canonicalName + ":" + "\n" + any.toString()
Timber.d(message)
}
}

View file

@ -1,6 +1,6 @@
package com.anytypeio.anytype.middleware.interactor
import anytype.Events
import anytype.Event
import com.anytypeio.anytype.data.auth.event.EventRemoteChannel
import com.anytypeio.anytype.data.auth.model.EventEntity
import com.anytypeio.anytype.middleware.EventProxy
@ -12,24 +12,23 @@ class MiddlewareEventChannel(
private val events: EventProxy
) : EventRemoteChannel {
/**
* List of currently supported events.
* Other events will be ignored.
*/
private val supportedEvents = listOf(
Events.Event.Message.ValueCase.BLOCKSHOW,
Events.Event.Message.ValueCase.BLOCKADD,
Events.Event.Message.ValueCase.BLOCKSETTEXT,
Events.Event.Message.ValueCase.BLOCKSETCHILDRENIDS,
Events.Event.Message.ValueCase.BLOCKSETBACKGROUNDCOLOR,
Events.Event.Message.ValueCase.BLOCKSETDETAILS,
Events.Event.Message.ValueCase.BLOCKDELETE,
Events.Event.Message.ValueCase.BLOCKSETLINK,
Events.Event.Message.ValueCase.BLOCKSETFILE,
Events.Event.Message.ValueCase.BLOCKSETFIELDS,
Events.Event.Message.ValueCase.BLOCKSETBOOKMARK,
Events.Event.Message.ValueCase.BLOCKSETALIGN
)
private fun filter(msg: Event.Message): Boolean {
val events = listOf(
msg.blockShow,
msg.blockAdd,
msg.blockSetText,
msg.blockSetChildrenIds,
msg.blockSetBackgroundColor,
msg.blockSetDetails,
msg.blockDelete,
msg.blockSetLink,
msg.blockSetFile,
msg.blockSetFields,
msg.blockSetBookmark,
msg.blockSetAlign
)
return events.any { it != null }
}
override fun observeEvents(
context: String?
@ -37,14 +36,12 @@ class MiddlewareEventChannel(
.flow()
.filter { event -> context == null || event.contextId == context }
.map { event ->
event.messagesList.filter { message ->
supportedEvents.contains(message.valueCase)
}.map { message -> Pair(event.contextId, message) }
event.messages.filter { filter(it) }.map { message -> Pair(event.contextId, message) }
}
.filter { it.isNotEmpty() }
.map { events -> processEvents(events) }
private fun processEvents(events: List<Pair<String, Events.Event.Message>>): List<EventEntity.Command> {
private fun processEvents(events: List<Pair<String, Event.Message>>): List<EventEntity.Command> {
return events.mapNotNull { (context, event) -> event.toEntity(context) }
}
}

View file

@ -1,8 +1,8 @@
package com.anytypeio.anytype.middleware.interactor
import anytype.Events
import anytype.Events.Event
import anytype.model.Models
import anytype.Event
import anytype.SmartBlockType
import anytype.model.Block
import com.anytypeio.anytype.data.auth.model.BlockEntity
import com.anytypeio.anytype.data.auth.model.EventEntity
import com.anytypeio.anytype.middleware.converters.blocks
@ -12,162 +12,158 @@ import com.anytypeio.anytype.middleware.converters.marks
fun Event.Message.toEntity(
context: String
): EventEntity.Command? = when (valueCase) {
Event.Message.ValueCase.BLOCKADD -> {
): EventEntity.Command? = when {
blockAdd != null -> {
val event = blockAdd
checkNotNull(event)
EventEntity.Command.AddBlock(
context = context,
blocks = blockAdd.blocksList.blocks()
blocks = event.blocks.blocks()
)
}
Event.Message.ValueCase.BLOCKSHOW -> {
val type = when (blockShow.type) {
Events.SmartBlockType.Page -> EventEntity.Command.ShowBlock.Type.PAGE
Events.SmartBlockType.ProfilePage -> EventEntity.Command.ShowBlock.Type.PROFILE_PAGE
Events.SmartBlockType.Home -> EventEntity.Command.ShowBlock.Type.HOME
Events.SmartBlockType.Archive -> EventEntity.Command.ShowBlock.Type.ACHIVE
Events.SmartBlockType.Set -> EventEntity.Command.ShowBlock.Type.SET
Events.SmartBlockType.Breadcrumbs -> EventEntity.Command.ShowBlock.Type.BREADCRUMBS
else -> throw IllegalStateException("Unexpected smart block type: ${blockShow.type}")
blockShow != null -> {
val event = blockShow
checkNotNull(event)
val type = when (event.type) {
SmartBlockType.Page -> EventEntity.Command.ShowBlock.Type.PAGE
SmartBlockType.ProfilePage -> EventEntity.Command.ShowBlock.Type.PROFILE_PAGE
SmartBlockType.Home -> EventEntity.Command.ShowBlock.Type.HOME
SmartBlockType.Archive -> EventEntity.Command.ShowBlock.Type.ACHIVE
SmartBlockType.Set -> EventEntity.Command.ShowBlock.Type.SET
SmartBlockType.Breadcrumbs -> EventEntity.Command.ShowBlock.Type.BREADCRUMBS
else -> throw IllegalStateException("Unexpected smart block type: ${event.type}")
}
EventEntity.Command.ShowBlock(
context = context,
root = blockShow.rootId,
blocks = blockShow.blocksList.blocks(
types = mapOf(blockShow.rootId to blockShow.type)
root = event.rootId,
blocks = event.blocks.blocks(
types = mapOf(event.rootId to event.type)
),
details = BlockEntity.Details(
blockShow.detailsList.associate { details ->
event.details.associate { details ->
details.id to details.details.fields()
}
),
type = type
)
}
Event.Message.ValueCase.BLOCKSETTEXT -> {
blockSetText != null -> {
val event = blockSetText
checkNotNull(event)
EventEntity.Command.GranularChange(
context = context,
id = blockSetText.id,
text = if (blockSetText.hasText())
blockSetText.text.value
else null,
style = if (blockSetText.hasStyle())
blockSetText.style.value.entity()
else
null,
color = if (blockSetText.hasColor())
blockSetText.color.value
else
null,
marks = if (blockSetText.hasMarks())
blockSetText.marks.value.marksList.marks()
else
null,
checked = if (blockSetText.hasChecked())
blockSetText.checked.value
else
null
id = event.id,
text = event.text?.value,
style = event.style?.value?.entity(),
color = event.color?.value,
marks = event.marks?.value?.marks?.marks(),
checked = event.checked?.value
)
}
Event.Message.ValueCase.BLOCKSETBACKGROUNDCOLOR -> {
blockSetBackgroundColor != null -> {
val event = blockSetBackgroundColor
checkNotNull(event)
EventEntity.Command.GranularChange(
context = context,
id = blockSetBackgroundColor.id,
backgroundColor = blockSetBackgroundColor.backgroundColor
id = event.id,
backgroundColor = event.backgroundColor
)
}
Event.Message.ValueCase.BLOCKDELETE -> {
blockDelete != null -> {
val event = blockDelete
checkNotNull(event)
EventEntity.Command.DeleteBlock(
context = context,
targets = blockDelete.blockIdsList.toList()
targets = event.blockIds
)
}
Event.Message.ValueCase.BLOCKSETCHILDRENIDS -> {
blockSetChildrenIds != null -> {
val event = blockSetChildrenIds
checkNotNull(event)
EventEntity.Command.UpdateStructure(
context = context,
id = blockSetChildrenIds.id,
children = blockSetChildrenIds.childrenIdsList.toList()
id = event.id,
children = event.childrenIds
)
}
Event.Message.ValueCase.BLOCKSETDETAILS -> {
blockSetDetails != null -> {
val event = blockSetDetails
checkNotNull(event)
EventEntity.Command.UpdateDetails(
context = context,
target = blockSetDetails.id,
details = blockSetDetails.details.fields()
target = event.id,
details = event.details.fields()
)
}
Event.Message.ValueCase.BLOCKSETLINK -> {
blockSetLink != null -> {
val event = blockSetLink
checkNotNull(event)
EventEntity.Command.LinkGranularChange(
context = context,
id = blockSetLink.id,
target = blockSetLink.targetBlockId.value,
fields = if (blockSetLink.hasFields())
blockSetLink.fields.value.fields()
else
null
id = event.id,
target = event.targetBlockId?.value.orEmpty(),
fields = event.fields?.value.fields()
)
}
Event.Message.ValueCase.BLOCKSETALIGN -> {
blockSetAlign != null -> {
val event = blockSetAlign
checkNotNull(event)
EventEntity.Command.GranularChange(
context = context,
id = blockSetAlign.id,
alignment = blockSetAlign.align.entity()
id = event.id,
alignment = event.align.entity()
)
}
Event.Message.ValueCase.BLOCKSETFIELDS -> {
blockSetFields != null -> {
val event = blockSetFields
checkNotNull(event)
EventEntity.Command.UpdateFields(
context = context,
target = blockSetFields.id,
fields = blockSetFields.fields.fields()
target = event.id,
fields = event.fields.fields()
)
}
Event.Message.ValueCase.BLOCKSETFILE -> {
with(blockSetFile) {
blockSetFile != null -> {
val event = blockSetFile
checkNotNull(event)
with(event) {
EventEntity.Command.UpdateBlockFile(
context = context,
id = id,
state = if (hasState()) state.value.entity() else null,
type = if (hasType()) type.value.entity() else null,
name = if (hasName()) name.value else null,
hash = if (hasHash()) hash.value else null,
mime = if (hasMime()) mime.value else null,
size = if (hasSize()) size.value else null
state = state?.value?.entity(),
type = type?.value?.entity(),
name = name?.value,
hash = hash?.value,
mime = mime?.value,
size = size?.value
)
}
}
Event.Message.ValueCase.BLOCKSETBOOKMARK -> {
blockSetBookmark != null -> {
val event = blockSetBookmark
checkNotNull(event)
EventEntity.Command.BookmarkGranularChange(
context = context,
target = blockSetBookmark.id,
url = if (blockSetBookmark.hasUrl())
blockSetBookmark.url.value
else null,
title = if (blockSetBookmark.hasTitle())
blockSetBookmark.title.value
else
null,
description = if (blockSetBookmark.hasDescription())
blockSetBookmark.description.value
else
null,
imageHash = if (blockSetBookmark.hasImageHash())
blockSetBookmark.imageHash.value
else
null,
faviconHash = if (blockSetBookmark.hasFaviconHash())
blockSetBookmark.faviconHash.value
else
null
target = event.id,
url = event.url?.value,
title = event.title?.value,
description = event.description?.value,
imageHash = event.imageHash?.value,
faviconHash = event.faviconHash?.value
)
}
Event.Message.ValueCase.BLOCKSETDIV -> {
val style = when (blockSetDiv.style.value) {
Models.Block.Content.Div.Style.Line -> BlockEntity.Content.Divider.Style.LINE
Models.Block.Content.Div.Style.Dots -> BlockEntity.Content.Divider.Style.DOTS
else -> throw IllegalStateException("Unexpected divider block style: ${blockSetDiv.style.value}")
blockSetDiv != null -> {
val event = blockSetDiv
checkNotNull(event)
val style = when (event.style?.value) {
Block.Content.Div.Style.Line -> BlockEntity.Content.Divider.Style.LINE
Block.Content.Div.Style.Dots -> BlockEntity.Content.Divider.Style.DOTS
else -> throw IllegalStateException("Unexpected divider block style: ${event.style?.value}")
}
EventEntity.Command.UpdateDivider(
context = context,
id = blockSetDiv.id,
id = event.id,
style = style
)
}

View file

@ -1,52 +1,40 @@
package com.anytypeio.anytype.middleware.interactor
import anytype.model.Models.Block
import anytype.model.Block
import com.anytypeio.anytype.data.auth.model.BlockEntity
import com.anytypeio.anytype.middleware.converters.state
import com.anytypeio.anytype.middleware.converters.toMiddleware
import com.anytypeio.anytype.middleware.converters.type
import com.anytypeio.anytype.middleware.converters.*
class MiddlewareFactory {
fun create(prototype: BlockEntity.Prototype): Block {
val builder = Block.newBuilder()
return when (prototype) {
is BlockEntity.Prototype.Bookmark -> {
val bookmark = Block.Content.Bookmark.getDefaultInstance()
builder.setBookmark(bookmark).build()
Block(bookmark = Bookmark())
}
is BlockEntity.Prototype.Text -> {
val text = Block.Content.Text.newBuilder().apply {
style = prototype.style.toMiddleware()
}
builder.setText(text).build()
val text = Block.Content.Text(style = prototype.style.toMiddleware())
Block(text = text)
}
is BlockEntity.Prototype.DividerLine -> {
val divider = Block.Content.Div.newBuilder().apply {
style = Block.Content.Div.Style.Line
}
builder.setDiv(divider).build()
val divider = Block.Content.Div(style = Block.Content.Div.Style.Line)
Block(div = divider)
}
is BlockEntity.Prototype.DividerDots -> {
val divider = Block.Content.Div.newBuilder().apply {
style = Block.Content.Div.Style.Dots
}
builder.setDiv(divider).build()
val divider = Block.Content.Div(style = Block.Content.Div.Style.Dots)
Block(div = divider)
}
is BlockEntity.Prototype.File -> {
val file = Block.Content.File.newBuilder().apply {
state = prototype.state.state()
val file = File(
state = prototype.state.state(),
type = prototype.type.type()
}
builder.setFile(file).build()
)
Block(file_ = file)
}
is BlockEntity.Prototype.Link -> {
val link = Block.Content.Link.newBuilder().apply {
val link = Block.Content.Link(
targetBlockId = prototype.target
}
builder.setLink(link).build()
)
Block(link = link)
}
else -> throw IllegalStateException("Unexpected prototype: $prototype")
}

View file

@ -1,16 +1,14 @@
package com.anytypeio.anytype.middleware.interactor
import anytype.Commands
import anytype.Events
import anytype.model.Models.Block
import anytype.ResponseEvent
import anytype.Rpc
import anytype.model.Block
import com.anytypeio.anytype.data.auth.model.BlockEntity
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 {
@ -26,21 +24,23 @@ class MiddlewareMapper {
return position.toMiddleware()
}
fun toMiddleware(mode: BlockEntity.Content.Text.SplitMode): Commands.Rpc.Block.Split.Request.Mode {
fun toMiddleware(mode: BlockEntity.Content.Text.SplitMode): Rpc.Block.Split.Request.Mode {
return when (mode) {
BlockEntity.Content.Text.SplitMode.BOTTOM -> Commands.Rpc.Block.Split.Request.Mode.BOTTOM
BlockEntity.Content.Text.SplitMode.TOP -> Commands.Rpc.Block.Split.Request.Mode.TOP
BlockEntity.Content.Text.SplitMode.INNER -> Commands.Rpc.Block.Split.Request.Mode.INNER
BlockEntity.Content.Text.SplitMode.BOTTOM -> Rpc.Block.Split.Request.Mode.BOTTOM
BlockEntity.Content.Text.SplitMode.TOP -> Rpc.Block.Split.Request.Mode.TOP
BlockEntity.Content.Text.SplitMode.INNER -> Rpc.Block.Split.Request.Mode.INNER
}
}
fun toPayload(response: Events.ResponseEvent): PayloadEntity {
fun toPayload(response: ResponseEvent?): PayloadEntity {
checkNotNull(response)
val context = response.contextId
return PayloadEntity(
context = context,
events = response.messagesList.mapNotNull { it.toEntity(context) }
events = response.messages.mapNotNull { it.toEntity(context) }
)
}
@ -51,8 +51,4 @@ class MiddlewareMapper {
fun toEntity(blocks: List<Block>): List<BlockEntity> {
return blocks.blocks()
}
fun toMiddleware(fields: BlockEntity.Fields): Struct {
return fields.fields()
}
}

View file

@ -1,9 +1,9 @@
package com.anytypeio.anytype.middleware.model
import anytype.model.Models.Account.Avatar
import anytype.model.Account.Avatar
class CreateAccountResponse(
val id: String,
val name: String,
val avatar: Avatar
val avatar: Avatar? = null
)

View file

@ -1,9 +1,10 @@
package com.anytypeio.anytype.middleware.model
import anytype.model.Models.Account.Avatar
import anytype.model.Account
class SelectAccountResponse(
val id: String,
val name: String,
val avatar: Avatar
val avatar: Account.Avatar?
)

View file

@ -1,449 +0,0 @@
package com.anytypeio.anytype.middleware.service;
import com.anytypeio.anytype.data.auth.exception.BackwardCompatilityNotSupportedException;
import anytype.Commands;
import anytype.Commands.Rpc.Account;
import anytype.Commands.Rpc.Block;
import anytype.Commands.Rpc.BlockList;
import anytype.Commands.Rpc.Config;
import anytype.Commands.Rpc.Navigation;
import anytype.Commands.Rpc.UploadFile;
import anytype.Commands.Rpc.Wallet;
import service.Service;
public class DefaultMiddlewareService implements MiddlewareService {
@Override
public Config.Get.Response configGet(Config.Get.Request request) throws Exception {
byte[] encoded = Service.configGet(request.toByteArray());
Config.Get.Response response = Config.Get.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Config.Get.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Wallet.Create.Response walletCreate(Wallet.Create.Request request) throws Exception {
byte[] encoded = Service.walletCreate(request.toByteArray());
Wallet.Create.Response response = Wallet.Create.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Wallet.Create.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Wallet.Convert.Response walletConvert(Wallet.Convert.Request request) throws Exception {
byte[] encoded = Service.walletConvert(request.toByteArray());
Wallet.Convert.Response response = Wallet.Convert.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Wallet.Convert.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Account.Create.Response accountCreate(Account.Create.Request request) throws Exception {
byte[] encoded = Service.accountCreate(request.toByteArray());
Account.Create.Response response = Account.Create.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Account.Create.Response.Error.Code.NULL) {
throw new Exception(response.getError().getCode().name() + "," + response.getError().getDescription());
} else {
return response;
}
}
@Override
public Wallet.Recover.Response walletRecover(Wallet.Recover.Request request) throws Exception {
byte[] encoded = Service.walletRecover(request.toByteArray());
Wallet.Recover.Response response = Wallet.Recover.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Wallet.Recover.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Account.Recover.Response accountRecover(Account.Recover.Request request) throws Exception {
byte[] encoded = Service.accountRecover(request.toByteArray());
Account.Recover.Response response = Account.Recover.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Account.Recover.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Account.Stop.Response accountStop(Account.Stop.Request request) throws Exception {
byte[] encoded = Service.accountStop(request.toByteArray());
Account.Stop.Response response = Account.Stop.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Account.Stop.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Account.Select.Response accountSelect(Account.Select.Request request) throws Exception {
byte[] encoded = Service.accountSelect(request.toByteArray());
Account.Select.Response response = Account.Select.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Account.Select.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Open.Response blockOpen(Block.Open.Request request) throws Exception {
byte[] encoded = Service.blockOpen(request.toByteArray());
Block.Open.Response response = Block.Open.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Open.Response.Error.Code.NULL) {
if (response.getError().getCode() == Block.Open.Response.Error.Code.ANYTYPE_NEEDS_UPGRADE) {
throw new BackwardCompatilityNotSupportedException();
} else {
throw new Exception(response.getError().getDescription());
}
} else {
return response;
}
}
@Override
public Block.Close.Response blockClose(Block.Close.Request request) throws Exception {
byte[] encoded = Service.blockClose(request.toByteArray());
Block.Close.Response response = Block.Close.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Close.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Create.Response blockCreate(Block.Create.Request request) throws Exception {
byte[] encoded = Service.blockCreate(request.toByteArray());
Block.Create.Response response = Block.Create.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Create.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.CreatePage.Response blockCreatePage(Block.CreatePage.Request request) throws Exception {
byte[] encoded = Service.blockCreatePage(request.toByteArray());
Block.CreatePage.Response response = Block.CreatePage.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.CreatePage.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Set.Text.TText.Response blockSetTextText(Block.Set.Text.TText.Request request) throws Exception {
byte[] encoded = Service.blockSetTextText(request.toByteArray());
Block.Set.Text.TText.Response response = Block.Set.Text.TText.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Set.Text.TText.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Set.Text.Checked.Response blockSetTextChecked(Block.Set.Text.Checked.Request request) throws Exception {
byte[] encoded = Service.blockSetTextChecked(request.toByteArray());
Block.Set.Text.Checked.Response response = Block.Set.Text.Checked.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Set.Text.Checked.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Set.Text.Style.Response blockSetTextStyle(BlockList.Set.Text.Style.Request request) throws Exception {
byte[] encoded = Service.blockListSetTextStyle(request.toByteArray());
BlockList.Set.Text.Style.Response response = BlockList.Set.Text.Style.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Set.Text.Style.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Set.Text.Color.Response blockSetTextColor(Block.Set.Text.Color.Request request) throws Exception {
byte[] encoded = Service.blockSetTextColor(request.toByteArray());
Block.Set.Text.Color.Response response = Block.Set.Text.Color.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Set.Text.Color.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Set.BackgroundColor.Response blockSetTextBackgroundColor(BlockList.Set.BackgroundColor.Request request) throws Exception {
byte[] encoded = Service.blockListSetBackgroundColor(request.toByteArray());
BlockList.Set.BackgroundColor.Response response = BlockList.Set.BackgroundColor.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Set.BackgroundColor.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Set.Align.Response blockSetAlignment(BlockList.Set.Align.Request request) throws Exception {
byte[] encoded = Service.blockListSetAlign(request.toByteArray());
BlockList.Set.Align.Response response = BlockList.Set.Align.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Set.Align.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Move.Response blockListMove(BlockList.Move.Request request) throws Exception {
byte[] encoded = Service.blockListMove(request.toByteArray());
BlockList.Move.Response response = BlockList.Move.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Move.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Unlink.Response blockUnlink(Block.Unlink.Request request) throws Exception {
byte[] encoded = Service.blockUnlink(request.toByteArray());
Block.Unlink.Response response = Block.Unlink.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Unlink.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Merge.Response blockMerge(Block.Merge.Request request) throws Exception {
byte[] encoded = Service.blockMerge(request.toByteArray());
Block.Merge.Response response = Block.Merge.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Merge.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Split.Response blockSplit(Block.Split.Request request) throws Exception {
byte[] encoded = Service.blockSplit(request.toByteArray());
Block.Split.Response response = Block.Split.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Split.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Duplicate.Response blockListDuplicate(BlockList.Duplicate.Request request) throws Exception {
byte[] encoded = Service.blockListDuplicate(request.toByteArray());
BlockList.Duplicate.Response response = BlockList.Duplicate.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Duplicate.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.ConvertChildrenToPages.Response convertChildrenToPages(BlockList.ConvertChildrenToPages.Request request) throws Exception {
byte[] encoded = Service.blockListConvertChildrenToPages(request.toByteArray());
BlockList.ConvertChildrenToPages.Response response = BlockList.ConvertChildrenToPages.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.ConvertChildrenToPages.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Upload.Response blockUpload(Block.Upload.Request request) throws Exception {
byte[] encoded = Service.blockUpload(request.toByteArray());
Block.Upload.Response response = Block.Upload.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Upload.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Bookmark.Fetch.Response blockBookmarkFetch(Block.Bookmark.Fetch.Request request) throws Exception {
byte[] encoded = Service.blockBookmarkFetch(request.toByteArray());
Block.Bookmark.Fetch.Response response = Block.Bookmark.Fetch.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Bookmark.Fetch.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Undo.Response blockUndo(Block.Undo.Request request) throws Exception {
byte[] encoded = Service.blockUndo(request.toByteArray());
Block.Undo.Response response = Block.Undo.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Undo.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Redo.Response blockRedo(Block.Redo.Request request) throws Exception {
byte[] encoded = Service.blockRedo(request.toByteArray());
Block.Redo.Response response = Block.Redo.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Redo.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Set.Page.IsArchived.Response blockListSetPageIsArchived(BlockList.Set.Page.IsArchived.Request request) throws Exception {
byte[] encoded = Service.blockListSetPageIsArchived(request.toByteArray());
BlockList.Set.Page.IsArchived.Response response = BlockList.Set.Page.IsArchived.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Set.Page.IsArchived.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Set.Details.Response blockSetDetails(Block.Set.Details.Request request) throws Exception {
byte[] encoded = Service.blockSetDetails(request.toByteArray());
Block.Set.Details.Response response = Block.Set.Details.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Set.Details.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Paste.Response blockPaste(Block.Paste.Request request) throws Exception {
byte[] encoded = Service.blockPaste(request.toByteArray());
Block.Paste.Response response = Block.Paste.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Paste.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Block.Copy.Response blockCopy(Block.Copy.Request request) throws Exception {
byte[] encoded = Service.blockCopy(request.toByteArray());
Block.Copy.Response response = Block.Copy.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Block.Copy.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public UploadFile.Response uploadFile(UploadFile.Request request) throws Exception {
byte[] encoded = Service.uploadFile(request.toByteArray());
UploadFile.Response response = UploadFile.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != UploadFile.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Navigation.GetPageInfoWithLinks.Response pageInfoWithLinks(Navigation.GetPageInfoWithLinks.Request request) throws Exception {
byte[] encoded = Service.navigationGetPageInfoWithLinks(request.toByteArray());
Navigation.GetPageInfoWithLinks.Response response = Navigation.GetPageInfoWithLinks.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Navigation.GetPageInfoWithLinks.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Navigation.ListPages.Response listPages(Navigation.ListPages.Request request) throws Exception {
byte[] encoded = Service.navigationListPages(request.toByteArray());
Navigation.ListPages.Response response = Navigation.ListPages.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Navigation.ListPages.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Commands.Rpc.Page.Create.Response pageCreate(Commands.Rpc.Page.Create.Request request) throws Exception {
byte[] encoded = Service.pageCreate(request.toByteArray());
Commands.Rpc.Page.Create.Response response = Commands.Rpc.Page.Create.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Commands.Rpc.Page.Create.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public Commands.Rpc.Version.Get.Response getVersion(Commands.Rpc.Version.Get.Request request) throws Exception {
byte[] encoded = Service.versionGet(request.toByteArray());
Commands.Rpc.Version.Get.Response response = Commands.Rpc.Version.Get.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != Commands.Rpc.Version.Get.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
return response;
}
}
@Override
public BlockList.Set.Div.Style.Response blockListSetDivStyle(BlockList.Set.Div.Style.Request request) throws Exception {
byte[] encoded = Service.blockListSetDivStyle(request.toByteArray());
BlockList.Set.Div.Style.Response response = BlockList.Set.Div.Style.Response.parseFrom(encoded);
if (response.getError() != null && response.getError().getCode() != BlockList.Set.Div.Style.Response.Error.Code.NULL) {
throw new Exception(response.getError().getDescription());
} else {
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;
}
}
}

View file

@ -1,93 +0,0 @@
package com.anytypeio.anytype.middleware.service;
import anytype.Commands;
import anytype.Commands.Rpc.Account;
import anytype.Commands.Rpc.Block;
import anytype.Commands.Rpc.BlockList;
import anytype.Commands.Rpc.Config;
import anytype.Commands.Rpc.Navigation;
import anytype.Commands.Rpc.UploadFile;
import anytype.Commands.Rpc.Wallet;
/**
* Service for interacting with the backend.
*/
public interface MiddlewareService {
Config.Get.Response configGet(Config.Get.Request request) throws Exception;
Wallet.Create.Response walletCreate(Wallet.Create.Request request) throws Exception;
Wallet.Convert.Response walletConvert(Wallet.Convert.Request request) throws Exception;
Wallet.Recover.Response walletRecover(Wallet.Recover.Request request) throws Exception;
Account.Create.Response accountCreate(Account.Create.Request request) throws Exception;
Account.Select.Response accountSelect(Account.Select.Request request) throws Exception;
Account.Recover.Response accountRecover(Account.Recover.Request request) throws Exception;
Account.Stop.Response accountStop(Account.Stop.Request request) throws Exception;
Block.Open.Response blockOpen(Block.Open.Request request) throws Exception;
Block.Close.Response blockClose(Block.Close.Request request) throws Exception;
Block.Create.Response blockCreate(Block.Create.Request request) throws Exception;
Block.CreatePage.Response blockCreatePage(Block.CreatePage.Request request) throws Exception;
Block.Set.Text.TText.Response blockSetTextText(Block.Set.Text.TText.Request request) throws Exception;
Block.Set.Text.Checked.Response blockSetTextChecked(Block.Set.Text.Checked.Request request) throws Exception;
Block.Set.Text.Color.Response blockSetTextColor(Block.Set.Text.Color.Request request) throws Exception;
BlockList.Set.BackgroundColor.Response blockSetTextBackgroundColor(BlockList.Set.BackgroundColor.Request request) throws Exception;
BlockList.Set.Align.Response blockSetAlignment(BlockList.Set.Align.Request request) throws Exception;
BlockList.Set.Text.Style.Response blockSetTextStyle(BlockList.Set.Text.Style.Request request) throws Exception;
BlockList.Set.Div.Style.Response blockListSetDivStyle(BlockList.Set.Div.Style.Request request) throws Exception;
BlockList.Move.Response blockListMove(BlockList.Move.Request request) throws Exception;
Block.Unlink.Response blockUnlink(Block.Unlink.Request request) throws Exception;
Block.Merge.Response blockMerge(Block.Merge.Request request) throws Exception;
Block.Split.Response blockSplit(Block.Split.Request request) throws Exception;
BlockList.Duplicate.Response blockListDuplicate(BlockList.Duplicate.Request request) throws Exception;
BlockList.ConvertChildrenToPages.Response convertChildrenToPages(BlockList.ConvertChildrenToPages.Request request) throws Exception;
Block.Bookmark.Fetch.Response blockBookmarkFetch(Block.Bookmark.Fetch.Request request) throws Exception;
Block.Upload.Response blockUpload(Block.Upload.Request request) throws Exception;
Block.Undo.Response blockUndo(Block.Undo.Request request) throws Exception;
Block.Redo.Response blockRedo(Block.Redo.Request request) throws Exception;
BlockList.Set.Page.IsArchived.Response blockListSetPageIsArchived(BlockList.Set.Page.IsArchived.Request request) throws Exception;
Block.Set.Details.Response blockSetDetails(Block.Set.Details.Request request) throws Exception;
Block.Paste.Response blockPaste(Block.Paste.Request request) throws Exception;
Block.Copy.Response blockCopy(Block.Copy.Request request) throws Exception;
UploadFile.Response uploadFile(UploadFile.Request request) throws Exception;
Navigation.GetPageInfoWithLinks.Response pageInfoWithLinks(Navigation.GetPageInfoWithLinks.Request request) throws Exception;
Navigation.ListPages.Response listPages(Navigation.ListPages.Request request) throws Exception;
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;
}

View file

@ -0,0 +1,126 @@
package com.anytypeio.anytype.middleware.service
import anytype.Rpc.*
import kotlin.jvm.Throws
/**
* Service for interacting with the backend.
*/
interface MiddlewareService {
@Throws(Exception::class)
fun configGet(request: Config.Get.Request): Config.Get.Response
@Throws(Exception::class)
fun walletCreate(request: Wallet.Create.Request): Wallet.Create.Response
@Throws(Exception::class)
fun walletConvert(request: Wallet.Convert.Request): Wallet.Convert.Response
@Throws(Exception::class)
fun walletRecover(request: Wallet.Recover.Request): Wallet.Recover.Response
@Throws(Exception::class)
fun accountCreate(request: Account.Create.Request): Account.Create.Response
@Throws(Exception::class)
fun accountSelect(request: Account.Select.Request): Account.Select.Response
@Throws(Exception::class)
fun accountRecover(request: Account.Recover.Request): Account.Recover.Response
@Throws(Exception::class)
fun accountStop(request: Account.Stop.Request): Account.Stop.Response
@Throws(Exception::class)
fun blockOpen(request: Block.Open.Request): Block.Open.Response
@Throws(Exception::class)
fun blockClose(request: Block.Close.Request): Block.Close.Response
@Throws(Exception::class)
fun blockCreate(request: Block.Create.Request): Block.Create.Response
@Throws(Exception::class)
fun blockCreatePage(request: Block.CreatePage.Request): Block.CreatePage.Response
@Throws(Exception::class)
fun blockSetTextText(request: Block.Set.Text.TText.Request): Block.Set.Text.TText.Response
@Throws(Exception::class)
fun blockSetTextChecked(request: Block.Set.Text.Checked.Request): Block.Set.Text.Checked.Response
@Throws(Exception::class)
fun blockSetTextColor(request: Block.Set.Text.Color.Request): Block.Set.Text.Color.Response
@Throws(Exception::class)
fun blockListSetBackgroundColor(request: BlockList.Set.BackgroundColor.Request): BlockList.Set.BackgroundColor.Response
@Throws(Exception::class)
fun blockListSetAlign(request: BlockList.Set.Align.Request): BlockList.Set.Align.Response
@Throws(Exception::class)
fun blockListSetTextStyle(request: BlockList.Set.Text.Style.Request): BlockList.Set.Text.Style.Response
@Throws(Exception::class)
fun blockListSetDivStyle(request: BlockList.Set.Div.Style.Request): BlockList.Set.Div.Style.Response
@Throws(Exception::class)
fun blockListMove(request: BlockList.Move.Request): BlockList.Move.Response
@Throws(Exception::class)
fun blockUnlink(request: Block.Unlink.Request): Block.Unlink.Response
@Throws(Exception::class)
fun blockMerge(request: Block.Merge.Request): Block.Merge.Response
@Throws(Exception::class)
fun blockSplit(request: Block.Split.Request): Block.Split.Response
@Throws(Exception::class)
fun blockListDuplicate(request: BlockList.Duplicate.Request): BlockList.Duplicate.Response
@Throws(Exception::class)
fun convertChildrenToPages(request: BlockList.ConvertChildrenToPages.Request): BlockList.ConvertChildrenToPages.Response
@Throws(Exception::class)
fun blockBookmarkFetch(request: Block.Bookmark.Fetch.Request): Block.Bookmark.Fetch.Response
@Throws(Exception::class)
fun blockUpload(request: Block.Upload.Request): Block.Upload.Response
@Throws(Exception::class)
fun blockUndo(request: Block.Undo.Request): Block.Undo.Response
@Throws(Exception::class)
fun blockRedo(request: Block.Redo.Request): Block.Redo.Response
@Throws(Exception::class)
fun blockListSetPageIsArchived(request: BlockList.Set.Page.IsArchived.Request): BlockList.Set.Page.IsArchived.Response
@Throws(Exception::class)
fun blockSetDetails(request: Block.Set.Details.Request): Block.Set.Details.Response
@Throws(Exception::class)
fun blockPaste(request: Block.Paste.Request): Block.Paste.Response
@Throws(Exception::class)
fun blockCopy(request: Block.Copy.Request): Block.Copy.Response
@Throws(Exception::class)
fun uploadFile(request: UploadFile.Request): UploadFile.Response
@Throws(Exception::class)
fun pageInfoWithLinks(request: Navigation.GetPageInfoWithLinks.Request): Navigation.GetPageInfoWithLinks.Response
@Throws(Exception::class)
fun listPages(request: Navigation.ListPages.Request): Navigation.ListPages.Response
@Throws(Exception::class)
fun pageCreate(request: Page.Create.Request): Page.Create.Response
@Throws(Exception::class)
fun versionGet(request: Version.Get.Request): Version.Get.Response
@Throws(Exception::class)
fun blockListSetFields(request: BlockList.Set.Fields.Request): BlockList.Set.Fields.Response
}

View file

@ -0,0 +1,458 @@
package com.anytypeio.anytype.middleware.service
import anytype.Rpc.*
import anytype.Rpc.Config
import service.Service
class MiddlewareServiceImplementation : MiddlewareService {
override fun configGet(request: Config.Get.Request): Config.Get.Response {
val encoded = Service.configGet(Config.Get.Request.ADAPTER.encode(request))
val response = Config.Get.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Config.Get.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun walletCreate(request: Wallet.Create.Request): Wallet.Create.Response {
val encoded = Service.walletCreate(Wallet.Create.Request.ADAPTER.encode(request))
val response = Wallet.Create.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Wallet.Create.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun walletConvert(request: Wallet.Convert.Request): Wallet.Convert.Response {
val encoded = Service.walletConvert(Wallet.Convert.Request.ADAPTER.encode(request))
val response = Wallet.Convert.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Wallet.Convert.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun walletRecover(request: Wallet.Recover.Request): Wallet.Recover.Response {
val encoded = Service.walletRecover(Wallet.Recover.Request.ADAPTER.encode(request))
val response = Wallet.Recover.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Wallet.Recover.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun accountCreate(request: Account.Create.Request): Account.Create.Response {
val encoded = Service.accountCreate(Account.Create.Request.ADAPTER.encode(request))
val response = Account.Create.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Account.Create.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun accountSelect(request: Account.Select.Request): Account.Select.Response {
val encoded = Service.accountSelect(Account.Select.Request.ADAPTER.encode(request))
val response = Account.Select.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Account.Select.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun accountRecover(request: Account.Recover.Request): Account.Recover.Response {
val encoded = Service.accountRecover(Account.Recover.Request.ADAPTER.encode(request))
val response = Account.Recover.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Account.Recover.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun accountStop(request: Account.Stop.Request): Account.Stop.Response {
val encoded = Service.accountStop(Account.Stop.Request.ADAPTER.encode(request))
val response = Account.Stop.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Account.Stop.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockOpen(request: Block.Open.Request): Block.Open.Response {
val encoded = Service.blockOpen(Block.Open.Request.ADAPTER.encode(request))
val response = Block.Open.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Open.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockClose(request: Block.Close.Request): Block.Close.Response {
val encoded = Service.blockClose(Block.Close.Request.ADAPTER.encode(request))
val response = Block.Close.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Close.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockCreate(request: Block.Create.Request): Block.Create.Response {
val encoded = Service.blockCreate(Block.Create.Request.ADAPTER.encode(request))
val response = Block.Create.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Create.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockCreatePage(request: Block.CreatePage.Request): Block.CreatePage.Response {
val encoded = Service.blockCreatePage(Block.CreatePage.Request.ADAPTER.encode(request))
val response = Block.CreatePage.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.CreatePage.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockSetTextText(request: Block.Set.Text.TText.Request): Block.Set.Text.TText.Response {
val encoded = Service.blockSetTextText(Block.Set.Text.TText.Request.ADAPTER.encode(request))
val response = Block.Set.Text.TText.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Set.Text.TText.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockSetTextChecked(request: Block.Set.Text.Checked.Request): Block.Set.Text.Checked.Response {
val encoded = Service.blockSetTextChecked(
Block.Set.Text.Checked.Request.ADAPTER.encode(request)
)
val response = Block.Set.Text.Checked.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Set.Text.Checked.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockSetTextColor(request: Block.Set.Text.Color.Request): Block.Set.Text.Color.Response {
val encoded = Service.blockSetTextColor(
Block.Set.Text.Color.Request.ADAPTER.encode(request)
)
val response = Block.Set.Text.Color.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Set.Text.Color.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListSetBackgroundColor(request: BlockList.Set.BackgroundColor.Request): BlockList.Set.BackgroundColor.Response {
val encoded = Service.blockListSetBackgroundColor(
BlockList.Set.BackgroundColor.Request.ADAPTER.encode(request)
)
val response = BlockList.Set.BackgroundColor.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Set.BackgroundColor.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListSetAlign(request: BlockList.Set.Align.Request): BlockList.Set.Align.Response {
val encoded = Service.blockListSetAlign(BlockList.Set.Align.Request.ADAPTER.encode(request))
val response = BlockList.Set.Align.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Set.Align.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListSetTextStyle(request: BlockList.Set.Text.Style.Request): BlockList.Set.Text.Style.Response {
val encoded =
Service.blockListSetTextStyle(BlockList.Set.Text.Style.Request.ADAPTER.encode(request))
val response = BlockList.Set.Text.Style.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Set.Text.Style.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListSetDivStyle(request: BlockList.Set.Div.Style.Request): BlockList.Set.Div.Style.Response {
val encoded =
Service.blockListSetDivStyle(BlockList.Set.Div.Style.Request.ADAPTER.encode(request))
val response = BlockList.Set.Div.Style.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Set.Div.Style.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListMove(request: BlockList.Move.Request): BlockList.Move.Response {
val encoded = Service.blockListMove(BlockList.Move.Request.ADAPTER.encode(request))
val response = BlockList.Move.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Move.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockUnlink(request: Block.Unlink.Request): Block.Unlink.Response {
val encoded = Service.blockUnlink(Block.Unlink.Request.ADAPTER.encode(request))
val response = Block.Unlink.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Unlink.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockMerge(request: Block.Merge.Request): Block.Merge.Response {
val encoded = Service.blockMerge(Block.Merge.Request.ADAPTER.encode(request))
val response = Block.Merge.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Merge.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockSplit(request: Block.Split.Request): Block.Split.Response {
val encoded = Service.blockSplit(Block.Split.Request.ADAPTER.encode(request))
val response = Block.Split.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Split.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListDuplicate(request: BlockList.Duplicate.Request): BlockList.Duplicate.Response {
val encoded = Service.blockListDuplicate(
BlockList.Duplicate.Request.ADAPTER.encode(request)
)
val response = BlockList.Duplicate.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Duplicate.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun convertChildrenToPages(request: BlockList.ConvertChildrenToPages.Request): BlockList.ConvertChildrenToPages.Response {
val encoded = Service.blockListConvertChildrenToPages(
BlockList.ConvertChildrenToPages.Request.ADAPTER.encode(request)
)
val response = BlockList.ConvertChildrenToPages.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.ConvertChildrenToPages.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockBookmarkFetch(request: Block.Bookmark.Fetch.Request): Block.Bookmark.Fetch.Response {
val encoded = Service.blockBookmarkFetch(
Block.Bookmark.Fetch.Request.ADAPTER.encode(request)
)
val response = Block.Bookmark.Fetch.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Bookmark.Fetch.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockUpload(request: Block.Upload.Request): Block.Upload.Response {
val encoded = Service.blockUpload(Block.Upload.Request.ADAPTER.encode(request))
val response = Block.Upload.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Upload.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockUndo(request: Block.Undo.Request): Block.Undo.Response {
val encoded = Service.blockUndo(Block.Undo.Request.ADAPTER.encode(request))
val response = Block.Undo.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Undo.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockRedo(request: Block.Redo.Request): Block.Redo.Response {
val encoded = Service.blockRedo(Block.Redo.Request.ADAPTER.encode(request))
val response = Block.Redo.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Redo.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListSetPageIsArchived(request: BlockList.Set.Page.IsArchived.Request): BlockList.Set.Page.IsArchived.Response {
val encoded = Service.blockListSetPageIsArchived(
BlockList.Set.Page.IsArchived.Request.ADAPTER.encode(request)
)
val response = BlockList.Set.Page.IsArchived.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Set.Page.IsArchived.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockSetDetails(request: Block.Set.Details.Request): Block.Set.Details.Response {
val encoded = Service.blockSetDetails(Block.Set.Details.Request.ADAPTER.encode(request))
val response = Block.Set.Details.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Set.Details.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockPaste(request: Block.Paste.Request): Block.Paste.Response {
val encoded = Service.blockPaste(Block.Paste.Request.ADAPTER.encode(request))
val response = Block.Paste.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Paste.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockCopy(request: Block.Copy.Request): Block.Copy.Response {
val encoded = Service.blockCopy(Block.Copy.Request.ADAPTER.encode(request))
val response = Block.Copy.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Block.Copy.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun uploadFile(request: UploadFile.Request): UploadFile.Response {
val encoded = Service.uploadFile(UploadFile.Request.ADAPTER.encode(request))
val response = UploadFile.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != UploadFile.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun pageInfoWithLinks(request: Navigation.GetPageInfoWithLinks.Request): Navigation.GetPageInfoWithLinks.Response {
val encoded = Service.navigationGetPageInfoWithLinks(
Navigation.GetPageInfoWithLinks.Request.ADAPTER.encode(request)
)
val response = Navigation.GetPageInfoWithLinks.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Navigation.GetPageInfoWithLinks.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun listPages(request: Navigation.ListPages.Request): Navigation.ListPages.Response {
val encoded = Service.navigationListPages(
Navigation.ListPages.Request.ADAPTER.encode(request)
)
val response = Navigation.ListPages.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Navigation.ListPages.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun pageCreate(request: Page.Create.Request): Page.Create.Response {
val encoded = Service.pageCreate(Page.Create.Request.ADAPTER.encode(request))
val response = Page.Create.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Page.Create.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun versionGet(request: Version.Get.Request): Version.Get.Response {
val encoded = Service.versionGet(Version.Get.Request.ADAPTER.encode(request))
val response = Version.Get.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Version.Get.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun blockListSetFields(request: BlockList.Set.Fields.Request): BlockList.Set.Fields.Response {
val encoded =
Service.blockListSetFields(BlockList.Set.Fields.Request.ADAPTER.encode(request))
val response = BlockList.Set.Fields.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != BlockList.Set.Fields.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
}

View file

@ -1,15 +1,12 @@
package com.anytypeio.anytype
import anytype.Events.Event
import anytype.Events.Event.Message
import anytype.model.Models
import anytype.Event
import anytype.model.Block
import com.anytypeio.anytype.common.MockDataFactory
import com.anytypeio.anytype.data.auth.model.BlockEntity
import com.anytypeio.anytype.data.auth.model.EventEntity
import com.anytypeio.anytype.middleware.EventProxy
import com.anytypeio.anytype.middleware.interactor.MiddlewareEventChannel
import com.google.protobuf.Struct
import com.google.protobuf.Value
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.stub
import kotlinx.coroutines.flow.collect
@ -39,21 +36,14 @@ class MiddlewareEventChannelTest {
val context = MockDataFactory.randomUuid()
val msg = Event.Block.Show
.newBuilder()
.setRootId(context)
.addAllBlocks(emptyList())
.build()
val msg = Event.Block.Show(
rootId = context,
blocks = emptyList()
)
val message = Message
.newBuilder()
.setBlockShow(msg)
val message = Event.Message(blockShow = msg)
val event = Event
.newBuilder()
.setContextId(context)
.addMessages(message)
.build()
val event = Event(contextId = context, messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)
@ -82,21 +72,14 @@ class MiddlewareEventChannelTest {
val context = MockDataFactory.randomUuid()
val msg = Event.Block.Show
.newBuilder()
.setRootId(MockDataFactory.randomString())
.addAllBlocks(emptyList())
.build()
val msg = Event.Block.Show(
rootId = MockDataFactory.randomString(),
blocks = emptyList()
)
val message = Message
.newBuilder()
.setBlockShow(msg)
val message = Event.Message(blockShow = msg)
val event = Event
.newBuilder()
.setContextId(MockDataFactory.randomUuid())
.addMessages(message)
.build()
val event = Event(contextId = MockDataFactory.randomUuid(), messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)
@ -117,21 +100,14 @@ class MiddlewareEventChannelTest {
val context = MockDataFactory.randomUuid()
val msg = Event.Block.Show
.newBuilder()
.setRootId(context)
.addAllBlocks(emptyList())
.build()
val msg = Event.Block.Show(
rootId = context,
blocks = emptyList()
)
val message = Message
.newBuilder()
.setBlockShow(msg)
val message = Event.Message(blockShow = msg)
val event = Event
.newBuilder()
.setContextId(context)
.addMessages(message)
.build()
val event = Event(contextId = context, messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)
@ -162,33 +138,25 @@ class MiddlewareEventChannelTest {
val name = "video1.mp4"
val mime = "video/*"
val size = 999111L
val state = Models.Block.Content.File.State.Done
val type = Models.Block.Content.File.Type.Video
val state = Block.Content.File.State.Done
val type = Block.Content.File.Type.Video
val context = MockDataFactory.randomUuid()
val id = MockDataFactory.randomUuid()
val msg = Message
.newBuilder()
.blockSetFileBuilder
.setId(id)
.setHash(Event.Block.Set.File.Hash.newBuilder().setValue(hash).build())
.setMime(Event.Block.Set.File.Mime.newBuilder().setValue(mime).build())
.setSize(Event.Block.Set.File.Size.newBuilder().setValue(size).build())
.setType(Event.Block.Set.File.Type.newBuilder().setValue(type).build())
.setState(Event.Block.Set.File.State.newBuilder().setValue(state).build())
.setName(Event.Block.Set.File.Name.newBuilder().setValue(name).build())
.build()
val msg = Event.Block.Set.File(
id = id,
hash = Event.Block.Set.File.Hash(hash),
mime = Event.Block.Set.File.Mime(mime),
size = Event.Block.Set.File.Size(size),
type = Event.Block.Set.File.Type(type),
state = Event.Block.Set.File.State(state),
name = Event.Block.Set.File.Name(name)
)
val message = Message
.newBuilder()
.setBlockSetFile(msg)
val message = Event.Message(blockSetFile = msg)
val event = Event
.newBuilder()
.setContextId(context)
.addMessages(message)
.build()
val event = Event(contextId = context, messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)
@ -223,21 +191,11 @@ class MiddlewareEventChannelTest {
val context = MockDataFactory.randomUuid()
val id = MockDataFactory.randomUuid()
val msg = Message
.newBuilder()
.blockSetFileBuilder
.setId(id)
.build()
val msg = Event.Block.Set.File(id = id)
val message = Message
.newBuilder()
.setBlockSetFile(msg)
val message = Event.Message(blockSetFile = msg)
val event = Event
.newBuilder()
.setContextId(context)
.addMessages(message)
.build()
val event = Event(contextId = context, messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)
@ -267,22 +225,11 @@ class MiddlewareEventChannelTest {
val id = MockDataFactory.randomUuid()
val color = MockDataFactory.randomString()
val msg = Message
.newBuilder()
.blockSetBackgroundColorBuilder
.setId(id)
.setBackgroundColor(color)
.build()
val msg = Event.Block.Set.BackgroundColor(id = id, backgroundColor = color)
val message = Message
.newBuilder()
.setBlockSetBackgroundColor(msg)
val message = Event.Message(blockSetBackgroundColor = msg)
val event = Event
.newBuilder()
.setContextId(context)
.addMessages(message)
.build()
val event = Event(contextId = context, messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)
@ -318,27 +265,17 @@ class MiddlewareEventChannelTest {
val details = BlockEntity.Fields(map = mutableMapOf(icon, name))
val msg = Message
.newBuilder()
.blockSetDetailsBuilder
.setId(id)
.setDetails(
Struct.newBuilder()
.putFields(icon.first, Value.newBuilder().setStringValue(icon.second).build())
.putFields(name.first, Value.newBuilder().setStringValue(name.second).build())
.build()
val msg = Event.Block.Set.Details(
id = id,
details = mapOf(
icon.first to icon.second,
name.first to name.second
)
.build()
)
val message = Message
.newBuilder()
.setBlockSetDetails(msg)
val message = Event.Message(blockSetDetails = msg)
val event = Event
.newBuilder()
.setContextId(context)
.addMessages(message)
.build()
val event = Event(contextId = context, messages = listOf(message))
proxy.stub {
on { flow() } doReturn flowOf(event)

View file

@ -1,8 +1,9 @@
package com.anytypeio.anytype
import anytype.Commands.Rpc.*
import anytype.model.Models
import anytype.model.Models.Range
import anytype.ResponseEvent
import anytype.Rpc
import anytype.model.Block
import anytype.model.Range
import com.anytypeio.anytype.common.MockDataFactory
import com.anytypeio.anytype.data.auth.model.BlockEntity
import com.anytypeio.anytype.data.auth.model.CommandEntity
@ -11,8 +12,6 @@ import com.anytypeio.anytype.middleware.interactor.Middleware
import com.anytypeio.anytype.middleware.interactor.MiddlewareFactory
import com.anytypeio.anytype.middleware.interactor.MiddlewareMapper
import com.anytypeio.anytype.middleware.service.MiddlewareService
import com.google.protobuf.Struct
import com.google.protobuf.Value
import com.nhaarman.mockitokotlin2.*
import org.junit.Before
import org.junit.Test
@ -42,10 +41,10 @@ class MiddlewareTest {
// SETUP
val request = Account.Stop.Request.newBuilder().build()
val request = Rpc.Account.Stop.Request()
service.stub {
on { accountStop(request) } doReturn Account.Stop.Response.getDefaultInstance()
on { accountStop(request) } doReturn Rpc.Account.Stop.Response()
}
// TESTING
@ -68,19 +67,18 @@ class MiddlewareTest {
emoji = null
)
val response = Block.CreatePage.Response
.newBuilder()
.setBlockId(MockDataFactory.randomUuid())
.setTargetId(MockDataFactory.randomUuid())
.build()
val response = Rpc.Block.CreatePage.Response(
blockId = MockDataFactory.randomUuid(),
targetId = MockDataFactory.randomUuid(),
event = ResponseEvent()
)
val request = Block.CreatePage.Request
.newBuilder()
.setContextId(command.context)
.setTargetId(command.target)
.setPosition(Models.Block.Position.Inner)
.setDetails(Struct.getDefaultInstance())
.build()
val request = Rpc.Block.CreatePage.Request(
contextId = command.context,
targetId = command.target,
position = Block.Position.Inner,
details = mapOf<String, Any?>()
)
service.stub {
on { blockCreatePage(any()) } doReturn response
@ -117,26 +115,18 @@ class MiddlewareTest {
emoji = emoji
)
val response = Block.CreatePage.Response
.newBuilder()
.setBlockId(MockDataFactory.randomUuid())
.setTargetId(MockDataFactory.randomUuid())
.build()
val response = Rpc.Block.CreatePage.Response(
blockId = MockDataFactory.randomUuid(),
targetId = MockDataFactory.randomUuid(),
event = ResponseEvent()
)
val request = Block.CreatePage.Request
.newBuilder()
.setContextId(command.context)
.setTargetId(command.target)
.setPosition(Models.Block.Position.Inner)
.setDetails(
Struct.newBuilder()
.putFields(
"iconEmoji",
Value.newBuilder().setStringValue(emoji).build()
)
.build()
)
.build()
val request = Rpc.Block.CreatePage.Request(
contextId = command.context,
targetId = command.target,
position = Block.Position.Inner,
details = mapOf("iconEmoji" to emoji)
)
service.stub {
on { blockCreatePage(any()) } doReturn response
@ -172,26 +162,23 @@ class MiddlewareTest {
)
)
val response = Block.Create.Response
.newBuilder()
.setBlockId(MockDataFactory.randomUuid())
.build()
val response = Rpc.Block.Create.Response(
blockId = MockDataFactory.randomUuid(),
event = ResponseEvent()
)
val model = Models.Block
.newBuilder()
.setText(
Models.Block.Content.Text
.newBuilder()
.setStyle(Models.Block.Content.Text.Style.Numbered)
val model = Block(
text = Block.Content.Text(
style = Block.Content.Text.Style.Numbered
)
)
val request = Block.Create.Request
.newBuilder()
.setContextId(command.context)
.setTargetId(command.target)
.setPosition(Models.Block.Position.Replace)
.setBlock(model)
.build()
val request = Rpc.Block.Create.Request(
contextId = command.context,
targetId = command.target,
position = Block.Position.Replace,
block = model
)
service.stub {
on { blockCreate(any()) } doReturn response
@ -222,28 +209,27 @@ class MiddlewareTest {
emoji = MockDataFactory.randomString()
)
val response = Block.Set.Details.Response.getDefaultInstance()
val response = Rpc.Block.Set.Details.Response(event = ResponseEvent())
val emojiIconKey = "iconEmoji"
val imageIconKey = "iconImage"
val emojiValue = Value.newBuilder().setStringValue(command.emoji)
val emojiValue = command.emoji
val emojiDetail = Block.Set.Details.Detail.newBuilder()
.setKey(emojiIconKey)
.setValue(emojiValue)
val emojiDetail = Rpc.Block.Set.Details.Detail(
key = emojiIconKey, value = emojiValue
)
val imageValue = Value.newBuilder().setStringValue("")
val imageValue = ""
val imageDetail = Block.Set.Details.Detail.newBuilder()
.setKey(imageIconKey)
.setValue(imageValue)
val imageDetail = Rpc.Block.Set.Details.Detail(
key = imageIconKey
)
val request = Block.Set.Details.Request.newBuilder()
.setContextId(command.context)
.addDetails(emojiDetail)
.addDetails(imageDetail)
.build()
val request = Rpc.Block.Set.Details.Request(
contextId = command.context,
details = listOf(emojiDetail, imageDetail)
)
service.stub {
on { blockSetDetails(any()) } doReturn response
@ -267,29 +253,22 @@ class MiddlewareTest {
hash = MockDataFactory.randomUuid()
)
val response = Block.Set.Details.Response.getDefaultInstance()
val response = Rpc.Block.Set.Details.Response(event = ResponseEvent())
val imageIconKey = "iconImage"
val imageIconValue = Value.newBuilder().setStringValue(command.hash)
val imageIconValue = command.hash
val imageIconDetail = Block.Set.Details.Detail.newBuilder()
.setKey(imageIconKey)
.setValue(imageIconValue)
val imageIconDetail = Rpc.Block.Set.Details.Detail(imageIconKey,imageIconValue)
val emojiIconKey = "iconEmoji"
val emojiIconValue = Value.newBuilder().setStringValue("")
val emojiIconDetail = Rpc.Block.Set.Details.Detail(emojiIconKey)
val emojiIconDetail = Block.Set.Details.Detail.newBuilder()
.setKey(emojiIconKey)
.setValue(emojiIconValue)
val request = Block.Set.Details.Request.newBuilder()
.setContextId(command.context)
.addDetails(imageIconDetail)
.addDetails(emojiIconDetail)
.build()
val request = Rpc.Block.Set.Details.Request(
contextId = command.context,
details = listOf(imageIconDetail, emojiIconDetail)
)
service.stub {
on { blockSetDetails(any()) } doReturn response
@ -313,20 +292,18 @@ class MiddlewareTest {
title = MockDataFactory.randomString()
)
val response = Block.Set.Details.Response.getDefaultInstance()
val response = Rpc.Block.Set.Details.Response()
val key = "name"
val value = Value.newBuilder().setStringValue(command.title)
val value = command.title
val details = Block.Set.Details.Detail.newBuilder()
.setKey(key)
.setValue(value)
val details = Rpc.Block.Set.Details.Detail(key, value)
val request = Block.Set.Details.Request.newBuilder()
.setContextId(command.context)
.addDetails(details)
.build()
val request = Rpc.Block.Set.Details.Request(
contextId = command.context,
details = listOf(details)
)
service.stub {
on { blockSetDetails(any()) } doReturn response
@ -354,26 +331,26 @@ class MiddlewareTest {
)
)
val request = BlockList.Set.Text.Style.Request
.newBuilder()
.setStyle(Models.Block.Content.Text.Style.Checkbox)
.addAllBlockIds(command.targets)
.setContextId(command.context)
.build()
val request = Rpc.BlockList.Set.Text.Style.Request(
contextId = command.context,
blockIds = command.targets,
style = Block.Content.Text.Style.Checkbox
)
service.stub {
on { blockSetTextStyle(request) } doReturn BlockList.Set.Text.Style.Response.getDefaultInstance()
on { blockListSetTextStyle(request) } doReturn
Rpc.BlockList.Set.Text.Style.Response(event = ResponseEvent())
}
// TESTING
assertTrue { request.blockIdsList.size == 2 }
assertTrue { request.blockIdsList[0] == command.targets[0] }
assertTrue { request.blockIdsList[1] == command.targets[1] }
assertTrue { request.blockIds.size == 2 }
assertTrue { request.blockIds[0] == command.targets[0] }
assertTrue { request.blockIds[1] == command.targets[1] }
middleware.updateTextStyle(command)
verify(service, times(1)).blockSetTextStyle(request)
verify(service, times(1)).blockListSetTextStyle(request)
verifyNoMoreInteractions(service)
}
@ -392,19 +369,18 @@ class MiddlewareTest {
position = PositionEntity.TOP
)
val position = Models.Block.Position.Top
val position = Block.Position.Top
val request = BlockList.Move.Request
.newBuilder()
.setContextId(command.contextId)
.setTargetContextId(command.contextId)
.setPosition(position)
.addAllBlockIds(command.blockIds)
.setDropTargetId(command.dropTargetId)
.build()
val request = Rpc.BlockList.Move.Request(
contextId = command.contextId,
targetContextId = command.contextId,
position = position,
blockIds = command.blockIds,
dropTargetId = command.dropTargetId
)
service.stub {
on { blockListMove(request) } doReturn BlockList.Move.Response.getDefaultInstance()
on { blockListMove(request) } doReturn Rpc.BlockList.Move.Response(event = ResponseEvent())
}
// TESTING
@ -432,20 +408,19 @@ class MiddlewareTest {
blocks = emptyList()
)
val range = Range.newBuilder().setFrom(0).setTo(5).build()
val range = Range(0, 5)
val request = Block.Paste.Request
.newBuilder()
.setContextId(command.context)
.setFocusedBlockId(command.focus)
.setTextSlot(command.text)
.setHtmlSlot(command.html)
.setSelectedTextRange(range)
.addAllSelectedBlockIds(command.selected)
.build()
val request = Rpc.Block.Paste.Request(
contextId = command.context,
focusedBlockId = command.focus,
textSlot = command.text,
htmlSlot = command.html.orEmpty(),
selectedTextRange = range,
selectedBlockIds = command.selected
)
service.stub {
on { blockPaste(request) } doReturn Block.Paste.Response.getDefaultInstance()
on { blockPaste(request) } doReturn Rpc.Block.Paste.Response(event = ResponseEvent())
}
// TESTING
@ -471,23 +446,16 @@ class MiddlewareTest {
mode = BlockEntity.Content.Text.SplitMode.BOTTOM
)
val request = Block.Split.Request
.newBuilder()
.setRange(
Range
.newBuilder()
.setFrom(command.range.first)
.setTo(command.range.last)
.build()
)
.setStyle(Models.Block.Content.Text.Style.Checkbox)
.setContextId(context)
.setBlockId(command.target)
.setMode(Block.Split.Request.Mode.BOTTOM)
.build()
val request = Rpc.Block.Split.Request(
range = Range(command.range.first, command.range.last),
style = Block.Content.Text.Style.Checkbox,
contextId = context,
blockId = command.target,
mode = Rpc.Block.Split.Request.Mode.BOTTOM
)
service.stub {
on { blockSplit(request) } doReturn Block.Split.Response.getDefaultInstance()
on { blockSplit(request) } doReturn Rpc.Block.Split.Response(event = ResponseEvent())
}
// TESTING
@ -510,14 +478,13 @@ class MiddlewareTest {
type = BlockEntity.Content.File.Type.IMAGE
)
val request = UploadFile.Request
.newBuilder()
.setLocalPath(path)
.setType(Models.Block.Content.File.Type.Image)
.build()
val request = Rpc.UploadFile.Request(
localPath = path,
type = Block.Content.File.Type.Image
)
service.stub {
on { uploadFile(request) } doReturn UploadFile.Response.getDefaultInstance()
on { uploadFile(request) } doReturn Rpc.UploadFile.Response()
}
// TESTING
@ -540,14 +507,13 @@ class MiddlewareTest {
type = BlockEntity.Content.File.Type.FILE
)
val request = UploadFile.Request
.newBuilder()
.setLocalPath(path)
.setType(Models.Block.Content.File.Type.File)
.build()
val request = Rpc.UploadFile.Request(
localPath = path,
type = Block.Content.File.Type.File
)
service.stub {
on { uploadFile(request) } doReturn UploadFile.Response.getDefaultInstance()
on { uploadFile(request) } doReturn Rpc.UploadFile.Response()
}
// TESTING
@ -570,14 +536,13 @@ class MiddlewareTest {
type = BlockEntity.Content.File.Type.VIDEO
)
val request = UploadFile.Request
.newBuilder()
.setLocalPath(path)
.setType(Models.Block.Content.File.Type.Video)
.build()
val request = Rpc.UploadFile.Request(
localPath = path,
type = Block.Content.File.Type.Video
)
service.stub {
on { uploadFile(request) } doReturn UploadFile.Response.getDefaultInstance()
on { uploadFile(request) } doReturn Rpc.UploadFile.Response()
}
// TESTING
@ -621,29 +586,23 @@ class MiddlewareTest {
)
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()
Rpc.BlockList.Set.Fields.Request.BlockField(
blockId = block1,
fields = mapOf("lang" to "kotlin")
),
Rpc.BlockList.Set.Fields.Request.BlockField(
blockId = block2,
fields = mapOf("lang" to "python")
)
)
val request = BlockList.Set.Fields.Request.newBuilder()
.setContextId(ctx)
.addAllBlockFields(fields)
.build()
val request = Rpc.BlockList.Set.Fields.Request(
contextId = ctx,
blockFields = fields
)
service.stub {
on { blockListSetFields(request) } doReturn BlockList.Set.Fields.Response.getDefaultInstance()
on { blockListSetFields(request) } doReturn Rpc.BlockList.Set.Fields.Response(event = ResponseEvent())
}
// TESTING

1
protobuf/.gitignore vendored
View file

@ -1 +0,0 @@
/build

View file

@ -1,17 +0,0 @@
apply plugin: 'java-library'
apply plugin: 'com.google.protobuf'
sourceSets{
main.java.srcDirs += "${protobuf.generatedFilesBaseDir}/main/java"
}
dependencies {
def protobufDependencies = rootProject.ext.protobuf
implementation protobufDependencies.protobufJava
}
protobuf {
protoc {
artifact = rootProject.ext.protobuf.protoc
}
}

1
protocol/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

44
protocol/build.gradle Normal file
View file

@ -0,0 +1,44 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'com.squareup.wire'
android {
def config = rootProject.extensions.getByName("ext")
compileSdkVersion config["compile_sdk"]
defaultConfig {
minSdkVersion config["min_sdk"]
targetSdkVersion config["target_sdk"]
versionCode config["version_code"]
versionName config["version_name"]
testInstrumentationRunner config["test_runner"]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
def applicationDependencies = rootProject.ext.mainApplication
implementation applicationDependencies.kotlin
}
wire {
protoPath { srcDir 'src/main/proto' }
kotlin {}
}

View file

21
protocol/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,4 @@
<manifest package="com.anytypeio.anytype.protocol">
/
</manifest>

View file

@ -1,7 +1,7 @@
include ':protocol'
include ':app',
':core-utils',
':middleware',
':protobuf',
':persistence',
':domain',
':data',