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

DROID-2544 Search | Enhancement | Integrate new search API (#1243)

This commit is contained in:
Evgenii Kozlov 2024-05-29 17:44:58 +02:00 committed by GitHub
parent 21a201a89b
commit a15a3f22f1
Signed by: github
GPG key ID: B5690EEEBB952194
12 changed files with 195 additions and 0 deletions

View file

@ -0,0 +1,43 @@
package com.anytypeio.anytype.di.feature.search
import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.di.common.ComponentDependencies
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.presentation.search.GlobalSearchViewModel
import dagger.Binds
import dagger.Component
import dagger.Module
@Component(
dependencies = [GlobalSearchDependencies::class],
modules = [
GlobalSearchModule::class,
GlobalSearchModule.Declarations::class
]
)
@PerScreen
interface GlobalSearchComponent {
@Component.Factory
interface Builder {
fun create(dependencies: GlobalSearchDependencies): GlobalSearchComponent
}
}
@Module
object GlobalSearchModule {
@Module
interface Declarations {
@Binds
@PerScreen
fun bindViewModelFactory(factory: GlobalSearchViewModel.Factory): ViewModelProvider.Factory
}
}
interface GlobalSearchDependencies : ComponentDependencies {
fun urlBuilder(): UrlBuilder
fun repo(): BlockRepository
fun dispatchers(): AppCoroutineDispatchers
}

View file

@ -496,4 +496,29 @@ sealed class Command {
data class VerifyEmailCode(val code: String) : Membership()
data class GetTiers(val noCache: Boolean, val locale: String) : Membership()
}
data class SearchWithMeta(
val query: String,
val limit: Int,
val offset: Int,
val keys: List<Key>,
val sorts: List<DVSort>,
val filters: List<DVFilter>,
val withMeta: Boolean,
val withMetaRelationDetails: Boolean
) {
data class Result(
val obj: Id,
val wrapper: ObjectWrapper,
val metas: List<Meta>
) {
data class Meta(
val relation: Key,
val block: Id,
val highlight: String,
val ranges: List<IntRange>,
val dependencies: List<ObjectWrapper>
)
}
}
}

View file

@ -400,6 +400,10 @@ class BlockDataRepository(
keys = keys
)
override suspend fun searchObjectWithMeta(
command: Command.SearchWithMeta
): List<Command.SearchWithMeta.Result> = remote.searchObjectWithMeta(command)
override suspend fun searchObjectsWithSubscription(
subscription: Id,
sorts: List<DVSort>,

View file

@ -160,6 +160,10 @@ interface BlockRemote {
keys: List<Id>
): List<Map<String, Any?>>
suspend fun searchObjectWithMeta(
command: Command.SearchWithMeta
): List<Command.SearchWithMeta.Result>
suspend fun searchObjectsWithSubscription(
subscription: Id,
sorts: List<DVSort>,

View file

@ -201,6 +201,10 @@ interface BlockRepository {
keys: List<Id> = emptyList()
): List<Struct>
suspend fun searchObjectWithMeta(
command: Command.SearchWithMeta
): List<Command.SearchWithMeta.Result>
suspend fun searchObjectsWithSubscription(
subscription: Id,
sorts: List<DVSort>,

View file

@ -0,0 +1,16 @@
package com.anytypeio.anytype.domain.search
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import javax.inject.Inject
class SearchWithMeta @Inject constructor(
private val repo: BlockRepository,
private val dispatchers: AppCoroutineDispatchers
) : ResultInteractor<Command.SearchWithMeta, List<Command.SearchWithMeta.Result>>(dispatchers.io) {
override suspend fun doWork(params: Command.SearchWithMeta): List<Command.SearchWithMeta.Result> {
return repo.searchObjectWithMeta(command = params)
}
}

View file

@ -358,6 +358,10 @@ class BlockMiddleware(
keys = keys
)
override suspend fun searchObjectWithMeta(
command: Command.SearchWithMeta
): List<Command.SearchWithMeta.Result> = middleware.objectSearchWithMeta(command)
override suspend fun searchObjectsWithSubscription(
subscription: Id,
sorts: List<DVSort>,

View file

@ -53,6 +53,7 @@ import com.anytypeio.anytype.middleware.mappers.mw
import com.anytypeio.anytype.middleware.mappers.parse
import com.anytypeio.anytype.middleware.mappers.toCore
import com.anytypeio.anytype.middleware.mappers.toCoreModel
import com.anytypeio.anytype.middleware.mappers.toCoreModelSearchResults
import com.anytypeio.anytype.middleware.mappers.toCoreModels
import com.anytypeio.anytype.middleware.mappers.toMiddlewareModel
import com.anytypeio.anytype.middleware.mappers.toMw
@ -1257,6 +1258,22 @@ class Middleware @Inject constructor(
return response.records.map { it?.toMap() ?: emptyMap() }
}
@Throws(Exception::class)
fun objectSearchWithMeta(command: Command.SearchWithMeta): List<Command.SearchWithMeta.Result> {
val request = Rpc.Object.SearchWithMeta.Request(
sorts = command.sorts.map { it.toMiddlewareModel() },
filters = command.filters.map { it.toMiddlewareModel() },
fullText = command.query,
offset = command.offset,
limit = command.limit,
keys = command.keys
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.objectSearchWithMeta(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.toCoreModelSearchResults()
}
@Throws(Exception::class)
fun objectSearchSubscribe(
subscription: Id,

View file

@ -1,13 +1,16 @@
package com.anytypeio.anytype.middleware.mappers
import anytype.Rpc
import anytype.model.InternalFlag
import anytype.model.Range
import anytype.model.RelationFormat
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.BlockSplitMode
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.NetworkMode
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.membership.MembershipPaymentMethod
@ -529,4 +532,34 @@ fun MembershipPaymentMethod.toMw(): MMembershipPaymentMethod = when (this) {
MembershipPaymentMethod.METHOD_CRYPTO -> MMembershipPaymentMethod.MethodCrypto
MembershipPaymentMethod.METHOD_INAPP_APPLE -> MMembershipPaymentMethod.MethodInappApple
MembershipPaymentMethod.METHOD_INAPP_GOOGLE -> MMembershipPaymentMethod.MethodInappGoogle
}
fun Rpc.Object.SearchWithMeta.Response.toCoreModelSearchResults(): List<Command.SearchWithMeta.Result> {
return results.map { result ->
Command.SearchWithMeta.Result(
obj = result.objectId,
wrapper = ObjectWrapper.Basic(result.details.orEmpty()),
metas = result.meta.map { meta ->
val dependentObjectDetails = meta.relationDetails.orEmpty()
Command.SearchWithMeta.Result.Meta(
highlight = meta.highlight,
block = meta.blockId,
relation = meta.relationKey,
dependencies = if (dependentObjectDetails.isNotEmpty()) {
listOf(
ObjectWrapper.Basic(dependentObjectDetails)
)
} else {
emptyList()
},
ranges = meta.highlightRanges.map { range ->
IntRange(
start = range.from,
endInclusive = range.to
)
}
)
}
)
}
}

View file

@ -90,6 +90,9 @@ interface MiddlewareService {
@Throws(Exception::class)
fun objectSearch(request: Rpc.Object.Search.Request): Rpc.Object.Search.Response
@Throws(Exception::class)
fun objectSearchWithMeta(request: Rpc.Object.SearchWithMeta.Request): Rpc.Object.SearchWithMeta.Response
@Throws(Exception::class)
fun objectSearchSubscribe(request: Rpc.Object.SearchSubscribe.Request): Rpc.Object.SearchSubscribe.Response

View file

@ -1004,6 +1004,17 @@ class MiddlewareServiceImplementation @Inject constructor(
}
}
override fun objectSearchWithMeta(request: Rpc.Object.SearchWithMeta.Request): Rpc.Object.SearchWithMeta.Response {
val encoded = Service.objectSearchWithMeta(Rpc.Object.SearchWithMeta.Request.ADAPTER.encode(request))
val response = Rpc.Object.SearchWithMeta.Response.ADAPTER.decode(encoded)
val error = response.error
if (error != null && error.code != Rpc.Object.SearchWithMeta.Response.Error.Code.NULL) {
throw Exception(error.description)
} else {
return response
}
}
override fun objectSearchSubscribe(request: Rpc.Object.SearchSubscribe.Request): Rpc.Object.SearchSubscribe.Response {
val encoded =
Service.objectSearchSubscribe(Rpc.Object.SearchSubscribe.Request.ADAPTER.encode(request))

View file

@ -0,0 +1,31 @@
package com.anytypeio.anytype.presentation.search
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.search.SearchWithMeta
import com.anytypeio.anytype.presentation.common.BaseViewModel
import javax.inject.Inject
class GlobalSearchViewModel(
private val searchWithMeta: SearchWithMeta,
private val urlBuilder: UrlBuilder
) : BaseViewModel() {
init {
// TODO
}
class Factory @Inject constructor(
private val searchWithMeta: SearchWithMeta,
private val urlBuilder: UrlBuilder
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return GlobalSearchViewModel(
searchWithMeta = searchWithMeta,
urlBuilder = urlBuilder
) as T
}
}
}