mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-11 02:13:30 +09:00
App | Feature | Use snippet as object name (#1868)
* rename typeLayout -> layout * add Note layout to supported layouts * add mapper functions for object wrapper * open Note from block links * fix
This commit is contained in:
parent
02adb12236
commit
72c6139d77
20 changed files with 251 additions and 206 deletions
|
@ -51,5 +51,9 @@ sealed class ObjectWrapper {
|
|||
val done: Boolean? by default
|
||||
|
||||
val snippet: String? by default
|
||||
|
||||
val fileExt: String? by default
|
||||
|
||||
val fileMimeType: String? by default
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ class DefaultObjectViewAdapter(
|
|||
itemView.setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
onClick(getItem(pos).id, getItem(pos).typeLayout)
|
||||
onClick(getItem(pos).id, getItem(pos).layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ class CreateFilterAdapter(
|
|||
class Object(view: View) : ViewHolder(view) {
|
||||
fun bind(item: CreateFilterView.Object) = with(itemView) {
|
||||
tvObjectName.text = item.name
|
||||
tvObjectType.text = item.type
|
||||
tvObjectType.text = item.typeName
|
||||
ivSelectObjectIcon.isSelected = item.isSelected
|
||||
objectIconWidget.setIcon(item.icon)
|
||||
}
|
||||
|
|
|
@ -2,22 +2,24 @@ package com.anytypeio.anytype.domain.dataview.interactor
|
|||
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.base.Either
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
||||
class SearchObjects(
|
||||
private val repo: BlockRepository
|
||||
) : BaseUseCase<List<Map<String, Any?>>, SearchObjects.Params>() {
|
||||
) : BaseUseCase<List<ObjectWrapper.Basic>, SearchObjects.Params>() {
|
||||
|
||||
override suspend fun run(params: Params): Either<Throwable, List<Map<String, Any?>>> = safe {
|
||||
override suspend fun run(params: Params) = safe {
|
||||
repo.searchObjects(
|
||||
sorts = params.sorts,
|
||||
filters = params.filters,
|
||||
fulltext = params.fulltext,
|
||||
offset = params.offset,
|
||||
limit = params.limit
|
||||
)
|
||||
).map { response ->
|
||||
ObjectWrapper.Basic(response)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(
|
||||
|
|
|
@ -16,7 +16,10 @@ import com.anytypeio.anytype.analytics.base.EventsDictionary.TAB_RECENT
|
|||
import com.anytypeio.anytype.analytics.base.EventsDictionary.TAB_SETS
|
||||
import com.anytypeio.anytype.analytics.base.sendEvent
|
||||
import com.anytypeio.anytype.analytics.props.Props
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Position
|
||||
import com.anytypeio.anytype.core_utils.common.EventWrapper
|
||||
import com.anytypeio.anytype.core_utils.ext.withLatestFrom
|
||||
import com.anytypeio.anytype.core_utils.ui.ViewStateViewModel
|
||||
|
@ -41,6 +44,7 @@ import com.anytypeio.anytype.presentation.mapper.toView
|
|||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
import com.anytypeio.anytype.presentation.navigation.SupportNavigation
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.settings.EditorSettings
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
@ -307,7 +311,7 @@ class HomeDashboardViewModel(
|
|||
TAB.RECENT -> recent.value.find { it is DashboardView.Document && it.target == target }
|
||||
else -> null
|
||||
}
|
||||
if (view is DashboardView.Document && supportedLayouts.contains(view.layout)) {
|
||||
if (view is DashboardView.Document && SupportedLayouts.layouts.contains(view.layout)) {
|
||||
if (view.type != ObjectType.TEMPLATE_URL) {
|
||||
if (view.layout == ObjectType.Layout.SET) {
|
||||
proceedWithOpeningObjectSet(target)
|
||||
|
@ -392,7 +396,6 @@ class HomeDashboardViewModel(
|
|||
searchObjects(params).process(
|
||||
success = { objects ->
|
||||
archived.value = objects
|
||||
.map { ObjectWrapper.Basic(it) }
|
||||
.map { obj ->
|
||||
val layout = obj.layout
|
||||
val oType = stateData.value?.findOTypeById(obj.type)
|
||||
|
@ -431,7 +434,6 @@ class HomeDashboardViewModel(
|
|||
searchObjects(params).process(
|
||||
success = { objects ->
|
||||
recent.value = objects
|
||||
.map { ObjectWrapper.Basic(it) }
|
||||
.map { obj ->
|
||||
val oType = stateData.value?.findOTypeById(obj.type)
|
||||
val layout = obj.layout
|
||||
|
@ -484,17 +486,18 @@ class HomeDashboardViewModel(
|
|||
)
|
||||
searchObjects(params).process(
|
||||
success = { objects ->
|
||||
sets.value = objects.map { ObjectWrapper.Basic(it) }.map { obj ->
|
||||
DashboardView.ObjectSet(
|
||||
id = obj.id,
|
||||
target = obj.id,
|
||||
title = obj.name,
|
||||
isArchived = obj.isArchived ?: false,
|
||||
isLoading = false,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.layout,
|
||||
builder = urlBuilder
|
||||
sets.value = objects
|
||||
.map { obj ->
|
||||
DashboardView.ObjectSet(
|
||||
id = obj.id,
|
||||
target = obj.id,
|
||||
title = obj.name,
|
||||
isArchived = obj.isArchived ?: false,
|
||||
isLoading = false,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.layout,
|
||||
builder = urlBuilder
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -632,18 +635,6 @@ class HomeDashboardViewModel(
|
|||
val direction: Position
|
||||
)
|
||||
|
||||
companion object {
|
||||
val supportedLayouts = listOf(
|
||||
ObjectType.Layout.BASIC,
|
||||
ObjectType.Layout.TODO,
|
||||
ObjectType.Layout.PROFILE,
|
||||
ObjectType.Layout.FILE,
|
||||
ObjectType.Layout.IMAGE,
|
||||
ObjectType.Layout.SET,
|
||||
ObjectType.Layout.NOTE
|
||||
)
|
||||
}
|
||||
|
||||
enum class TAB { FAVOURITE, RECENT, INBOX, SETS, ARCHIVE }
|
||||
|
||||
//region CREATE PAGE
|
||||
|
|
|
@ -97,7 +97,7 @@ import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
|
|||
import com.anytypeio.anytype.presentation.navigation.SupportNavigation
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectTypeView
|
||||
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
|
||||
import com.anytypeio.anytype.presentation.objects.toDefaultObjectView
|
||||
import com.anytypeio.anytype.presentation.objects.toView
|
||||
import com.anytypeio.anytype.presentation.relations.DocumentRelationView
|
||||
import com.anytypeio.anytype.presentation.relations.views
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
|
@ -2626,6 +2626,7 @@ class EditorViewModel(
|
|||
when (wrapper.layout) {
|
||||
ObjectType.Layout.BASIC,
|
||||
ObjectType.Layout.PROFILE,
|
||||
ObjectType.Layout.NOTE,
|
||||
ObjectType.Layout.TODO,
|
||||
ObjectType.Layout.FILE -> {
|
||||
proceedWithOpeningPage(target = target)
|
||||
|
@ -5079,14 +5080,13 @@ class EditorViewModel(
|
|||
)
|
||||
viewModelScope.launch {
|
||||
searchObjects(params).process(
|
||||
success = { raw ->
|
||||
val objects = raw.toDefaultObjectView(
|
||||
objectTypes = objectTypesProvider.get(),
|
||||
urlBuilder = urlBuilder
|
||||
).filter {
|
||||
SupportedLayouts.layouts.contains(it.typeLayout)
|
||||
&& it.type != ObjectType.TEMPLATE_URL
|
||||
}
|
||||
success = { result ->
|
||||
val objects = result
|
||||
.toView(urlBuilder, objectTypesProvider.get())
|
||||
.filter {
|
||||
SupportedLayouts.layouts.contains(it.layout)
|
||||
&& it.type != ObjectType.TEMPLATE_URL
|
||||
}
|
||||
controlPanelInteractor.onEvent(
|
||||
ControlPanelMachine.Event.Mentions.OnResult(
|
||||
objects,
|
||||
|
|
|
@ -10,9 +10,8 @@ import com.anytypeio.anytype.core_models.SmartBlockType
|
|||
import com.anytypeio.anytype.domain.block.interactor.sets.GetObjectTypes
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
|
||||
import com.anytypeio.anytype.presentation.objects.toView
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -40,22 +39,10 @@ class MoveToViewModel(
|
|||
init {
|
||||
viewModelScope.launch {
|
||||
combine(objects, types) { listOfObjects, listOfTypes ->
|
||||
listOfObjects.map { obj ->
|
||||
val targetType = listOfTypes.find { type ->
|
||||
obj.type.contains(type.url)
|
||||
}
|
||||
DefaultObjectView(
|
||||
id = obj.id,
|
||||
name = obj.name.orEmpty(),
|
||||
typeName = targetType?.name.orEmpty(),
|
||||
typeLayout = obj.layout,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.layout,
|
||||
builder = urlBuilder
|
||||
)
|
||||
)
|
||||
}
|
||||
listOfObjects.toView(
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypes = listOfTypes
|
||||
)
|
||||
}.collectLatest { views ->
|
||||
if (views.isNotEmpty())
|
||||
_viewState.value = MoveToView.Success(views)
|
||||
|
@ -74,10 +61,11 @@ class MoveToViewModel(
|
|||
searchQuery.collectLatest { query ->
|
||||
val params = getSearchObjectsParams().copy(fulltext = query)
|
||||
searchObjects(params = params).process(
|
||||
success = { raw ->
|
||||
success = { objects ->
|
||||
setObjects(
|
||||
ctx = ctx,
|
||||
data = raw.map { ObjectWrapper.Basic(it) })
|
||||
data = objects
|
||||
)
|
||||
},
|
||||
failure = { Timber.e(it, "Error while searching for objects") }
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ data class DefaultObjectView(
|
|||
val name: String,
|
||||
val type: String? = null,
|
||||
val typeName: String? = null,
|
||||
val typeLayout: ObjectType.Layout? = null,
|
||||
val layout: ObjectType.Layout? = null,
|
||||
val icon: ObjectIcon = ObjectIcon.None
|
||||
)
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package com.anytypeio.anytype.presentation.objects
|
||||
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
|
||||
|
||||
fun List<Map<String, Any?>>.toDefaultObjectView(
|
||||
urlBuilder: UrlBuilder,
|
||||
objectTypes: List<ObjectType>
|
||||
): List<DefaultObjectView> =
|
||||
this.map { record ->
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val type = obj.type.firstOrNull()
|
||||
val layout = obj.layout ?: ObjectType.Layout.BASIC
|
||||
DefaultObjectView(
|
||||
id = obj.id,
|
||||
name = obj.name.orEmpty(),
|
||||
typeName = objectTypes.find { it.url == type }?.name.orEmpty(),
|
||||
typeLayout = layout,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = layout,
|
||||
builder = urlBuilder
|
||||
),
|
||||
type = type
|
||||
)
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package com.anytypeio.anytype.presentation.objects
|
||||
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
|
||||
import com.anytypeio.anytype.presentation.sets.RelationValueBaseViewModel
|
||||
import com.anytypeio.anytype.presentation.sets.filter.CreateFilterView
|
||||
|
||||
fun List<ObjectWrapper.Basic>.toView(
|
||||
urlBuilder: UrlBuilder,
|
||||
objectTypes: List<ObjectType>
|
||||
): List<DefaultObjectView> =
|
||||
this.map { obj ->
|
||||
val typeUrl = obj.getProperType()
|
||||
val layout = obj.getProperLayout()
|
||||
DefaultObjectView(
|
||||
id = obj.id,
|
||||
name = obj.getProperName(),
|
||||
type = typeUrl,
|
||||
typeName = getProperTypeName(url = typeUrl, types = objectTypes),
|
||||
layout = layout,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = layout,
|
||||
builder = urlBuilder
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun List<ObjectWrapper.Basic>.toCreateFilterObjectView(
|
||||
ids: List<*>? = null,
|
||||
urlBuilder: UrlBuilder,
|
||||
objectTypes: List<ObjectType>
|
||||
): List<CreateFilterView.Object> =
|
||||
this.map { obj ->
|
||||
CreateFilterView.Object(
|
||||
id = obj.id,
|
||||
typeName = getProperTypeName(
|
||||
url = obj.getProperType(),
|
||||
types = objectTypes
|
||||
),
|
||||
name = obj.getProperName(),
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.getProperLayout(),
|
||||
builder = urlBuilder
|
||||
),
|
||||
isSelected = ids?.contains(obj.id) ?: false
|
||||
)
|
||||
}
|
||||
|
||||
fun List<ObjectWrapper.Basic>.toRelationObjectValueView(
|
||||
ids: List<String>,
|
||||
urlBuilder: UrlBuilder,
|
||||
objectTypes: List<ObjectType>
|
||||
): List<RelationValueBaseViewModel.RelationValueView.Object> =
|
||||
this.mapNotNull { obj ->
|
||||
val typeUrl = obj.getProperType()
|
||||
val layout = obj.getProperLayout()
|
||||
if (obj.id !in ids) {
|
||||
RelationValueBaseViewModel.RelationValueView.Object(
|
||||
id = obj.id,
|
||||
name = obj.getProperName(),
|
||||
typeName = getProperTypeName(
|
||||
url = typeUrl,
|
||||
types = objectTypes
|
||||
),
|
||||
type = typeUrl,
|
||||
layout = layout,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = layout,
|
||||
builder = urlBuilder
|
||||
),
|
||||
isSelected = false,
|
||||
removeable = false
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun List<ObjectWrapper.Basic>.toRelationFileValueView(
|
||||
ids: List<String>,
|
||||
urlBuilder: UrlBuilder
|
||||
): List<RelationValueBaseViewModel.RelationValueView.File> =
|
||||
this.mapNotNull { obj ->
|
||||
val image = obj.getProperFileImage(urlBuilder)
|
||||
if (obj.id !in ids) {
|
||||
RelationValueBaseViewModel.RelationValueView.File(
|
||||
id = obj.id,
|
||||
name = obj.getProperName(),
|
||||
ext = obj.getProperFileExt(),
|
||||
mime = obj.getProperFileMime(),
|
||||
image = image,
|
||||
isSelected = false
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun ObjectWrapper.Basic.getProperLayout() = layout ?: ObjectType.Layout.BASIC
|
||||
private fun ObjectWrapper.Basic.getProperType() = type.firstOrNull()
|
||||
private fun ObjectWrapper.Basic.getProperFileExt() = fileExt.orEmpty()
|
||||
private fun ObjectWrapper.Basic.getProperFileMime() = fileMimeType.orEmpty()
|
||||
|
||||
private fun getProperTypeName(url: String?, types: List<ObjectType>) =
|
||||
types.find { it.url == url }?.name.orEmpty()
|
||||
|
||||
private fun ObjectWrapper.Basic.getProperFileImage(urlBuilder: UrlBuilder): String? =
|
||||
iconImage?.let { if (it.isBlank()) null else urlBuilder.thumbnail(it) }
|
||||
|
||||
private fun ObjectWrapper.Basic.getProperName() = if (layout == ObjectType.Layout.NOTE) {
|
||||
snippet.orEmpty()
|
||||
} else {
|
||||
name.orEmpty()
|
||||
}
|
|
@ -10,6 +10,7 @@ object SupportedLayouts {
|
|||
ObjectType.Layout.IMAGE,
|
||||
ObjectType.Layout.PROFILE,
|
||||
ObjectType.Layout.SET,
|
||||
ObjectType.Layout.TODO
|
||||
ObjectType.Layout.TODO,
|
||||
ObjectType.Layout.NOTE
|
||||
)
|
||||
}
|
|
@ -19,20 +19,11 @@ object ObjectSetConfig {
|
|||
*/
|
||||
const val EMOJI_KEY = "iconEmoji"
|
||||
|
||||
/**
|
||||
* Image url key
|
||||
*/
|
||||
const val IMAGE_KEY = "iconImage"
|
||||
|
||||
/**
|
||||
* Object type key.
|
||||
*/
|
||||
const val TYPE_KEY = "type"
|
||||
|
||||
const val FILE_EXT_KEY = "fileExt"
|
||||
|
||||
const val FILE_MIME_KEY = "fileMimeType"
|
||||
|
||||
const val DEFAULT_LIMIT = 50
|
||||
}
|
||||
|
||||
|
|
|
@ -217,27 +217,6 @@ fun Relation.toCreateFilterStatusView(ids: List<*>? = null): List<CreateFilterVi
|
|||
)
|
||||
}
|
||||
|
||||
fun List<Map<String, Any?>>.toCreateFilterObjectView(
|
||||
ids: List<*>? = null,
|
||||
urlBuilder: UrlBuilder,
|
||||
objectTypes: List<ObjectType>
|
||||
): List<CreateFilterView.Object> =
|
||||
this.map { record ->
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val type = obj.type.firstOrNull()
|
||||
CreateFilterView.Object(
|
||||
id = obj.id,
|
||||
type = objectTypes.find { it.url == type }?.name.orEmpty(),
|
||||
name = obj.name.orEmpty(),
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.layout,
|
||||
builder = urlBuilder
|
||||
),
|
||||
isSelected = ids?.contains(obj.id) ?: false
|
||||
)
|
||||
}
|
||||
|
||||
fun Relation.toCreateFilterDateView(exactDayTimestamp: Long): List<CreateFilterView.Date> {
|
||||
val filterTime = Calendar.getInstance()
|
||||
if (exactDayTimestamp != EMPTY_TIMESTAMP) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.core_models.*
|
|||
import com.anytypeio.anytype.core_utils.ext.typeOf
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.objects.toRelationFileValueView
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectValueProvider
|
||||
import com.anytypeio.anytype.presentation.sets.RelationValueBaseViewModel
|
||||
|
@ -132,26 +133,11 @@ class RelationFileValueAddViewModel(
|
|||
)
|
||||
).process(
|
||||
failure = { Timber.e(it, "Error while getting objects") },
|
||||
success = {
|
||||
_views.value = it.mapNotNull { record ->
|
||||
val id = record[ObjectSetConfig.ID_KEY] as String
|
||||
val name = record[ObjectSetConfig.NAME_KEY] as String?
|
||||
val image = record[ObjectSetConfig.IMAGE_KEY] as String?
|
||||
val ext = record[ObjectSetConfig.FILE_EXT_KEY] as String?
|
||||
val mime = record[ObjectSetConfig.FILE_MIME_KEY] as String?
|
||||
if (id !in ids) {
|
||||
RelationValueBaseViewModel.RelationValueView.File(
|
||||
id = id,
|
||||
ext = ext.orEmpty(),
|
||||
mime = mime.orEmpty(),
|
||||
name = name.orEmpty(),
|
||||
image = if (image.isNullOrBlank()) null else urlBuilder.thumbnail(
|
||||
image
|
||||
),
|
||||
isSelected = false,
|
||||
)
|
||||
} else null
|
||||
}
|
||||
success = { objects ->
|
||||
_views.value = objects.toRelationFileValueView(
|
||||
ids = ids,
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,13 +4,11 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_utils.ext.typeOf
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.toRelationObjectValueView
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectValueProvider
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
|
@ -42,20 +40,17 @@ class RelationObjectValueAddViewModel(
|
|||
when (val ids = values[relation.key]) {
|
||||
is List<*> -> {
|
||||
proceedWithSearchObjects(
|
||||
ids = ids.typeOf(),
|
||||
relation = relation
|
||||
ids = ids.typeOf()
|
||||
)
|
||||
}
|
||||
is Id -> {
|
||||
proceedWithSearchObjects(
|
||||
ids = listOf(ids),
|
||||
relation = relation
|
||||
ids = listOf(ids)
|
||||
)
|
||||
}
|
||||
null -> {
|
||||
proceedWithSearchObjects(
|
||||
ids = emptyList(),
|
||||
relation = relation
|
||||
ids = emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +111,7 @@ class RelationObjectValueAddViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun proceedWithSearchObjects(ids: List<String>, relation: Relation) {
|
||||
private fun proceedWithSearchObjects(ids: List<String>) {
|
||||
viewModelScope.launch {
|
||||
searchObjects(
|
||||
SearchObjects.Params(
|
||||
|
@ -129,30 +124,11 @@ class RelationObjectValueAddViewModel(
|
|||
).process(
|
||||
failure = { Timber.e(it, "Error while getting objects") },
|
||||
success = { objects ->
|
||||
_views.value = objects.mapNotNull { obj ->
|
||||
val wrapped = ObjectWrapper.Basic(obj)
|
||||
val id = wrapped.id
|
||||
val type = wrapped.type
|
||||
val targetType = objectTypesProvider.get().find { it.url == type.firstOrNull() }
|
||||
val name = wrapped.name
|
||||
val layout = wrapped.layout
|
||||
if (id !in ids) {
|
||||
RelationValueView.Object(
|
||||
id = id,
|
||||
typeName = targetType?.name,
|
||||
type = type.firstOrNull(),
|
||||
name = name.orEmpty(),
|
||||
icon = ObjectIcon.from(
|
||||
obj = wrapped,
|
||||
layout = wrapped.layout,
|
||||
builder = urlBuilder
|
||||
),
|
||||
isSelected = false,
|
||||
layout = layout,
|
||||
removeable = false
|
||||
)
|
||||
} else null
|
||||
}
|
||||
_views.value = objects.toRelationObjectValueView(
|
||||
ids = ids,
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypes = objectTypesProvider.get()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,9 +12,8 @@ import com.anytypeio.anytype.domain.block.interactor.sets.GetObjectTypes
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
|
||||
import com.anytypeio.anytype.presentation.navigation.SupportNavigation
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.toView
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
@ -42,22 +41,10 @@ open class ObjectSearchViewModel(
|
|||
init {
|
||||
viewModelScope.launch {
|
||||
combine(objects, types) { listOfObjects, listOfTypes ->
|
||||
listOfObjects.map { obj ->
|
||||
val targetType = listOfTypes.find { type ->
|
||||
obj.type.contains(type.url)
|
||||
}
|
||||
DefaultObjectView(
|
||||
id = obj.id,
|
||||
name = obj.name.orEmpty(),
|
||||
typeName = targetType?.name.orEmpty(),
|
||||
typeLayout = obj.layout,
|
||||
icon = ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.layout,
|
||||
builder = urlBuilder
|
||||
)
|
||||
)
|
||||
}
|
||||
listOfObjects.toView(
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypes = listOfTypes
|
||||
)
|
||||
}.collectLatest { views ->
|
||||
if (views.isNotEmpty())
|
||||
stateData.postValue(ObjectSearchView.Success(views))
|
||||
|
@ -94,7 +81,7 @@ open class ObjectSearchViewModel(
|
|||
searchQuery.collectLatest { query ->
|
||||
val params = getSearchObjectsParams().copy(fulltext = query)
|
||||
searchObjects(params = params).process(
|
||||
success = { raw -> setObjects(raw.map { ObjectWrapper.Basic(it) }) },
|
||||
success = { objects -> setObjects(objects) },
|
||||
failure = { Timber.e(it, "Error while searching for objects") }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ sealed class CreateFilterView {
|
|||
data class Object(
|
||||
val id: Id,
|
||||
val name: String,
|
||||
val type: String?,
|
||||
val typeName: String?,
|
||||
val icon: ObjectIcon,
|
||||
override val isSelected: Boolean
|
||||
): CreateFilterView() {
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.anytypeio.anytype.presentation.extension.index
|
|||
import com.anytypeio.anytype.presentation.extension.toConditionView
|
||||
import com.anytypeio.anytype.presentation.extension.type
|
||||
import com.anytypeio.anytype.presentation.mapper.toDomain
|
||||
import com.anytypeio.anytype.presentation.objects.toCreateFilterObjectView
|
||||
import com.anytypeio.anytype.presentation.relations.*
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSet
|
||||
|
@ -192,7 +193,7 @@ open class FilterViewModel(
|
|||
proceedWithFilterValueList(
|
||||
relation = relation,
|
||||
filter = null,
|
||||
objecttypes = objectTypesProvider.get()
|
||||
objectTypes = objectTypesProvider.get()
|
||||
)
|
||||
} else {
|
||||
val filter = viewer.filters[index]
|
||||
|
@ -205,7 +206,7 @@ open class FilterViewModel(
|
|||
proceedWithFilterValueList(
|
||||
relation = relation,
|
||||
filter = filter,
|
||||
objecttypes = objectTypesProvider.get()
|
||||
objectTypes = objectTypesProvider.get()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +214,7 @@ open class FilterViewModel(
|
|||
private fun proceedWithFilterValueList(
|
||||
relation: Relation,
|
||||
filter: DVFilter?,
|
||||
objecttypes: List<ObjectType>
|
||||
objectTypes: List<ObjectType>
|
||||
) = when (relation.format) {
|
||||
Relation.Format.DATE -> {
|
||||
val timestamp = (filter?.value as? Double)?.toLong() ?: EMPTY_TIMESTAMP
|
||||
|
@ -237,8 +238,7 @@ open class FilterViewModel(
|
|||
val ids = filter?.value as? List<*>
|
||||
proceedWithSearchObjects(
|
||||
ids = ids,
|
||||
relation = relation,
|
||||
objectTypes = objecttypes
|
||||
objectTypes = objectTypes
|
||||
)
|
||||
}
|
||||
Relation.Format.CHECKBOX -> {
|
||||
|
@ -253,7 +253,6 @@ open class FilterViewModel(
|
|||
|
||||
private fun proceedWithSearchObjects(
|
||||
ids: List<*>? = null,
|
||||
relation: Relation,
|
||||
objectTypes: List<ObjectType>
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
|
@ -267,8 +266,8 @@ open class FilterViewModel(
|
|||
)
|
||||
).process(
|
||||
failure = { Timber.e(it, "Error while getting objects") },
|
||||
success = {
|
||||
filterValueListState.value = it.toCreateFilterObjectView(
|
||||
success = { objects ->
|
||||
filterValueListState.value = objects.toCreateFilterObjectView(
|
||||
ids = ids,
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypes = objectTypes
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.Config
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetProfile
|
||||
|
@ -15,7 +16,8 @@ import com.anytypeio.anytype.domain.config.DebugSettings
|
|||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.config.GetConfig
|
||||
import com.anytypeio.anytype.domain.config.GetDebugSettings
|
||||
import com.anytypeio.anytype.domain.dashboard.interactor.*
|
||||
import com.anytypeio.anytype.domain.dashboard.interactor.CloseDashboard
|
||||
import com.anytypeio.anytype.domain.dashboard.interactor.OpenDashboard
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
|
||||
|
@ -180,7 +182,7 @@ open class DashboardTestSetup {
|
|||
objects: List<Map<String, Any?>> = emptyList()
|
||||
) {
|
||||
searchObjects.stub {
|
||||
onBlocking { invoke(params) } doReturn Either.Right(objects)
|
||||
onBlocking { invoke(params) } doReturn Either.Right(objects.map { ObjectWrapper.Basic(it) })
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package com.anytypeio.anytype.presentation.mapper
|
||||
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.objects.toView
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
|
@ -154,6 +156,52 @@ class ObjectWrapperExtensionsKtTest {
|
|||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should map to view with snippet as name when layout is note`() {
|
||||
|
||||
val imageHash = "ycd79"
|
||||
|
||||
val obj = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
"id" to "Ef6",
|
||||
"name" to "LmL7R",
|
||||
"snippet" to "OMr2Y",
|
||||
"layout" to ObjectType.Layout.NOTE.code.toDouble()
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
val result = listOf(obj).toView(urlBuilder, objectTypes = listOf())
|
||||
|
||||
assertEquals(
|
||||
expected = "OMr2Y",
|
||||
actual = result.first().name
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should map to view with snippet as name when layout is not note`() {
|
||||
|
||||
val imageHash = "ycd79"
|
||||
|
||||
val obj = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
"id" to "Ef6",
|
||||
"name" to "LmL7R",
|
||||
"snippet" to "OMr2Y",
|
||||
"layout" to ObjectType.Layout.BASIC.code.toDouble()
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
val result = listOf(obj).toView(urlBuilder, objectTypes = listOf())
|
||||
|
||||
assertEquals(
|
||||
expected = "LmL7R",
|
||||
actual = result.first().name
|
||||
)
|
||||
}
|
||||
|
||||
fun stubUrlBuilder(hash: String?) {
|
||||
if (hash == null) {
|
||||
urlBuilder.stub {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue