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

DROID-3429 Primitives | Edit type properties, part 1 (#2138)

This commit is contained in:
Konstantin Ivanov 2025-03-10 13:46:53 +01:00 committed by GitHub
parent b566ba30e0
commit 3932c2fe87
Signed by: github
GPG key ID: B5690EEEBB952194
42 changed files with 750 additions and 1142 deletions

View file

@ -0,0 +1,58 @@
plugins {
id "com.android.library"
id "kotlin-android"
alias(libs.plugins.compose.compiler)
}
android {
defaultConfig {
buildConfigField "boolean", "USE_NEW_WINDOW_INSET_API", "true"
buildConfigField "boolean", "USE_EDGE_TO_EDGE", "true"
}
buildFeatures {
compose true
}
namespace 'com.anytypeio.anytype.feature_properties'
}
dependencies {
implementation project(':domain')
implementation project(':core-ui')
implementation project(':analytics')
implementation project(':core-models')
implementation project(':core-utils')
implementation project(':localization')
implementation project(':presentation')
compileOnly libs.javaxInject
implementation libs.lifecycleViewModel
implementation libs.lifecycleRuntime
implementation libs.appcompat
implementation libs.compose
implementation libs.fragmentCompose
implementation libs.composeFoundation
implementation libs.composeToolingPreview
implementation libs.composeMaterial3
implementation libs.navigationCompose
debugImplementation libs.composeTooling
implementation libs.timber
testImplementation project(':test:android-utils')
testImplementation project(':test:utils')
testImplementation project(":test:core-models-stub")
testImplementation libs.junit
testImplementation libs.kotlinTest
testImplementation libs.androidXTestCore
testImplementation libs.mockitoKotlin
testImplementation libs.coroutineTesting
testImplementation libs.timberJUnit
testImplementation libs.turbine
}

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest/>

View file

@ -0,0 +1,5 @@
package com.anytypeio.anytype.feature_properties
class EditSpacePropertiesViewModel {
//todo: implement later
}

View file

@ -0,0 +1,22 @@
package com.anytypeio.anytype.feature_properties
import androidx.lifecycle.ViewModel
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.primitives.SetObjectTypeRecommendedFields
import com.anytypeio.anytype.domain.relations.CreateRelation
import com.anytypeio.anytype.domain.resources.StringResourceProvider
import com.anytypeio.anytype.feature_properties.add.EditTypePropertiesVmParams
class EditTypePropertiesViewModel(
private val vmParams: EditTypePropertiesVmParams,
private val storeOfRelations: StoreOfRelations,
private val storeOfObjectTypes: StoreOfObjectTypes,
private val stringResourceProvider: StringResourceProvider,
private val createRelation: CreateRelation,
private val setObjectDetails: SetObjectDetails,
private val setObjectTypeRecommendedFields: SetObjectTypeRecommendedFields
) : ViewModel() {
}

View file

@ -0,0 +1,35 @@
package com.anytypeio.anytype.feature_properties
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.primitives.SetObjectTypeRecommendedFields
import com.anytypeio.anytype.domain.relations.CreateRelation
import com.anytypeio.anytype.domain.resources.StringResourceProvider
import com.anytypeio.anytype.feature_properties.add.EditTypePropertiesVmParams
import javax.inject.Inject
class EditTypePropertiesViewModelFactory @Inject constructor(
private val vmParams: EditTypePropertiesVmParams,
private val storeOfRelations: StoreOfRelations,
private val stringResourceProvider: StringResourceProvider,
private val createRelation: CreateRelation,
private val setObjectDetails: SetObjectDetails,
private val storeOfObjectTypes: StoreOfObjectTypes,
private val setObjectTypeRecommendedFields: SetObjectTypeRecommendedFields
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
EditTypePropertiesViewModel(
vmParams = vmParams,
storeOfRelations = storeOfRelations,
stringResourceProvider = stringResourceProvider,
createRelation = createRelation,
setObjectDetails = setObjectDetails,
storeOfObjectTypes = storeOfObjectTypes,
setObjectTypeRecommendedFields = setObjectTypeRecommendedFields
) as T
}

View file

@ -0,0 +1,12 @@
package com.anytypeio.anytype.feature_properties.add
sealed class UiEditTypePropertiesEvent {
data class OnSearchQueryChanged(val query: String) : UiEditTypePropertiesEvent()
data class OnCreate(val item: UiEditTypePropertiesItem.Create) : UiEditTypePropertiesEvent()
data class OnTypeClicked(val item: UiEditTypePropertiesItem.Format) : UiEditTypePropertiesEvent()
data class OnExistingClicked(val item: UiEditTypePropertiesItem.Default) : UiEditTypePropertiesEvent()
data object OnCreateNewButtonClicked : UiEditTypePropertiesEvent()
data object OnSaveButtonClicked : UiEditTypePropertiesEvent()
data object OnEditPropertyScreenDismissed : UiEditTypePropertiesEvent()
data class OnPropertyNameUpdate(val name: String) : UiEditTypePropertiesEvent()
}

View file

@ -0,0 +1,116 @@
package com.anytypeio.anytype.feature_properties.add
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.Relations
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.domain.resources.StringResourceProvider
data class UiEditTypePropertiesState(
val items: List<UiEditTypePropertiesItem>
) {
companion object {
val EMPTY = UiEditTypePropertiesState(emptyList())
val DEFAULT_NEW_PROPERTY_FORMAT = RelationFormat.STATUS
//This is a list of formats that are available for creating new properties
val PROPERTIES_FORMATS = listOf<RelationFormat>(
RelationFormat.LONG_TEXT,
RelationFormat.TAG,
RelationFormat.STATUS,
RelationFormat.NUMBER,
RelationFormat.DATE,
RelationFormat.FILE,
RelationFormat.OBJECT,
RelationFormat.CHECKBOX,
RelationFormat.URL,
RelationFormat.EMAIL,
RelationFormat.PHONE
)
}
}
sealed class UiEditTypePropertiesItem {
abstract val id: Id
sealed class Section : UiEditTypePropertiesItem() {
data class Types(
override val id: Id = "section_properties_types_id"
) : Section()
data class Existing(
override val id: Id = "section_properties_existing_id"
) : Section()
}
data class Format(
override val id: Id = "property_item_format_id_${format.ordinal}",
val format: RelationFormat,
val prettyName: String
) : UiEditTypePropertiesItem()
data class Create(
override val id: Id = ID,
val format: RelationFormat = UiEditTypePropertiesState.Companion.DEFAULT_NEW_PROPERTY_FORMAT,
val title: String
) : UiEditTypePropertiesItem() {
companion object {
private const val ID = "create_new_property_id"
}
}
data class Default(
override val id: Id,
val format: RelationFormat,
val propertyKey: Key,
val title: String,
) : UiEditTypePropertiesItem()
}
data class EditTypePropertiesVmParams(
val objectTypeId: Id,
val spaceId: SpaceId
)
sealed class UiEditTypePropertiesErrorState {
data object Hidden : UiEditTypePropertiesErrorState()
data class Show(val reason: Reason) : UiEditTypePropertiesErrorState()
sealed class Reason {
data class ErrorAddingProperty(val msg: String) : Reason()
data class ErrorCreatingProperty(val msg: String) : Reason()
data class ErrorUpdatingProperty(val msg: String) : Reason()
data class Other(val msg: String) : Reason()
}
}
//region MAPPING
fun ObjectWrapper.Relation.mapToStateItem(
stringResourceProvider: StringResourceProvider
): UiEditTypePropertiesItem.Default? {
val field = this
if (field.key == Relations.DESCRIPTION) return null
return UiEditTypePropertiesItem.Default(
id = field.id,
propertyKey = field.key,
title = field.getName(stringResourceProvider),
format = field.format
)
}
/**
* Extension function to safely get a name for the relation.
* If the name is blank, returns a default untitled title.
*/
fun ObjectWrapper.Relation.getName(stringResourceProvider: StringResourceProvider): String =
if (name.isNullOrBlank()) {
stringResourceProvider.getUntitledObjectTitle()
} else {
name!!
}
//endregion

View file

@ -0,0 +1,16 @@
package com.anytypeio.anytype.feature_properties.add.ui
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesEvent
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesState
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AddFieldScreen(
state: UiEditTypePropertiesState,
uiStateEditProperty: UiEditPropertyState,
event: (UiEditTypePropertiesEvent) -> Unit
) {
}

View file

@ -0,0 +1,44 @@
package com.anytypeio.anytype.feature_properties.edit
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.presentation.objects.ObjectIcon
sealed class UiEditPropertyState {
data object Hidden : UiEditPropertyState()
sealed class Visible : UiEditPropertyState() {
data class Edit(
val id: Id,
val key: Key,
val name: String,
val formatName: String,
val formatIcon: Int?,
val format: RelationFormat,
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList()
) : Visible()
data class New(
val name: String,
val formatName: String,
val formatIcon: Int?,
val format: RelationFormat,
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList()
) : Visible()
data class View(
val id: Id,
val key: Key,
val name: String,
val formatName: String,
val formatIcon: Int?,
val format: RelationFormat,
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList()
) : Visible()
}
}
data class UiPropertyLimitTypeItem(
val id: Id, val key: Key, val title: String, val icon: ObjectIcon
)

View file

@ -0,0 +1,20 @@
package com.anytypeio.anytype.feature_properties.edit.ui
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PropertyScreen(
modifier: Modifier,
uiState: UiEditPropertyState.Visible,
onSaveButtonClicked: () -> Unit = {},
onFormatClick: () -> Unit = {},
onLimitTypesClick: () -> Unit = {},
onCreateNewButtonClicked: () -> Unit = {},
onDismissRequest: () -> Unit,
onPropertyNameUpdate: (String) -> Unit
) {
}