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

DROID-1948 Tech | Object type unique key refactoring (#571)

This commit is contained in:
Konstantin Ivanov 2023-11-22 12:00:06 +01:00 committed by GitHub
parent 0111484a61
commit 9340e2617e
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 151 additions and 132 deletions

View file

@ -7,7 +7,7 @@ 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.domain.types.CreateType
import com.anytypeio.anytype.domain.types.CreateObjectType
import com.anytypeio.anytype.domain.workspace.SpaceManager
import com.anytypeio.anytype.emojifier.data.Emoji
import com.anytypeio.anytype.emojifier.data.EmojiProvider
@ -50,7 +50,7 @@ object CreateObjectTypeModule {
fun provideCreateTypeInteractor(
blockRepository: BlockRepository,
dispatchers: AppCoroutineDispatchers
): CreateType = CreateType(blockRepository, dispatchers)
): CreateObjectType = CreateObjectType(blockRepository, dispatchers)
@Module
interface Declarations {

View file

@ -160,7 +160,7 @@ sealed class ObjectWrapper {
data class Type(override val map: Struct) : ObjectWrapper() {
private val default = map.withDefault { null }
val id: Id by default
val uniqueKey: String? by default
val uniqueKey: String by default
val name: String? by default
val sourceObject: Id? get() = getSingleValue(Relations.SOURCE_OBJECT)
val description: String? by default
@ -176,10 +176,6 @@ sealed class ObjectWrapper {
else -> ObjectType.Layout.BASIC
}
val defaultTemplateId: Id? by default
val key: String? get() = uniqueKey
val isValid get() = map.containsKey(Relations.UNIQUE_KEY)
}
data class Relation(override val map: Struct) : ObjectWrapper() {

View file

@ -2,6 +2,8 @@ package com.anytypeio.anytype.core_models.ext
import com.anytypeio.anytype.core_models.Event
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.Struct
fun Map<Id, Struct>.process(event: Event.Command.Details) = when (event) {
@ -37,4 +39,8 @@ fun Map<Id, Struct>.unset(
val curr = getOrDefault(target, emptyMap())
val update = curr - keys
return this + mapOf(target to update)
}
}
fun Struct.mapToObjectWrapperType(): ObjectWrapper.Type? =
if (containsKey(Relations.ID) && containsKey(Relations.UNIQUE_KEY)) ObjectWrapper.Type(this)
else null

View file

@ -604,7 +604,7 @@ class BlockDataRepository(
space: Id,
name: String,
emojiUnicode: String?,
): ObjectWrapper.Type = remote.createType(
): Struct? = remote.createType(
space = space,
name = name,
emojiUnicode = emojiUnicode
@ -782,7 +782,7 @@ class BlockDataRepository(
override suspend fun addObjectToSpace(
command: Command.AddObjectToSpace
): Pair<Id, ObjectWrapper.Type> = remote.addObjectToSpace(command)
): Pair<Id, Struct?> = remote.addObjectToSpace(command)
override suspend fun removeObjectFromWorkspace(objects: List<Id>): List<Id> {
return remote.removeObjectFromWorkspace(

View file

@ -250,7 +250,7 @@ interface BlockRemote {
space: Id,
name: String,
emojiUnicode: String?
): ObjectWrapper.Type
): Struct?
suspend fun createRelationOption(
space: Id,
@ -334,7 +334,7 @@ interface BlockRemote {
suspend fun getSpaceConfig(space: Id): Config
suspend fun addObjectListToSpace(objects: List<Id>, space: Id): List<Id>
suspend fun addObjectToSpace(command: Command.AddObjectToSpace) : Pair<Id, ObjectWrapper.Type>
suspend fun addObjectToSpace(command: Command.AddObjectToSpace) : Pair<Id, Struct?>
suspend fun removeObjectFromWorkspace(objects: List<Id>): List<Id>
suspend fun createObject(command: Command.CreateObject): CreateObjectResult

View file

@ -4,6 +4,7 @@ import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
@ -23,9 +24,10 @@ class GetObjectTypes @Inject constructor(
offset = params.offset,
fulltext = params.query
)
return result.map { struct ->
ObjectWrapper.Type(struct)
}
return result
.mapNotNull {
it.mapToObjectWrapperType()
}
}
data class Params(

View file

@ -306,7 +306,7 @@ interface BlockRepository {
space: Id,
name: String,
emojiUnicode: String?
): ObjectWrapper.Type
): Struct?
suspend fun createRelationOption(
space: Id,
@ -386,7 +386,7 @@ interface BlockRepository {
suspend fun createWorkspace(details: Struct): Id
suspend fun getSpaceConfig(space: Id): Config
suspend fun addObjectListToSpace(objects: List<Id>, space: Id) : List<Id>
suspend fun addObjectToSpace(command: Command.AddObjectToSpace) : Pair<Id, ObjectWrapper.Type>
suspend fun addObjectToSpace(command: Command.AddObjectToSpace) : Pair<Id, Struct?>
suspend fun removeObjectFromWorkspace(objects: List<Id>) : List<Id>
suspend fun createWidget(

View file

@ -8,6 +8,7 @@ import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeUniqueKeys
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_models.primitives.TypeId
import com.anytypeio.anytype.core_models.primitives.TypeKey
@ -36,9 +37,7 @@ class GetDefaultObjectType @Inject constructor(
space = space
)
return if (item != null) {
val key = item.uniqueKey?.let {
TypeKey(it)
} ?: TypeKey(ObjectTypeUniqueKeys.NOTE)
val key = TypeKey(item.uniqueKey)
val id = TypeId(item.id)
Response(
type = key,
@ -55,7 +54,7 @@ class GetDefaultObjectType @Inject constructor(
}
private suspend fun fetchDefaultType(): Response {
val items = blockRepository.searchObjects(
val structs = blockRepository.searchObjects(
limit = 1,
fulltext = NO_VALUE,
filters = buildList {
@ -90,15 +89,15 @@ class GetDefaultObjectType @Inject constructor(
Relations.DEFAULT_TEMPLATE_ID
)
)
if (items.isNotEmpty()) {
val note = ObjectWrapper.Type(items.first())
val key = TypeKey(note.uniqueKey ?: throw IllegalStateException("Default type has empty key"))
val id = TypeId(note.id)
val objType = structs.firstOrNull()?.mapToObjectWrapperType()
if (objType != null) {
val key = TypeKey(objType.uniqueKey)
val id = TypeId(objType.id)
return Response(
type = key,
name = note.name,
name = objType.name,
id = id,
defaultTemplate = note.defaultTemplateId
defaultTemplate = objType.defaultTemplateId
)
} else {
throw IllegalStateException("Default type not found")
@ -109,7 +108,7 @@ class GetDefaultObjectType @Inject constructor(
type: TypeId,
space: SpaceId
): ObjectWrapper.Type? {
val items = blockRepository.searchObjects(
val structs = blockRepository.searchObjects(
limit = 1,
fulltext = NO_VALUE,
filters = buildList {
@ -132,11 +131,7 @@ class GetDefaultObjectType @Inject constructor(
Relations.DEFAULT_TEMPLATE_ID
)
)
return if (items.isNotEmpty()) {
ObjectWrapper.Type(items.first())
} else {
null
}
return structs.firstOrNull()?.mapToObjectWrapperType()
}
private fun filterObjectTypeLibrary(space: SpaceId) = listOf(

View file

@ -50,6 +50,15 @@ class ObjectTypesSubscriptionManager (
condition = DVFilterCondition.NOT_EQUAL,
value = true
),
DVFilter(
relation = Relations.IS_ARCHIVED,
condition = DVFilterCondition.NOT_EQUAL,
value = true
),
DVFilter(
relation = Relations.UNIQUE_KEY,
condition = DVFilterCondition.NOT_EMPTY
),
),
limit = 0,
offset = 0L,

View file

@ -2,7 +2,7 @@ package com.anytypeio.anytype.domain.spaces
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
@ -35,7 +35,7 @@ class AddObjectToSpace(
data class Result(
val id: Id,
val type: ObjectWrapper.Type
val type: Struct?
)
}

View file

@ -2,21 +2,22 @@ package com.anytypeio.anytype.domain.types
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
// TODO rename to "CreateObjectType" after refactoring
class CreateType(
class CreateObjectType(
private val repo: BlockRepository,
dispatchers: AppCoroutineDispatchers
) : ResultInteractor<CreateType.Params, ObjectWrapper.Type>(dispatchers.io) {
override suspend fun doWork(params: Params): ObjectWrapper.Type {
return repo.createType(
) : ResultInteractor<CreateObjectType.Params, ObjectWrapper.Type?>(dispatchers.io) {
override suspend fun doWork(params: Params): ObjectWrapper.Type? {
val result = repo.createType(
space = params.space,
name = params.name,
emojiUnicode = params.emojiUnicode
)
return result?.mapToObjectWrapperType()
}
class Params(

View file

@ -678,7 +678,7 @@ class BlockMiddleware(
space: Id,
name: String,
emojiUnicode: String?
): ObjectWrapper.Type = middleware.objectCreateObjectType(
): Struct? = middleware.objectCreateObjectType(
space = space,
name = name,
emojiUnicode = emojiUnicode
@ -738,7 +738,7 @@ class BlockMiddleware(
override suspend fun addObjectToSpace(
command: Command.AddObjectToSpace
): Pair<Id, ObjectWrapper.Type> = middleware.workspaceObjectAdd(command)
): Pair<Id, Struct?> = middleware.workspaceObjectAdd(command)
override suspend fun removeObjectFromWorkspace(objects: List<Id>): List<Id> {
return middleware.workspaceObjectListRemove(objects)

View file

@ -952,7 +952,7 @@ class Middleware @Inject constructor(
space: Id,
name: String,
emojiUnicode: String?
): ObjectWrapper.Type {
): Struct {
val request = Rpc.Object.CreateObjectType.Request(
details = buildMap {
put(Relations.NAME, name)
@ -965,9 +965,7 @@ class Middleware @Inject constructor(
if (BuildConfig.DEBUG) logRequest(request)
val response = service.objectCreateObjectType(request)
if (BuildConfig.DEBUG) logResponse(response)
return ObjectWrapper.Type(
response.details ?: throw IllegalStateException("Missing details")
)
return response.details ?: throw IllegalStateException("Null object type struct")
}
@Throws(Exception::class)
@ -1995,7 +1993,7 @@ class Middleware @Inject constructor(
}
@Throws(Exception::class)
fun workspaceObjectAdd(command: Command.AddObjectToSpace): Pair<Id, ObjectWrapper.Type> {
fun workspaceObjectAdd(command: Command.AddObjectToSpace): Pair<Id, Struct?> {
val request = Rpc.Workspace.Object.Add.Request(
objectId = command.objectId,
spaceId = command.space
@ -2003,7 +2001,7 @@ class Middleware @Inject constructor(
if (BuildConfig.DEBUG) logRequest(request)
val response = service.workspaceObjectAdd(request)
if (BuildConfig.DEBUG) logResponse(response)
return Pair(response.objectId, ObjectWrapper.Type(response.details ?: emptyMap()))
return Pair(response.objectId, response.details)
}
@Throws(Exception::class)

View file

@ -28,6 +28,7 @@ import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.core_models.RelationLink
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.SyncStatus
import com.anytypeio.anytype.core_models.TextBlock
import com.anytypeio.anytype.core_models.ThemeColor
@ -38,6 +39,7 @@ import com.anytypeio.anytype.core_models.ext.content
import com.anytypeio.anytype.core_models.ext.descendants
import com.anytypeio.anytype.core_models.ext.isAllTextAndNoneCodeBlocks
import com.anytypeio.anytype.core_models.ext.isAllTextBlocks
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_models.ext.parents
import com.anytypeio.anytype.core_models.ext.process
import com.anytypeio.anytype.core_models.ext.sortByType
@ -4861,7 +4863,6 @@ class EditorViewModel(
val objectDetails = details.details[context]?.map ?: emptyMap()
val objectWrapper = ObjectWrapper.Basic(objectDetails)
val objectType = objectWrapper.getProperType()
val objectTypeWrapper = ObjectWrapper.Type(details.details[objectType]?.map ?: emptyMap())
val relationLinks = orchestrator.stores.relationLinks.current()
viewModelScope.launch {
@ -4877,7 +4878,7 @@ class EditorViewModel(
ctx = context,
objectDetails = objectDetails,
relationLinks = relationLinks,
objectTypeWrapper = objectTypeWrapper,
objectTypeStruct = details.details[objectType]?.map,
details = details
)
val update =
@ -4911,12 +4912,14 @@ class EditorViewModel(
ctx: Id,
objectDetails: Map<Key, Any?>,
relationLinks: List<RelationLink>,
objectTypeWrapper: ObjectWrapper.Type,
objectTypeStruct: Struct?,
details: Block.Details
): List<ObjectRelationView> {
val objType = objectTypeStruct?.mapToObjectWrapperType()
val recommendedRelations = objType?.recommendedRelations ?: emptyList()
return getNotIncludedRecommendedRelations(
relationLinks = relationLinks,
recommendedRelations = objectTypeWrapper.recommendedRelations,
recommendedRelations = recommendedRelations,
storeOfRelations = storeOfRelations
).views(
context = ctx,
@ -6251,11 +6254,8 @@ class EditorViewModel(
val details = orchestrator.stores.details.current()
val currentObject = ObjectWrapper.Basic(details.details[context]?.map ?: emptyMap())
val currentObjectTypeId = currentObject.getProperType() ?: return null
return if (details.details.containsKey(currentObjectTypeId)) {
ObjectWrapper.Type(details.details[currentObjectTypeId]?.map ?: emptyMap())
} else {
null
}
val struct = details.details[currentObjectTypeId]?.map
return struct?.mapToObjectWrapperType()
}
fun isObjectTemplate(): Boolean {

View file

@ -48,6 +48,7 @@ import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.TextStyle
import com.anytypeio.anytype.core_models.ThemeMode
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_utils.ext.Mimetype
import com.anytypeio.anytype.domain.config.ConfigStorage
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
@ -1951,8 +1952,7 @@ private fun getAnalyticsObjectType(
ctx: Id
): String {
val objTypeId = details[ctx]?.type?.firstOrNull()
val sourceObject = if (objTypeId != null) {
ObjectWrapper.Type(details[objTypeId]?.map ?: emptyMap()).sourceObject
} else null
return sourceObject ?: OBJ_TYPE_CUSTOM
val typeStruct = details[objTypeId]?.map
val objType = typeStruct?.mapToObjectWrapperType()
return objType?.sourceObject ?: OBJ_TYPE_CUSTOM
}

View file

@ -600,7 +600,7 @@ fun RelationFormat.toView() = when (this) {
fun ObjectWrapper.Type.toObjectTypeView(selectedSources: List<Id> = emptyList()): ObjectTypeView =
ObjectTypeView(
id = id,
key = uniqueKey.orEmpty(),
key = uniqueKey,
name = name.orEmpty(),
emoji = iconEmoji,
description = description,

View file

@ -76,7 +76,7 @@ class CreateObjectOfTypeViewModel(
groups.map { type ->
SelectTypeView.Type(
id = type.id,
typeKey = type.uniqueKey!!,
typeKey = type.uniqueKey,
name = type.name.orEmpty(),
icon = type.iconEmoji.orEmpty()
)
@ -91,7 +91,7 @@ class CreateObjectOfTypeViewModel(
objects.map { type ->
SelectTypeView.Type(
id = type.id,
typeKey = type.uniqueKey!!,
typeKey = type.uniqueKey,
name = type.name.orEmpty(),
icon = type.iconEmoji.orEmpty()
)

View file

@ -9,6 +9,7 @@ import com.anytypeio.anytype.core_models.MarketplaceObjectTypeIds
import com.anytypeio.anytype.core_models.MarketplaceObjectTypeIds.MARKETPLACE_OBJECT_TYPE_PREFIX
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.block.interactor.sets.GetObjectTypes
@ -148,18 +149,8 @@ class ObjectTypeChangeViewModel(
space = spaceManager.get()
)
addObjectTypeToSpace.async(params = params).fold(
onSuccess = { result ->
commands.emit(Command.TypeAdded(type = result.type.name.orEmpty()))
proceedWithDispatchingType(
item = ObjectTypeView(
id = result.id,
key = result.type.uniqueKey.orEmpty(),
name = result.type.name.orEmpty(),
description = result.type.description.orEmpty(),
emoji = result.type.iconEmoji,
defaultTemplate = result.type.defaultTemplateId
)
)
onSuccess = {
proceedWithNewlyAddedObjectType(it)
},
onFailure = {
Timber.e(it, "Error while adding object by id:${item.id} to space")
@ -174,6 +165,27 @@ class ObjectTypeChangeViewModel(
}
}
private suspend fun proceedWithNewlyAddedObjectType(result: AddObjectToSpace.Result) {
val struct = result.type
val type = struct?.mapToObjectWrapperType()
if (type != null) {
commands.emit(Command.TypeAdded(type = type.name.orEmpty()))
proceedWithDispatchingType(
item = ObjectTypeView(
id = result.id,
key = type.uniqueKey,
name = type.name.orEmpty(),
description = type.description.orEmpty(),
emoji = type.iconEmoji,
defaultTemplate = type.defaultTemplateId
)
)
} else {
Timber.e("Type is not valid")
sendToast("Error while adding object type by id:${result.id} to space")
}
}
private suspend fun proceedWithDispatchingType(
item: ObjectTypeView
) {
@ -226,7 +238,7 @@ class ObjectTypeChangeViewModel(
query: String
): List<ObjectWrapper.Type> {
val excludedMarketplaceTypes = buildList {
addAll(myTypes.mapNotNull { it.uniqueKey })
addAll(myTypes.map { it.uniqueKey })
if (!setup.isWithBookmark) {
add(MarketplaceObjectTypeIds.BOOKMARK)
}

View file

@ -11,6 +11,7 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
@ -105,10 +106,12 @@ class ObjectMenuViewModel(
add(ObjectAction.UNDO_REDO)
val objTypeId = storage.details.current().details[ctx]?.type?.firstOrNull()
storage.details.current().details[objTypeId]?.let { objType ->
val objTypeWrapper = ObjectWrapper.Type(objType.map)
val isTemplateAllowed = objTypeWrapper.isTemplatesAllowed()
val details = storage.details.current().details
val objTypeId = details[ctx]?.type?.firstOrNull()
val typeStruct = details[objTypeId]?.map
val objType = typeStruct?.mapToObjectWrapperType()
if (objType != null) {
val isTemplateAllowed = objType.isTemplatesAllowed()
if (isTemplateAllowed && !isTemplate) {
add(ObjectAction.USE_AS_TEMPLATE)
}
@ -272,13 +275,9 @@ class ObjectMenuViewModel(
private fun proceedWithSettingAsDefaultTemplate(ctx: Id) {
val startTime = System.currentTimeMillis()
val objTemplate = ObjectWrapper.Basic(
storage.details.current().details[ctx]?.map ?: emptyMap()
)
val details = storage.details.current().details
val objTemplate = ObjectWrapper.Basic(details[ctx]?.map ?: emptyMap())
val targetObjectTypeId = objTemplate.targetObjectType ?: return
val objType = ObjectWrapper.Type(
storage.details.current().details[targetObjectTypeId]?.map ?: emptyMap()
)
viewModelScope.launch {
val params = SetObjectDetails.Params(
ctx = targetObjectTypeId,
@ -286,6 +285,7 @@ class ObjectMenuViewModel(
)
setObjectDetails.async(params).fold(
onSuccess = {
val objType = details[targetObjectTypeId]?.map?.mapToObjectWrapperType()
sendAnalyticsDefaultTemplateEvent(analytics, objType, startTime)
_toasts.emit("The template was set as default")
isDismissed.value = true
@ -324,9 +324,10 @@ class ObjectMenuViewModel(
private suspend fun buildOpenTemplateCommand(ctx: Id, template: Id) {
val details = storage.details.current().details
val type = details[ctx]?.type?.firstOrNull()
val objType = ObjectWrapper.Type(details[type]?.map ?: emptyMap())
val objTypeKey = objType.key
if (objTypeKey != null) {
val typeStruct = details[type]?.map
val objType = typeStruct?.mapToObjectWrapperType()
if (objType != null) {
val objTypeKey = objType.uniqueKey
val command = Command.OpenTemplate(
templateId = template,
typeId = objType.id,
@ -335,8 +336,7 @@ class ObjectMenuViewModel(
)
commands.emit(command)
} else {
Timber.e("Error while opening template from object, type $type has no key)}")
sendToast("Couldn't open template from object")
Timber.e("Error while opening template from object, type:$type hasn't key")
}
}

View file

@ -14,6 +14,7 @@ import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.core_models.RelationLink
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_utils.diff.DefaultObjectDiffIdentifier
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.`object`.UpdateDetail
@ -87,8 +88,12 @@ class RelationListViewModel(
val objectDetails = details.details[ctx]?.map ?: emptyMap()
val objectWrapper = ObjectWrapper.Basic(objectDetails)
val objectType = objectWrapper.getProperType()
val objectTypeWrapper = ObjectWrapper.Type(details.details[objectType]?.map ?: emptyMap())
val objectTypeId = objectWrapper.getProperType()
val objectTypeWrapper = details.details[objectTypeId]?.map?.mapToObjectWrapperType()
if (objectTypeWrapper == null) {
Timber.e("Couldn't find valid object type for id: $objectTypeId")
return emptyList()
}
val objectRelationViews = getObjectRelationsView(
ctx = ctx,

View file

@ -5,6 +5,7 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_utils.const.DateConst
import com.anytypeio.anytype.core_utils.ext.typeOf
import com.anytypeio.anytype.domain.misc.UrlBuilder
@ -230,12 +231,8 @@ fun Block.Details.objectTypeRelation(
isFeatured: Boolean,
objectTypeId: Id
): ObjectRelationView {
val typeDetails = details[objectTypeId]?.map
val objectType = if (typeDetails != null) {
ObjectWrapper.Type(typeDetails)
} else {
null
}
val typeStruct = details[objectTypeId]?.map
val objectType = typeStruct?.mapToObjectWrapperType()
return if (objectType == null || objectType.isDeleted == true) {
ObjectRelationView.ObjectType.Deleted(
id = objectTypeId,
@ -248,7 +245,7 @@ fun Block.Details.objectTypeRelation(
ObjectRelationView.ObjectType.Base(
id = objectTypeId,
key = relationKey,
name = details[objectTypeId]?.name.orEmpty(),
name = objectType.name.orEmpty(),
featured = isFeatured,
readOnly = false,
type = objectTypeId,

View file

@ -671,6 +671,10 @@ object ObjectSearchConstants {
relation = Relations.SPACE_ID,
condition = DVFilterCondition.IN,
value = spaces
),
DVFilter(
relation = Relations.UNIQUE_KEY,
condition = DVFilterCondition.NOT_EMPTY
)
)
)

View file

@ -14,10 +14,10 @@ import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVVie
import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVViewerRelationUpdate
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_models.ext.title
import com.anytypeio.anytype.core_models.primitives.TypeId
import com.anytypeio.anytype.core_models.primitives.TypeKey
@ -47,7 +47,6 @@ import com.anytypeio.anytype.presentation.sets.state.ObjectState.Companion.VIEW_
import com.anytypeio.anytype.presentation.sets.state.ObjectState.Companion.VIEW_TYPE_UNSUPPORTED
import com.anytypeio.anytype.presentation.sets.viewer.ViewerView
import com.anytypeio.anytype.presentation.templates.TemplateView
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
import timber.log.Timber
fun ObjectState.DataView.featuredRelations(
@ -119,7 +118,7 @@ private fun ObjectState.DataView.mapFeaturedRelations(
when (key) {
Relations.DESCRIPTION -> null
Relations.TYPE -> details.details[ctx]?.type?.firstOrNull()?.let { typeId ->
val objectType = details.details[typeId]?.map?.let { ObjectWrapper.Type(it) }
val objectType = details.details[typeId]?.map?.mapToObjectWrapperType()
if (objectType?.isDeleted == true) {
ObjectRelationView.ObjectType.Deleted(
id = typeId,
@ -550,9 +549,9 @@ suspend fun ObjectState.DataView.getActiveViewTypeAndTemplate(
Timber.d("Set by type setOf param is null or empty, not possible to get Type and Template")
Pair(null, null)
} else {
val defaultSetObjectType = ObjectWrapper.Type(details[setOf]?.map.orEmpty())
val defaultSetObjectType = details[setOf]?.map?.mapToObjectWrapperType()
if (activeView.defaultTemplate.isNullOrEmpty()) {
val defaultTemplateId = defaultSetObjectType.defaultTemplateId
val defaultTemplateId = defaultSetObjectType?.defaultTemplateId
Pair(defaultSetObjectType, defaultTemplateId)
} else {
Pair(defaultSetObjectType, activeView.defaultTemplate)

View file

@ -1606,7 +1606,7 @@ class ObjectSetViewModel(
val dataView = stateReducer.state.value.dataViewState() ?: return@launch
val viewer = getViewer(dataView) ?: return@launch
val (type, _) = dataView.getActiveViewTypeAndTemplate(context, viewer, storeOfObjectTypes)
if (type == null || !type.isValid) return@launch
if (type == null) return@launch
typeTemplatesWidgetState.value = createState(viewer)
selectedTypeFlow.value = SelectedType(type.id, type.defaultTemplateId)
}
@ -1851,9 +1851,7 @@ class ObjectSetViewModel(
if (viewerDefType == null) return emptyList()
val viewerDefTypeId = viewerDefType.id
val viewerDefTypeKey =
(if (viewerDefType.uniqueKey != null) TypeKey(viewerDefType.uniqueKey!!) else null)
?: return emptyList()
val viewerDefTypeKey = TypeKey(viewerDefType.uniqueKey)
val isTemplatesAllowed = viewerDefType.isTemplatesAllowed()

View file

@ -75,16 +75,13 @@ class TemplateSelectViewModel(
layout = objType.recommendedLayout?.code ?: 0
)
)
addAll(templates.mapNotNull {
val typeKey = objType.key
if (typeKey != null) {
TemplateSelectView.Template(
id = it.id,
layout = it.layout ?: ObjectType.Layout.BASIC,
typeId = objType.id,
typeKey = typeKey
)
} else null
addAll(templates.map {
TemplateSelectView.Template(
id = it.id,
layout = it.layout ?: ObjectType.Layout.BASIC,
typeId = objType.id,
typeKey = objType.uniqueKey
)
})
}
_viewState.emit(

View file

@ -13,7 +13,7 @@ import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_utils.ext.orNull
import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.types.CreateType
import com.anytypeio.anytype.domain.types.CreateObjectType
import com.anytypeio.anytype.domain.workspace.SpaceManager
import com.anytypeio.anytype.emojifier.data.EmojiProvider
import com.anytypeio.anytype.presentation.navigation.NavigationViewModel
@ -28,7 +28,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
class CreateObjectTypeViewModel(
private val createTypeInteractor: CreateType,
private val createObjectType: CreateObjectType,
private val urlBuilder: UrlBuilder,
private val emojiProvider: EmojiProvider,
private val analytics: Analytics,
@ -61,8 +61,8 @@ class CreateObjectTypeViewModel(
return
}
viewModelScope.launch {
createTypeInteractor.execute(
CreateType.Params(
createObjectType.execute(
CreateObjectType.Params(
space = spaceManager.get(),
name = name,
emojiUnicode = uiState.value.emojiUnicode.orNull()
@ -105,7 +105,7 @@ class CreateObjectTypeViewModel(
}
class Factory @Inject constructor(
private val createType: CreateType,
private val createObjectType: CreateObjectType,
private val urlBuilder: UrlBuilder,
private val emojiProvider: EmojiProvider,
private val analytics: Analytics,
@ -114,7 +114,7 @@ class CreateObjectTypeViewModel(
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return CreateObjectTypeViewModel(
createTypeInteractor = createType,
createObjectType = createObjectType,
urlBuilder = urlBuilder,
emojiProvider = emojiProvider,
analytics = analytics,

View file

@ -337,7 +337,7 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
SlashItem.ObjectType(
objectTypeView = ObjectTypeView(
id = type1.id,
key = type1.uniqueKey.orEmpty(),
key = type1.uniqueKey,
name = type1.name.orEmpty(),
description = type1.description,
emoji = type1.iconEmoji
@ -346,7 +346,7 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
SlashItem.ObjectType(
objectTypeView = ObjectTypeView(
id = type2.id,
key = type2.uniqueKey.orEmpty(),
key = type2.uniqueKey,
name = type2.name.orEmpty(),
description = type2.description,
emoji = type2.iconEmoji
@ -355,7 +355,7 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
SlashItem.ObjectType(
objectTypeView = ObjectTypeView(
id = type3.id,
key = type3.uniqueKey.orEmpty(),
key = type3.uniqueKey,
name = type3.name.orEmpty(),
description = type3.description,
emoji = type3.iconEmoji

View file

@ -479,7 +479,7 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
SlashItem.ObjectType(
objectTypeView = ObjectTypeView(
id = type1.id,
key = type1.uniqueKey.orEmpty(),
key = type1.uniqueKey,
name = type1.name.orEmpty(),
description = type1.description,
emoji = type1.iconEmoji
@ -488,7 +488,7 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
SlashItem.ObjectType(
objectTypeView = ObjectTypeView(
id = type2.id,
key = type2.uniqueKey.orEmpty(),
key = type2.uniqueKey,
name = type2.name.orEmpty(),
description = type2.description,
emoji = type2.iconEmoji

View file

@ -535,7 +535,7 @@ class ObjectTypeChangeViewModelTest {
expected = ObjectTypeChangeViewModel.Command.DispatchType(
ObjectTypeView(
id = expectedType.id,
key = expectedType.key!!,
key = expectedType.uniqueKey,
name = expectedType.name.orEmpty(),
description = expectedType.description.orEmpty(),
emoji = null