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:
parent
b566ba30e0
commit
3932c2fe87
42 changed files with 750 additions and 1142 deletions
58
feature-properties/build.gradle
Normal file
58
feature-properties/build.gradle
Normal 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
|
||||
}
|
2
feature-properties/src/main/AndroidManifest.xml
Normal file
2
feature-properties/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest/>
|
|
@ -0,0 +1,5 @@
|
|||
package com.anytypeio.anytype.feature_properties
|
||||
|
||||
class EditSpacePropertiesViewModel {
|
||||
//todo: implement later
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
) {
|
||||
}
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
) {
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue