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:
parent
21a201a89b
commit
a15a3f22f1
12 changed files with 195 additions and 0 deletions
|
@ -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
|
||||
}
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue