mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3435 Primitives | Ui fixes (#2152)
This commit is contained in:
parent
a65f78c8d4
commit
58f64ffd61
19 changed files with 434 additions and 118 deletions
|
@ -28,7 +28,12 @@ import com.anytypeio.anytype.feature_properties.EditTypePropertiesViewModel
|
|||
import com.anytypeio.anytype.feature_properties.EditTypePropertiesViewModel.EditTypePropertiesCommand
|
||||
import com.anytypeio.anytype.feature_properties.add.EditTypePropertiesVmParams
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesErrorState
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesEvent
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesEvent.OnPropertyFormatSelected
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesEvent.OnPropertyFormatsListDismiss
|
||||
import com.anytypeio.anytype.feature_properties.add.ui.AddFieldScreen
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiPropertyFormatsListState
|
||||
import com.anytypeio.anytype.feature_properties.edit.ui.PropertyFormatsListScreen
|
||||
import javax.inject.Inject
|
||||
|
||||
class EditTypePropertiesFragment : BaseBottomSheetComposeFragment() {
|
||||
|
@ -51,6 +56,7 @@ class EditTypePropertiesFragment : BaseBottomSheetComposeFragment() {
|
|||
uiStateEditProperty = vm.uiPropertyEditState.collectAsStateWithLifecycle().value,
|
||||
event = vm::onEvent
|
||||
)
|
||||
PropertyFormatsScreen()
|
||||
ErrorScreen()
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +106,18 @@ class EditTypePropertiesFragment : BaseBottomSheetComposeFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PropertyFormatsScreen() {
|
||||
val uiState = vm.uiPropertyFormatsListState.collectAsStateWithLifecycle().value
|
||||
if (uiState is UiPropertyFormatsListState.Visible) {
|
||||
PropertyFormatsListScreen(
|
||||
uiState = uiState,
|
||||
onDismissRequest = { vm.onEvent(OnPropertyFormatsListDismiss) },
|
||||
onFormatClick = { vm.onEvent(OnPropertyFormatSelected(it)) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupBottomSheetBehavior(DEFAULT_PADDING_TOP)
|
||||
|
|
|
@ -172,6 +172,7 @@ class ObjectTypeFragment : BaseComposeFragment() {
|
|||
uiIconState = vm.uiIconState.collectAsStateWithLifecycle().value,
|
||||
uiEditPropertyState = vm.uiEditPropertyScreen.collectAsStateWithLifecycle().value,
|
||||
uiFieldLocalInfoState = vm.uiFieldLocalInfoState.collectAsStateWithLifecycle().value,
|
||||
withDragger = false,
|
||||
fieldEvent = vm::onFieldEvent
|
||||
)
|
||||
}
|
||||
|
|
|
@ -168,6 +168,9 @@ open class ObjectSetFragment :
|
|||
private val topBackButton: View
|
||||
get() = binding.topToolbar.root.findViewById(R.id.topBackButton)
|
||||
|
||||
private val topToolbar: ViewGroup
|
||||
get() = binding.topToolbar.root
|
||||
|
||||
private val topToolbarTitle: TextView
|
||||
get() = binding.topToolbar.root.findViewById(R.id.tvTopToolbarTitle)
|
||||
|
||||
|
@ -708,7 +711,9 @@ open class ObjectSetFragment :
|
|||
is DataViewViewState.TypeSet.Default -> {
|
||||
topToolbarThreeDotsButton.gone()
|
||||
topToolbarStatusContainer.gone()
|
||||
topToolbarTitle.gone()
|
||||
topBackButton.gone()
|
||||
topToolbar.gone()
|
||||
initView.gone()
|
||||
header.gone()
|
||||
dataViewHeader.visible()
|
||||
|
@ -727,6 +732,8 @@ open class ObjectSetFragment :
|
|||
is DataViewViewState.TypeSet.NoItems -> {
|
||||
topToolbarThreeDotsButton.gone()
|
||||
topToolbarStatusContainer.gone()
|
||||
topToolbarTitle.gone()
|
||||
topToolbar.gone()
|
||||
topBackButton.gone()
|
||||
initView.gone()
|
||||
header.gone()
|
||||
|
@ -750,7 +757,9 @@ open class ObjectSetFragment :
|
|||
is DataViewViewState.TypeSet.Error -> {
|
||||
topToolbarThreeDotsButton.gone()
|
||||
topToolbarStatusContainer.gone()
|
||||
topToolbarTitle.gone()
|
||||
topBackButton.gone()
|
||||
topToolbar.gone()
|
||||
initView.gone()
|
||||
header.gone()
|
||||
dataViewHeader.visible()
|
||||
|
|
|
@ -26,4 +26,9 @@ sealed class FieldEvent {
|
|||
data class OnMove(val fromKey: String, val toKey: String) : DragEvent()
|
||||
data object OnDragEnd : DragEvent()
|
||||
}
|
||||
|
||||
sealed class EditProperty : FieldEvent() {
|
||||
data class OnPropertyNameUpdate(val name: String) : EditProperty()
|
||||
data object OnSaveButtonClicked : EditProperty()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ sealed class UiFieldsListItem {
|
|||
abstract val fieldTitle: String
|
||||
abstract val format: RelationFormat
|
||||
abstract val limitObjectTypes: List<UiPropertyLimitTypeItem>
|
||||
abstract val canDelete: Boolean
|
||||
abstract val isPossibleToUnlinkFromType: Boolean
|
||||
abstract val isEditableField: Boolean
|
||||
|
||||
data class Draggable(
|
||||
|
@ -53,7 +53,7 @@ sealed class UiFieldsListItem {
|
|||
override val fieldTitle: String,
|
||||
override val format: RelationFormat,
|
||||
override val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList(),
|
||||
override val canDelete: Boolean,
|
||||
override val isPossibleToUnlinkFromType: Boolean,
|
||||
override val isEditableField: Boolean
|
||||
) : Item()
|
||||
|
||||
|
@ -63,7 +63,7 @@ sealed class UiFieldsListItem {
|
|||
override val fieldTitle: String,
|
||||
override val format: RelationFormat,
|
||||
override val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList(),
|
||||
override val canDelete: Boolean = false,
|
||||
override val isPossibleToUnlinkFromType: Boolean = false,
|
||||
override val isEditableField: Boolean
|
||||
) : Item()
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.os.Build
|
|||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
@ -47,15 +48,14 @@ import com.anytypeio.anytype.core_models.RelationFormat
|
|||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.common.ReorderHapticFeedback
|
||||
import com.anytypeio.anytype.core_ui.common.ReorderHapticFeedbackType
|
||||
import com.anytypeio.anytype.core_ui.common.bottomBorder
|
||||
import com.anytypeio.anytype.core_ui.common.rememberReorderHapticFeedback
|
||||
import com.anytypeio.anytype.core_ui.extensions.simpleIcon
|
||||
import com.anytypeio.anytype.core_ui.foundation.Dragger
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleThrottledClickable
|
||||
import com.anytypeio.anytype.core_ui.views.BodyCalloutMedium
|
||||
import com.anytypeio.anytype.core_ui.views.BodyCalloutRegular
|
||||
import com.anytypeio.anytype.core_ui.views.BodyRegular
|
||||
import com.anytypeio.anytype.core_ui.views.Caption1Medium
|
||||
import com.anytypeio.anytype.core_ui.views.Relations1
|
||||
import com.anytypeio.anytype.core_ui.views.Title1
|
||||
import com.anytypeio.anytype.core_ui.widgets.ListWidgetObjectIcon
|
||||
import com.anytypeio.anytype.core_utils.insets.EDGE_TO_EDGE_MIN_SDK
|
||||
|
@ -85,6 +85,7 @@ fun FieldsMainScreen(
|
|||
uiIconState: UiIconState,
|
||||
uiFieldLocalInfoState: UiLocalsFieldsInfoState,
|
||||
uiEditPropertyState: UiEditPropertyState,
|
||||
withDragger: Boolean = true,
|
||||
fieldEvent: (FieldEvent) -> Unit
|
||||
) {
|
||||
|
||||
|
@ -125,7 +126,8 @@ fun FieldsMainScreen(
|
|||
TopBar(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
uiTitleState = uiTitleState,
|
||||
uiIconState = uiIconState
|
||||
uiIconState = uiIconState,
|
||||
withDragger = withDragger
|
||||
)
|
||||
},
|
||||
content = { paddingValues ->
|
||||
|
@ -141,7 +143,8 @@ fun FieldsMainScreen(
|
|||
}
|
||||
LazyColumn(
|
||||
modifier = contentModifier,
|
||||
state = lazyListState
|
||||
state = lazyListState,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
items(
|
||||
count = uiFieldsListState.items.size,
|
||||
|
@ -224,10 +227,10 @@ fun FieldsMainScreen(
|
|||
onDismissRequest = { fieldEvent(OnEditPropertyScreenDismiss) },
|
||||
onFormatClick = {},
|
||||
onLimitTypesClick = {},
|
||||
onSaveButtonClicked = {},
|
||||
onSaveButtonClicked = { fieldEvent(EditProperty.OnSaveButtonClicked) },
|
||||
onCreateNewButtonClicked = {},
|
||||
onPropertyNameUpdate = { },
|
||||
onDeleteButtonClicked = { id -> fieldEvent(OnDeleteFromTypeClick(id)) },
|
||||
onPropertyNameUpdate = { fieldEvent(EditProperty.OnPropertyNameUpdate(it)) },
|
||||
onMenuUnlinkClick = { fieldEvent(OnDeleteFromTypeClick(it)) }
|
||||
|
||||
)
|
||||
}
|
||||
|
@ -259,15 +262,20 @@ private fun getContentType(item: UiFieldsListItem): String {
|
|||
/** A common modifier for list items. **/
|
||||
@Composable
|
||||
fun LazyItemScope.commonItemModifier() = Modifier
|
||||
.height(52.dp)
|
||||
.height(48.dp)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 20.dp)
|
||||
.bottomBorder()
|
||||
.padding(horizontal = 16.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = colorResource(id = R.color.shape_primary),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
.animateItem()
|
||||
|
||||
@Composable
|
||||
private fun TopBar(
|
||||
modifier: Modifier,
|
||||
withDragger: Boolean = true,
|
||||
uiTitleState: UiTitleState,
|
||||
uiIconState: UiIconState,
|
||||
) {
|
||||
|
@ -283,11 +291,13 @@ private fun TopBar(
|
|||
shape = RoundedCornerShape(16.dp, 16.dp, 0.dp, 0.dp)
|
||||
)
|
||||
) {
|
||||
Dragger(
|
||||
modifier = Modifier
|
||||
.padding(vertical = 6.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
if (withDragger) {
|
||||
Dragger(
|
||||
modifier = Modifier
|
||||
.padding(vertical = 6.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
@ -388,7 +398,7 @@ private fun LazyItemScope.SectionItem(
|
|||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 7.dp, start = 20.dp)
|
||||
.padding(bottom = 4.dp, start = 20.dp)
|
||||
.align(Alignment.BottomStart),
|
||||
text = title,
|
||||
style = BodyCalloutMedium,
|
||||
|
@ -406,7 +416,7 @@ private fun LazyItemScope.SectionItem(
|
|||
) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 6.dp, end = 20.dp)
|
||||
.padding(bottom = 2.dp, end = 20.dp)
|
||||
.wrapContentSize()
|
||||
.align(Alignment.BottomEnd),
|
||||
painter = painterResource(R.drawable.ic_default_plus),
|
||||
|
@ -459,7 +469,7 @@ private fun FieldItemLocal(
|
|||
if (formatIcon != null) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.padding(end = 10.dp)
|
||||
.padding(start = 14.dp, end = 8.dp)
|
||||
.size(24.dp),
|
||||
painter = painterResource(id = formatIcon),
|
||||
contentDescription = "Relation format icon",
|
||||
|
@ -472,7 +482,7 @@ private fun FieldItemLocal(
|
|||
.weight(1.0f)
|
||||
.padding(end = 16.dp),
|
||||
text = item.fieldTitle,
|
||||
style = BodyRegular,
|
||||
style = Relations1,
|
||||
color = colorResource(id = R.color.text_primary),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
|
@ -480,6 +490,7 @@ private fun FieldItemLocal(
|
|||
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.padding(end = 14.dp)
|
||||
.size(24.dp)
|
||||
.noRippleThrottledClickable {
|
||||
isMenuExpanded.value = true
|
||||
|
@ -524,7 +535,7 @@ private fun LazyItemScope.FieldItemDraggable(
|
|||
if (formatIcon != null) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.padding(end = 10.dp)
|
||||
.padding(start = 14.dp, end = 8.dp)
|
||||
.size(24.dp),
|
||||
painter = painterResource(id = formatIcon),
|
||||
contentDescription = "Relation format icon",
|
||||
|
@ -541,7 +552,7 @@ private fun LazyItemScope.FieldItemDraggable(
|
|||
},
|
||||
onLongClick = {
|
||||
// show your menu, only if NOT dragging
|
||||
if (item.canDelete) {
|
||||
if (item.isPossibleToUnlinkFromType) {
|
||||
isMenuExpanded.value = true
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +564,7 @@ private fun LazyItemScope.FieldItemDraggable(
|
|||
.fillMaxWidth()
|
||||
.padding(end = 16.dp),
|
||||
text = item.fieldTitle,
|
||||
style = BodyRegular,
|
||||
style = Relations1,
|
||||
color = colorResource(id = R.color.text_primary),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
|
@ -562,6 +573,7 @@ private fun LazyItemScope.FieldItemDraggable(
|
|||
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.padding(end = 14.dp)
|
||||
.size(24.dp)
|
||||
.draggableHandle(
|
||||
onDragStarted = {
|
||||
|
@ -668,7 +680,7 @@ fun PreviewTypeFieldsMainScreen() {
|
|||
fieldKey = "key1",
|
||||
fieldTitle = "Status",
|
||||
format = RelationFormat.STATUS,
|
||||
canDelete = true,
|
||||
isPossibleToUnlinkFromType = true,
|
||||
isEditableField = true
|
||||
),
|
||||
UiFieldsListItem.Item.Draggable(
|
||||
|
@ -676,7 +688,7 @@ fun PreviewTypeFieldsMainScreen() {
|
|||
fieldKey = "key2",
|
||||
fieldTitle = "Very long field title, just to test how it looks",
|
||||
format = RelationFormat.LONG_TEXT,
|
||||
canDelete = true,
|
||||
isPossibleToUnlinkFromType = true,
|
||||
isEditableField = true
|
||||
),
|
||||
UiFieldsListItem.Section.SideBar(
|
||||
|
@ -688,7 +700,7 @@ fun PreviewTypeFieldsMainScreen() {
|
|||
fieldTitle = "Links",
|
||||
format = RelationFormat.URL,
|
||||
isEditableField = true,
|
||||
canDelete = true
|
||||
isPossibleToUnlinkFromType = true
|
||||
),
|
||||
UiFieldsListItem.Item.Draggable(
|
||||
id = "id4",
|
||||
|
@ -696,7 +708,7 @@ fun PreviewTypeFieldsMainScreen() {
|
|||
fieldTitle = "Very long field title, just to test how it looks",
|
||||
format = RelationFormat.DATE,
|
||||
isEditableField = true,
|
||||
canDelete = true
|
||||
isPossibleToUnlinkFromType = true
|
||||
),
|
||||
UiFieldsListItem.Section.Hidden(),
|
||||
UiFieldsListItem.Item.Draggable(
|
||||
|
@ -705,7 +717,7 @@ fun PreviewTypeFieldsMainScreen() {
|
|||
fieldTitle = "Hidden field",
|
||||
format = RelationFormat.LONG_TEXT,
|
||||
isEditableField = true,
|
||||
canDelete = true
|
||||
isPossibleToUnlinkFromType = true
|
||||
),
|
||||
UiFieldsListItem.Section.Local(),
|
||||
UiFieldsListItem.Item.Local(
|
||||
|
|
|
@ -210,7 +210,7 @@ private suspend fun mapToUiFieldsDraggableListItem(
|
|||
format = field.format,
|
||||
limitObjectTypes = limitObjectTypes,
|
||||
isEditableField = fieldParser.isFieldEditable(field),
|
||||
canDelete = fieldParser.isFieldCanBeDeletedFromType(field)
|
||||
isPossibleToUnlinkFromType = fieldParser.isFieldCanBeDeletedFromType(field)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import com.anytypeio.anytype.feature_object_type.ui.UiTitleState
|
|||
import com.anytypeio.anytype.feature_object_type.ui.buildUiFieldsList
|
||||
import com.anytypeio.anytype.feature_object_type.ui.toTemplateView
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState.Visible.View
|
||||
import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
|
||||
import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsScreenObjectType
|
||||
|
@ -113,7 +114,8 @@ class ObjectTypeViewModel(
|
|||
//layout, fields and templates buttons
|
||||
val uiFieldsButtonState = MutableStateFlow<UiFieldsButtonState>(UiFieldsButtonState.Hidden)
|
||||
val uiLayoutButtonState = MutableStateFlow<UiLayoutButtonState>(UiLayoutButtonState.Hidden)
|
||||
val uiTemplatesButtonState = MutableStateFlow<UiTemplatesButtonState>(UiTemplatesButtonState.Hidden)
|
||||
val uiTemplatesButtonState =
|
||||
MutableStateFlow<UiTemplatesButtonState>(UiTemplatesButtonState.Hidden)
|
||||
|
||||
//type layouts
|
||||
val uiTypeLayoutsState = MutableStateFlow<UiLayoutTypeState>(Hidden)
|
||||
|
@ -376,7 +378,8 @@ class ObjectTypeViewModel(
|
|||
formatName = stringResourceProvider.getPropertiesFormatPrettyString(item.format),
|
||||
formatIcon = item.format.simpleIcon(),
|
||||
format = item.format,
|
||||
limitObjectTypes = item.limitObjectTypes
|
||||
limitObjectTypes = item.limitObjectTypes,
|
||||
isPossibleToUnlinkFromType = item.isPossibleToUnlinkFromType
|
||||
)
|
||||
} else {
|
||||
uiEditPropertyScreen.value = UiEditPropertyState.Visible.View(
|
||||
|
@ -386,7 +389,8 @@ class ObjectTypeViewModel(
|
|||
formatName = stringResourceProvider.getPropertiesFormatPrettyString(item.format),
|
||||
formatIcon = item.format.simpleIcon(),
|
||||
format = item.format,
|
||||
limitObjectTypes = item.limitObjectTypes
|
||||
limitObjectTypes = item.limitObjectTypes,
|
||||
isPossibleToUnlinkFromType = item.isPossibleToUnlinkFromType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -696,6 +700,7 @@ class ObjectTypeViewModel(
|
|||
currentList.add(toIndex, item)
|
||||
uiFieldsListState.value = UiFieldsListState(items = currentList)
|
||||
}
|
||||
is FieldEvent.EditProperty -> proceedWithEditPropertyEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -749,7 +754,44 @@ class ObjectTypeViewModel(
|
|||
val newRecommendedFields = currentRecommendedFields + event.item.id
|
||||
proceedWithSetRecommendedFields(newRecommendedFields)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithEditPropertyEvent(event: FieldEvent.EditProperty) {
|
||||
when (event) {
|
||||
is FieldEvent.EditProperty.OnPropertyNameUpdate -> {
|
||||
val state = uiEditPropertyScreen.value as? UiEditPropertyState.Visible ?: return
|
||||
uiEditPropertyScreen.value = when (state) {
|
||||
is UiEditPropertyState.Visible.Edit -> state.copy(name = event.name)
|
||||
is UiEditPropertyState.Visible.New -> state.copy(name = event.name)
|
||||
is View -> state
|
||||
}
|
||||
}
|
||||
|
||||
FieldEvent.EditProperty.OnSaveButtonClicked -> {
|
||||
val state =
|
||||
uiEditPropertyScreen.value as? UiEditPropertyState.Visible.Edit ?: return
|
||||
viewModelScope.launch {
|
||||
val params = SetObjectDetails.Params(
|
||||
ctx = state.id,
|
||||
details = mapOf(
|
||||
Relations.NAME to state.name
|
||||
)
|
||||
)
|
||||
setObjectDetails.async(params).fold(
|
||||
onSuccess = {
|
||||
Timber.d("Relation updated: $it")
|
||||
uiEditPropertyScreen.value = UiEditPropertyState.Hidden
|
||||
},
|
||||
onFailure = { error ->
|
||||
Timber.e(error, "Failed to update relation")
|
||||
errorState.value = UiErrorState.Show(
|
||||
reason = UiErrorState.Reason.Other(error.message ?: "")
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
|
|
|
@ -18,9 +18,13 @@ import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesEvent
|
|||
import com.anytypeio.anytype.feature_properties.add.EditTypePropertiesVmParams
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesErrorState
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesItem
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesItem.*
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesState
|
||||
import com.anytypeio.anytype.feature_properties.add.mapToStateItem
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState.Visible.*
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiPropertyFormatsListState
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiPropertyFormatsListState.*
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -57,6 +61,9 @@ class EditTypePropertiesViewModel(
|
|||
val uiPropertyEditState =
|
||||
MutableStateFlow<UiEditPropertyState>(UiEditPropertyState.Hidden)
|
||||
|
||||
val uiPropertyFormatsListState =
|
||||
MutableStateFlow<UiPropertyFormatsListState>(UiPropertyFormatsListState.Hidden)
|
||||
|
||||
private val _commands = MutableSharedFlow<EditTypePropertiesCommand>()
|
||||
val commands = _commands.asSharedFlow()
|
||||
|
||||
|
@ -184,10 +191,11 @@ class EditTypePropertiesViewModel(
|
|||
|
||||
//region Ui Events
|
||||
fun onEvent(event: UiEditTypePropertiesEvent) {
|
||||
Timber.d("UiEditTypePropertiesEvent: $event")
|
||||
when (event) {
|
||||
is UiEditTypePropertiesEvent.OnCreate -> {
|
||||
val format = event.item.format
|
||||
uiPropertyEditState.value = UiEditPropertyState.Visible.New(
|
||||
uiPropertyEditState.value = New(
|
||||
name = event.item.title,
|
||||
formatName = stringResourceProvider.getPropertiesFormatPrettyString(format),
|
||||
formatIcon = format.simpleIcon(),
|
||||
|
@ -212,7 +220,7 @@ class EditTypePropertiesViewModel(
|
|||
|
||||
is UiEditTypePropertiesEvent.OnTypeClicked -> {
|
||||
val format = event.item.format
|
||||
uiPropertyEditState.value = UiEditPropertyState.Visible.New(
|
||||
uiPropertyEditState.value = New(
|
||||
name = "",
|
||||
formatName = stringResourceProvider.getPropertiesFormatPrettyString(format),
|
||||
formatIcon = format.simpleIcon(),
|
||||
|
@ -235,9 +243,43 @@ class EditTypePropertiesViewModel(
|
|||
is UiEditTypePropertiesEvent.OnPropertyNameUpdate -> {
|
||||
val state = uiPropertyEditState.value as? UiEditPropertyState.Visible ?: return
|
||||
uiPropertyEditState.value = when (state) {
|
||||
is UiEditPropertyState.Visible.Edit -> state.copy(name = event.name)
|
||||
is UiEditPropertyState.Visible.New -> state.copy(name = event.name)
|
||||
is UiEditPropertyState.Visible.View -> state
|
||||
is Edit -> state.copy(name = event.name)
|
||||
is New -> state.copy(name = event.name)
|
||||
is View -> state
|
||||
}
|
||||
}
|
||||
|
||||
UiEditTypePropertiesEvent.OnPropertyFormatClick -> {
|
||||
uiPropertyFormatsListState.value = Visible(
|
||||
items = UiEditTypePropertiesState.Companion.PROPERTIES_FORMATS.map { format ->
|
||||
Format(
|
||||
format = format,
|
||||
prettyName = stringResourceProvider.getPropertiesFormatPrettyString(format)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
UiEditTypePropertiesEvent.OnPropertyFormatsListDismiss -> {
|
||||
uiPropertyFormatsListState.value = Hidden
|
||||
}
|
||||
|
||||
is UiEditTypePropertiesEvent.OnPropertyFormatSelected -> {
|
||||
uiPropertyFormatsListState.value = Hidden
|
||||
val state = uiPropertyEditState.value as? UiEditPropertyState.Visible ?: return
|
||||
uiPropertyEditState.value = when (state) {
|
||||
is New -> {
|
||||
val newFormat = event.format.format
|
||||
state.copy(
|
||||
formatName = stringResourceProvider.getPropertiesFormatPrettyString(
|
||||
newFormat
|
||||
),
|
||||
formatIcon = newFormat.simpleIcon(),
|
||||
format = newFormat,
|
||||
)
|
||||
}
|
||||
|
||||
else -> state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,21 +288,20 @@ class EditTypePropertiesViewModel(
|
|||
|
||||
//region Use Cases
|
||||
private fun proceedWithUpdatingRelation() {
|
||||
val state = uiPropertyEditState.value as? UiEditPropertyState.Visible.Edit ?: return
|
||||
val state = uiPropertyEditState.value as? Edit ?: return
|
||||
viewModelScope.launch {
|
||||
val params = SetObjectDetails.Params(
|
||||
ctx = state.id,
|
||||
details = mapOf(
|
||||
Relations.NAME to state.name,
|
||||
Relations.RELATION_FORMAT to state.format
|
||||
Relations.NAME to state.name
|
||||
)
|
||||
)
|
||||
setObjectDetails.async(params).fold(
|
||||
onSuccess = {
|
||||
Timber.d("Relation updated: $it")
|
||||
onSuccess = { payload ->
|
||||
Timber.d("Property updated :[$payload]")
|
||||
},
|
||||
onFailure = { error ->
|
||||
Timber.e(error, "Failed to update relation")
|
||||
Timber.e(error, "Failed to update property")
|
||||
_errorState.value = UiEditTypePropertiesErrorState.Show(
|
||||
UiEditTypePropertiesErrorState.Reason.ErrorUpdatingProperty(error.message ?: "")
|
||||
)
|
||||
|
@ -285,19 +326,18 @@ class EditTypePropertiesViewModel(
|
|||
prefilled = emptyMap()
|
||||
)
|
||||
createRelation(params).process(
|
||||
success = { relation ->
|
||||
Timber.d("Relation created: $relation")
|
||||
success = { property ->
|
||||
Timber.d("Property created: $property")
|
||||
val objType = storeOfObjectTypes.get(vmParams.objectTypeId)
|
||||
if (objType != null) {
|
||||
proceedWithSetRecommendedProperties(
|
||||
properties = objType.recommendedRelations + listOf(relation.id)
|
||||
properties = objType.recommendedRelations + listOf(property.id)
|
||||
)
|
||||
}
|
||||
uiPropertyEditState.value = UiEditPropertyState.Hidden
|
||||
_commands.emit(EditTypePropertiesCommand.Exit)
|
||||
},
|
||||
failure = { error ->
|
||||
Timber.e(error, "Failed to create relation")
|
||||
Timber.e(error, "Failed to create property")
|
||||
_errorState.value = UiEditTypePropertiesErrorState.Show(
|
||||
UiEditTypePropertiesErrorState.Reason.ErrorCreatingProperty(error.message ?: "")
|
||||
)
|
||||
|
|
|
@ -9,4 +9,8 @@ sealed class UiEditTypePropertiesEvent {
|
|||
data object OnSaveButtonClicked : UiEditTypePropertiesEvent()
|
||||
data object OnEditPropertyScreenDismissed : UiEditTypePropertiesEvent()
|
||||
data class OnPropertyNameUpdate(val name: String) : UiEditTypePropertiesEvent()
|
||||
|
||||
data object OnPropertyFormatClick : UiEditTypePropertiesEvent()
|
||||
data object OnPropertyFormatsListDismiss : UiEditTypePropertiesEvent()
|
||||
data class OnPropertyFormatSelected(val format: UiEditTypePropertiesItem.Format) : UiEditTypePropertiesEvent()
|
||||
}
|
|
@ -14,7 +14,7 @@ data class UiEditTypePropertiesState(
|
|||
companion object {
|
||||
val EMPTY = UiEditTypePropertiesState(emptyList())
|
||||
|
||||
val DEFAULT_NEW_PROPERTY_FORMAT = RelationFormat.STATUS
|
||||
val DEFAULT_NEW_PROPERTY_FORMAT = RelationFormat.LONG_TEXT
|
||||
|
||||
//This is a list of formats that are available for creating new properties
|
||||
val PROPERTIES_FORMATS = listOf<RelationFormat>(
|
||||
|
|
|
@ -177,6 +177,12 @@ fun AddFieldScreen(
|
|||
},
|
||||
onPropertyNameUpdate = { name ->
|
||||
event(UiEditTypePropertiesEvent.OnPropertyNameUpdate(name))
|
||||
},
|
||||
onFormatClick = {
|
||||
event(UiEditTypePropertiesEvent.OnPropertyFormatClick)
|
||||
},
|
||||
onSaveButtonClicked = {
|
||||
event(UiEditTypePropertiesEvent.OnSaveButtonClicked)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -201,7 +207,7 @@ private fun Section(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun PropertyTypeItem(
|
||||
fun PropertyTypeItem(
|
||||
modifier: Modifier,
|
||||
item: UiEditTypePropertiesItem.Format
|
||||
) {
|
||||
|
|
|
@ -3,6 +3,7 @@ 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.feature_properties.add.UiEditTypePropertiesItem
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
sealed class UiEditPropertyState {
|
||||
|
@ -16,7 +17,8 @@ sealed class UiEditPropertyState {
|
|||
val formatName: String,
|
||||
val formatIcon: Int?,
|
||||
val format: RelationFormat,
|
||||
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList()
|
||||
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList(),
|
||||
val isPossibleToUnlinkFromType: Boolean
|
||||
) : Visible()
|
||||
|
||||
data class New(
|
||||
|
@ -34,11 +36,20 @@ sealed class UiEditPropertyState {
|
|||
val formatName: String,
|
||||
val formatIcon: Int?,
|
||||
val format: RelationFormat,
|
||||
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList()
|
||||
val limitObjectTypes: List<UiPropertyLimitTypeItem> = emptyList(),
|
||||
val isPossibleToUnlinkFromType: Boolean
|
||||
) : Visible()
|
||||
}
|
||||
}
|
||||
|
||||
data class UiPropertyLimitTypeItem(
|
||||
val id: Id, val key: Key, val title: String, val icon: ObjectIcon
|
||||
)
|
||||
)
|
||||
|
||||
sealed class UiPropertyFormatsListState {
|
||||
data class Visible(
|
||||
val items: List<UiEditTypePropertiesItem.Format>
|
||||
) : UiPropertyFormatsListState()
|
||||
|
||||
data object Hidden : UiPropertyFormatsListState()
|
||||
}
|
|
@ -5,11 +5,12 @@ import androidx.compose.foundation.layout.Box
|
|||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
|
@ -29,6 +30,7 @@ import androidx.compose.ui.res.colorResource
|
|||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.RelationFormat
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
|
@ -47,15 +49,16 @@ fun PropertyEditScreen(
|
|||
onFormatClick: () -> Unit,
|
||||
onLimitTypesClick: () -> Unit,
|
||||
onPropertyNameUpdate: (String) -> Unit,
|
||||
onDeleteButtonClicked: () -> Unit
|
||||
onMenuUnlinkClick: (Id) -> Unit
|
||||
) {
|
||||
|
||||
var innerValue by remember(uiState.name) { mutableStateOf(uiState.name) }
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
||||
var isNameChanged by remember { mutableStateOf(false) }
|
||||
|
||||
Column(modifier = modifier) {
|
||||
Column(modifier = modifier.imePadding()) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -77,50 +80,52 @@ fun PropertyEditScreen(
|
|||
emptyName = stringResource(R.string.untitled),
|
||||
onValueChange = {
|
||||
innerValue = it
|
||||
isNameChanged = true
|
||||
onPropertyNameUpdate(it)
|
||||
}
|
||||
)
|
||||
Spacer(modifier = Modifier.size(4.dp))
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(end = 21.dp)
|
||||
.size(40.dp)
|
||||
.noRippleThrottledClickable {
|
||||
isMenuExpanded = true
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
if (uiState.isPossibleToUnlinkFromType) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
//.padding(end = 20.dp)
|
||||
.wrapContentSize()
|
||||
.align(Alignment.Center),
|
||||
painter = painterResource(id = R.drawable.ic_widget_three_dots),
|
||||
contentDescription = "Property menu icon",
|
||||
contentScale = ContentScale.None,
|
||||
)
|
||||
DropdownMenu(
|
||||
modifier = Modifier.width(244.dp),
|
||||
expanded = isMenuExpanded,
|
||||
onDismissRequest = { isMenuExpanded = false },
|
||||
shape = RoundedCornerShape(size = 10.dp),
|
||||
containerColor = colorResource(id = R.color.background_primary),
|
||||
shadowElevation = 5.dp,
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
modifier = Modifier.height(44.dp),
|
||||
onClick = {
|
||||
onDeleteButtonClicked()
|
||||
isMenuExpanded = false
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = stringResource(R.string.delete),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.palette_system_red),
|
||||
modifier = Modifier
|
||||
)
|
||||
.padding(end = 21.dp)
|
||||
.size(40.dp)
|
||||
.noRippleThrottledClickable {
|
||||
isMenuExpanded = true
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.align(Alignment.Center),
|
||||
painter = painterResource(id = R.drawable.ic_widget_three_dots),
|
||||
contentDescription = "Property menu icon",
|
||||
contentScale = ContentScale.None,
|
||||
)
|
||||
DropdownMenu(
|
||||
modifier = Modifier.defaultMinSize(minWidth = 244.dp),
|
||||
expanded = isMenuExpanded,
|
||||
onDismissRequest = { isMenuExpanded = false },
|
||||
shape = RoundedCornerShape(size = 10.dp),
|
||||
containerColor = colorResource(id = R.color.background_primary),
|
||||
shadowElevation = 5.dp,
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
modifier = Modifier.height(44.dp),
|
||||
onClick = {
|
||||
onMenuUnlinkClick(uiState.id)
|
||||
isMenuExpanded = false
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = stringResource(R.string.property_edit_menu_unlink),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.palette_system_red),
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +139,7 @@ fun PropertyEditScreen(
|
|||
.padding(horizontal = 20.dp)
|
||||
.noRippleThrottledClickable { onFormatClick() },
|
||||
formatName = uiState.formatName,
|
||||
isEditable = true,
|
||||
isEditable = false,
|
||||
)
|
||||
Divider()
|
||||
|
||||
|
@ -156,8 +161,11 @@ fun PropertyEditScreen(
|
|||
onClick = {
|
||||
onSaveButtonClicked()
|
||||
},
|
||||
size = ButtonSize.Large
|
||||
size = ButtonSize.Large,
|
||||
enabled = innerValue.isNotBlank() && isNameChanged
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,12 +181,13 @@ fun EditPropertyPreview() {
|
|||
formatName = "Text",
|
||||
formatIcon = R.drawable.ic_relation_format_date_small,
|
||||
limitObjectTypes = emptyList(),
|
||||
format = RelationFormat.OBJECT
|
||||
format = RelationFormat.OBJECT,
|
||||
isPossibleToUnlinkFromType = true
|
||||
),
|
||||
onSaveButtonClicked = {},
|
||||
onFormatClick = {},
|
||||
onLimitTypesClick = {},
|
||||
onPropertyNameUpdate = {},
|
||||
onDeleteButtonClicked = {},
|
||||
onMenuUnlinkClick = {}
|
||||
)
|
||||
}
|
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -41,7 +42,7 @@ fun PropertyNewScreen(
|
|||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
|
||||
Column(modifier = modifier) {
|
||||
Column(modifier = modifier.imePadding()) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -100,8 +101,11 @@ fun PropertyNewScreen(
|
|||
onClick = {
|
||||
onCreateNewButtonClicked()
|
||||
},
|
||||
size = ButtonSize.Large
|
||||
size = ButtonSize.Large,
|
||||
enabled = innerValue.isNotBlank()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package com.anytypeio.anytype.feature_properties.edit.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.anytypeio.anytype.core_ui.foundation.Divider
|
||||
import com.anytypeio.anytype.core_ui.views.Title1
|
||||
import com.anytypeio.anytype.core_ui.widgets.dv.DragHandle
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiPropertyFormatsListState
|
||||
import com.anytypeio.anytype.feature_properties.R
|
||||
import com.anytypeio.anytype.feature_properties.add.UiEditTypePropertiesItem
|
||||
import com.anytypeio.anytype.feature_properties.add.ui.PropertyTypeItem
|
||||
import com.anytypeio.anytype.feature_properties.add.ui.commonItemModifier
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun PropertyFormatsListScreen(
|
||||
uiState: UiPropertyFormatsListState.Visible,
|
||||
onDismissRequest: () -> Unit,
|
||||
onFormatClick: (UiEditTypePropertiesItem.Format) -> Unit,
|
||||
) {
|
||||
val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
ModalBottomSheet(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onDismissRequest = onDismissRequest,
|
||||
dragHandle = { DragHandle() },
|
||||
scrimColor = colorResource(id = R.color.modal_screen_outside_background),
|
||||
containerColor = colorResource(id = R.color.background_primary),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
sheetState = bottomSheetState,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().height(48.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.property_select_format_title),
|
||||
style = Title1,
|
||||
color = colorResource(R.color.text_primary),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
|
||||
Divider(paddingStart = 0.dp, paddingEnd = 0.dp)
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.background(color = colorResource(id = R.color.background_primary)),
|
||||
state = lazyListState
|
||||
) {
|
||||
items(
|
||||
count = uiState.items.size,
|
||||
key = { index -> uiState.items[index].id },
|
||||
itemContent = { index ->
|
||||
val item = uiState.items[index]
|
||||
PropertyTypeItem(
|
||||
modifier = commonItemModifier()
|
||||
.clickable {
|
||||
onFormatClick(item)
|
||||
},
|
||||
item = item
|
||||
)
|
||||
}
|
||||
)
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(100.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ fun PropertyScreen(
|
|||
onCreateNewButtonClicked: () -> Unit = {},
|
||||
onDismissRequest: () -> Unit,
|
||||
onPropertyNameUpdate: (String) -> Unit,
|
||||
onDeleteButtonClicked: (Id) -> Unit ={},
|
||||
onMenuUnlinkClick: (Id) -> Unit ={}
|
||||
) {
|
||||
val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
ModalBottomSheet(
|
||||
|
@ -61,7 +61,7 @@ fun PropertyScreen(
|
|||
dragHandle = { DragHandle() },
|
||||
scrimColor = colorResource(id = R.color.modal_screen_outside_background),
|
||||
containerColor = colorResource(id = R.color.background_primary),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
||||
sheetState = bottomSheetState,
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
|
@ -73,16 +73,15 @@ fun PropertyScreen(
|
|||
onFormatClick = onFormatClick,
|
||||
onLimitTypesClick = onLimitTypesClick,
|
||||
onPropertyNameUpdate = onPropertyNameUpdate,
|
||||
onDeleteButtonClicked = {
|
||||
onDeleteButtonClicked(uiState.id)
|
||||
}
|
||||
onMenuUnlinkClick = onMenuUnlinkClick
|
||||
)
|
||||
|
||||
is UiEditPropertyState.Visible.View -> PropertyViewScreen(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
uiState = uiState,
|
||||
onFormatClick = onFormatClick,
|
||||
onLimitTypesClick = onLimitTypesClick
|
||||
onLimitTypesClick = onLimitTypesClick,
|
||||
onMenuUnlinkClick = onMenuUnlinkClick
|
||||
)
|
||||
|
||||
is UiEditPropertyState.Visible.New -> PropertyNewScreen(
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
package com.anytypeio.anytype.feature_properties.edit.ui
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
@ -15,14 +23,19 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.RelationFormat
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.foundation.Divider
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleThrottledClickable
|
||||
import com.anytypeio.anytype.core_ui.views.BodyRegular
|
||||
import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState
|
||||
|
||||
@Composable
|
||||
|
@ -30,12 +43,14 @@ fun PropertyViewScreen(
|
|||
modifier: Modifier,
|
||||
uiState: UiEditPropertyState.Visible.View,
|
||||
onFormatClick: () -> Unit,
|
||||
onLimitTypesClick: () -> Unit
|
||||
onLimitTypesClick: () -> Unit,
|
||||
onMenuUnlinkClick: (Id) -> Unit
|
||||
) {
|
||||
|
||||
var innerValue by remember(uiState.name) { mutableStateOf(uiState.name) }
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
Column(modifier = modifier) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
@ -59,7 +74,52 @@ fun PropertyViewScreen(
|
|||
emptyName = stringResource(R.string.untitled),
|
||||
onValueChange = { innerValue = it }
|
||||
)
|
||||
Spacer(modifier = Modifier.size(20.dp))
|
||||
if (uiState.isPossibleToUnlinkFromType) {
|
||||
Spacer(modifier = Modifier.size(4.dp))
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(end = 21.dp)
|
||||
.size(40.dp)
|
||||
.noRippleThrottledClickable {
|
||||
isMenuExpanded = true
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.align(Alignment.Center),
|
||||
painter = painterResource(id = R.drawable.ic_widget_three_dots),
|
||||
contentDescription = "Property menu icon",
|
||||
contentScale = ContentScale.None,
|
||||
)
|
||||
DropdownMenu(
|
||||
modifier = Modifier.defaultMinSize(minWidth = 244.dp),
|
||||
expanded = isMenuExpanded,
|
||||
onDismissRequest = { isMenuExpanded = false },
|
||||
shape = RoundedCornerShape(size = 10.dp),
|
||||
containerColor = colorResource(id = R.color.background_primary),
|
||||
shadowElevation = 5.dp,
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
modifier = Modifier.height(44.dp),
|
||||
onClick = {
|
||||
onMenuUnlinkClick(uiState.id)
|
||||
isMenuExpanded = false
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = stringResource(R.string.property_edit_menu_unlink),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.palette_system_red),
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Spacer(modifier = Modifier.size(20.dp))
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
@ -83,6 +143,8 @@ fun PropertyViewScreen(
|
|||
)
|
||||
Divider()
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,9 +159,11 @@ fun MyPreviewView() {
|
|||
name = "View property",
|
||||
formatName = "Text",
|
||||
formatIcon = R.drawable.ic_relation_format_date_small,
|
||||
format = RelationFormat.FILE
|
||||
format = RelationFormat.FILE,
|
||||
isPossibleToUnlinkFromType = true
|
||||
),
|
||||
onFormatClick = {},
|
||||
onLimitTypesClick = {}
|
||||
onLimitTypesClick = {},
|
||||
onMenuUnlinkClick = {}
|
||||
)
|
||||
}
|
|
@ -1865,12 +1865,12 @@ Please provide specific details of your needs here.</string>
|
|||
<string name="object_type_templates_menu_edit">Edit</string>
|
||||
<string name="object_type_templates_menu_duplicate">Duplicate</string>
|
||||
<string name="object_type_templates_menu_delete">Delete</string>
|
||||
<string name="object_type_fields_section_header">Header</string>
|
||||
<string name="object_type_fields_section_fields_menu">Sidebar</string>
|
||||
<string name="object_type_fields_section_header">Shown in object header</string>
|
||||
<string name="object_type_fields_section_fields_menu">Shown in properties menu</string>
|
||||
<string name="object_type_fields_section_hidden">Hidden</string>
|
||||
<string name="object_type_fields_section_file">File</string>
|
||||
<string name="object_type_fields_section_local_fields">Local fields</string>
|
||||
<string name="object_type_fields_title">Fields</string>
|
||||
<string name="object_type_fields_section_local_fields">Local properties</string>
|
||||
<string name="object_type_fields_title">Properties</string>
|
||||
<string name="object_type_fields_info_text">You\'re editing type</string>
|
||||
<string name="object_type_fields_edit_field">Edit field</string>
|
||||
<string name="object_type_fields_new_field">New field</string>
|
||||
|
@ -1921,7 +1921,7 @@ Please provide specific details of your needs here.</string>
|
|||
<string name="migration_migration_failed">Migration failed</string>
|
||||
<string name="migration_error_please_free_up_space_and_run_the_process_again">Please free up space and run the process again.</string>
|
||||
|
||||
<string name="fields_screen_title">Fields</string>
|
||||
<string name="fields_screen_title">Properties</string>
|
||||
<string name="field_text_title">Text</string>
|
||||
<string name="field_text_empty">Enter</string>
|
||||
<string name="field_number_title">Number</string>
|
||||
|
@ -1966,9 +1966,8 @@ Please provide specific details of your needs here.</string>
|
|||
<string name="space_settings_save_button">Save</string>
|
||||
|
||||
<string name="object_type_add_property_screen_title">Add property</string>
|
||||
<string name="object_type_add_property_screen_section">Properties types</string>
|
||||
<string name="object_type_add_property_screen_create">Create property \'%1$s\'"</string>
|
||||
<string name="object_type_add_property_screen_section_types">Properties types"</string>
|
||||
<string name="object_type_add_property_screen_section_types">Properties formats"</string>
|
||||
<string name="object_type_add_property_screen_section_existing">Existing properties"</string>
|
||||
<string name="object_type_add_property_screen_search_hint">Search or create new"</string>
|
||||
|
||||
|
@ -1979,4 +1978,8 @@ Please provide specific details of your needs here.</string>
|
|||
<string name="add_property_error_update">Error while updating property</string>
|
||||
<string name="add_property_error_add">Error while adding property to type</string>
|
||||
|
||||
<string name="property_select_format_title">Select property format</string>
|
||||
<string name="property_edit_menu_delete">Delete from space</string>
|
||||
<string name="property_edit_menu_unlink">Unlink from type</string>
|
||||
|
||||
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue