From ad58c376d33a5d526c0e5896f23be0b10b3c9d2a Mon Sep 17 00:00:00 2001 From: Konstantin Ivanov <54908981+konstantiniiv@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:11:46 +0100 Subject: [PATCH] DROID-2121 Relations | Create or edit options screen (#821) --- .../value/CreateOrEditOptionFragment.kt | 12 +- .../value/TagOrStatusValueFragment.kt | 13 +- .../relations/CreateOrEditOptionScreen.kt | 268 ++++++++++++++++++ .../anytype/core_ui/relations/OptionWidget.kt | 63 ---- .../core_ui/relations/RelationsLazyList.kt | 37 +-- .../option/CreateOrEditOptionViewModel.kt | 142 +++++++++- 6 files changed, 430 insertions(+), 105 deletions(-) create mode 100644 core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/CreateOrEditOptionScreen.kt delete mode 100644 core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/OptionWidget.kt diff --git a/app/src/main/java/com/anytypeio/anytype/ui/relations/value/CreateOrEditOptionFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/relations/value/CreateOrEditOptionFragment.kt index fcbb322651..d902bcae62 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/relations/value/CreateOrEditOptionFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/relations/value/CreateOrEditOptionFragment.kt @@ -12,9 +12,11 @@ import androidx.compose.ui.res.colorResource import androidx.compose.ui.unit.dp import androidx.core.os.bundleOf import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.Key +import com.anytypeio.anytype.core_ui.relations.CreateOrEditOptionScreen import com.anytypeio.anytype.core_utils.ext.argString import com.anytypeio.anytype.core_utils.ext.argStringOrNull import com.anytypeio.anytype.core_utils.ext.subscribe @@ -54,12 +56,18 @@ class CreateOrEditOptionFragment : BaseBottomSheetComposeFragment() { colors = MaterialTheme.colors.copy( surface = colorResource(id = R.color.context_menu_background) ) - ) {} + ) { + CreateOrEditOptionScreen( + state = vm.viewState.collectAsStateWithLifecycle().value, + onButtonClicked = { vm.onButtonClick() }, + onTextChanged = { vm.updateName(it) }, + onColorChanged = { vm.updateColor(it) } + ) + } } } } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) skipCollapsed() diff --git a/app/src/main/java/com/anytypeio/anytype/ui/relations/value/TagOrStatusValueFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/relations/value/TagOrStatusValueFragment.kt index 3d149e4704..1fd8312b9a 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/relations/value/TagOrStatusValueFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/relations/value/TagOrStatusValueFragment.kt @@ -12,11 +12,14 @@ import androidx.compose.ui.res.colorResource import androidx.compose.ui.unit.dp import androidx.core.os.bundleOf import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.Key +import com.anytypeio.anytype.core_ui.relations.RelationsLazyList +import com.anytypeio.anytype.core_ui.relations.TagOrStatusValueScreen import com.anytypeio.anytype.core_utils.ext.argBoolean import com.anytypeio.anytype.core_utils.ext.argString import com.anytypeio.anytype.core_utils.ext.subscribe @@ -55,11 +58,11 @@ class TagOrStatusValueFragment : BaseBottomSheetComposeFragment() { surface = colorResource(id = R.color.context_menu_background) ) ) { -// RelationsValueScreen( -// state = vm.viewState.collectAsStateWithLifecycle().value, -// action = vm::onAction, -// onQueryChanged = vm::onQueryChanged -// ) + TagOrStatusValueScreen( + state = vm.viewState.collectAsStateWithLifecycle().value, + action = vm::onAction, + onQueryChanged = vm::onQueryChanged + ) } } } diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/CreateOrEditOptionScreen.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/CreateOrEditOptionScreen.kt new file mode 100644 index 0000000000..1856a58bc3 --- /dev/null +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/CreateOrEditOptionScreen.kt @@ -0,0 +1,268 @@ +package com.anytypeio.anytype.core_ui.relations + + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +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.wrapContentHeight +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.SoftwareKeyboardController +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Devices +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.anytypeio.anytype.core_models.ThemeColor +import com.anytypeio.anytype.core_ui.R +import com.anytypeio.anytype.core_ui.extensions.dark +import com.anytypeio.anytype.core_ui.foundation.Divider +import com.anytypeio.anytype.core_ui.foundation.Dragger +import com.anytypeio.anytype.core_ui.foundation.noRippleClickable +import com.anytypeio.anytype.core_ui.views.ButtonPrimary +import com.anytypeio.anytype.core_ui.views.ButtonSize +import com.anytypeio.anytype.core_ui.views.Caption1Regular +import com.anytypeio.anytype.core_ui.views.Title1 +import com.anytypeio.anytype.presentation.relations.option.CreateOrEditOptionScreenViewState + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +fun CreateOrEditOptionScreen( + state: CreateOrEditOptionScreenViewState, + onButtonClicked: () -> Unit, + onTextChanged: (String) -> Unit, + onColorChanged: (ThemeColor) -> Unit +) { + val focusRequester = remember { FocusRequester() } + + val currentState by rememberUpdatedState(state) + val keyboardController = LocalSoftwareKeyboardController.current + + var selectedColor by remember { mutableStateOf(currentState.color) } + var editableText by remember { mutableStateOf(currentState.text) } + + val (title, buttonText) = getTexts(currentState) + Column( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .verticalScroll(rememberScrollState()) + .padding(bottom = 20.dp, start = 20.dp, end = 20.dp) + ) { + Header(text = title) + TextInput( + initialValue = currentState.text, + color = currentState.color, + onTextChanged = { + editableText = it + onTextChanged(it) + }, + focusRequester = focusRequester, + keyboardController = keyboardController + ) + Divider(paddingEnd = 0.dp, paddingStart = 0.dp) + Spacer(modifier = Modifier.height(26.dp)) + Text( + text = stringResource(id = R.string.color), + style = Caption1Regular, + color = colorResource(id = R.color.text_secondary) + ) + Spacer(modifier = Modifier.height(20.dp)) + CirclesContainer(selectedColor = selectedColor) { newColor -> + selectedColor = newColor + onColorChanged(newColor) + } + Spacer(modifier = Modifier.height(115.dp)) + ButtonPrimary( + text = buttonText, + modifier = Modifier + .fillMaxWidth() + .imePadding(), + onClick = { onButtonClicked() }, + size = ButtonSize.Large + ) + } +} + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun CirclesContainer(selectedColor: ThemeColor, action: (ThemeColor) -> Unit) { + FlowRow( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + maxItemsInEachRow = 5 + ) { + val itemModifier = Modifier + .weight(1f) + .fillMaxWidth() + .clip(CircleShape) + .aspectRatio(1f) + .align(Alignment.CenterVertically) + ThemeColor.values().drop(1).forEach { color -> + Box( + itemModifier + .noRippleClickable { action(color) } + .background( + color = dark(color = color) + ) + ) { + if (selectedColor == color) { + Image( + modifier = Modifier.align(Alignment.Center), + painter = painterResource(id = R.drawable.ic_tick_24), + contentDescription = "option selected" + ) + } + } + } + } +} + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +private fun TextInput( + initialValue: String, + color: ThemeColor, + focusRequester: FocusRequester, + keyboardController: SoftwareKeyboardController?, + onTextChanged: (String) -> Unit +) { + var innerValue by remember { mutableStateOf(initialValue) } + val focusManager = LocalFocusManager.current + + if (initialValue.isEmpty()) { + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } + } + + BasicTextField( + value = innerValue, + onValueChange = { + innerValue = it + onTextChanged(it) + }, + textStyle = Title1.copy(color = dark(color = color)), + singleLine = true, + enabled = true, + cursorBrush = SolidColor(dark(color = color)), + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(start = 0.dp, top = 2.dp) + .focusRequester(focusRequester), + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions { + keyboardController?.hide() + focusManager.clearFocus() + }, + decorationBox = { innerTextField -> + if (innerValue.isEmpty()) { + Text( + text = stringResource(id = R.string.hint_enter_name), + style = Title1, + color = colorResource(id = R.color.text_tertiary), + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + ) + } + innerTextField() + } + ) +} + +@Composable +private fun Header(text: String) { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 6.dp) + ) { + Dragger(modifier = Modifier.align(Alignment.Center)) + } + + // Main content box + Box( + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + ) { + Text( + modifier = Modifier + .align(Alignment.Center) + .padding(horizontal = 74.dp), + text = text, + style = Title1.copy(), + color = colorResource(R.color.text_primary), + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + } +} + +@Composable +private fun getTexts(state: CreateOrEditOptionScreenViewState): Pair { + return when (state) { + is CreateOrEditOptionScreenViewState.Create -> { + stringResource(id = R.string.option_widget_create) to stringResource(id = R.string.create) + } + + is CreateOrEditOptionScreenViewState.Edit -> { + stringResource(id = R.string.option_widget_edit) to stringResource(id = R.string.apply) + } + } +} + +@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, device = Devices.PIXEL_4_XL) +@Composable +fun PreviewOptionWidget() { + CreateOrEditOptionScreen( + state = CreateOrEditOptionScreenViewState.Create( + text = "Urgent", + color = ThemeColor.BLUE, + ), + onButtonClicked = {}, + onTextChanged = {}, + onColorChanged = {} + ) +} \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/OptionWidget.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/OptionWidget.kt deleted file mode 100644 index 7589de763e..0000000000 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/OptionWidget.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.anytypeio.anytype.core_ui.relations - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.platform.SoftwareKeyboardController -import com.anytypeio.anytype.core_models.ThemeColor -import com.anytypeio.anytype.presentation.relations.option.OptionScreenViewState - -@OptIn(ExperimentalComposeUiApi::class) -@Composable -fun OptionWidget( - state: OptionScreenViewState, - onButtonClicked: () -> Unit, - onTextChanged: (String) -> Unit, - onColorChanged: (ThemeColor) -> Unit -) { - val focusRequester = remember { FocusRequester() } - val focusManager = LocalFocusManager.current - - Box( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - contentAlignment = Alignment.TopCenter, - ) { - - val currentState by rememberUpdatedState(state) - val keyboardController = LocalSoftwareKeyboardController.current - - OptionWidgetContent( - state = currentState, - onButtonClicked = onButtonClicked, - focusRequester = focusRequester, - keyboardController = keyboardController, - onTextChanged = onTextChanged, - onColorChanged = onColorChanged - ) - } -} - -@OptIn(ExperimentalComposeUiApi::class) -@Composable -fun OptionWidgetContent( - state: OptionScreenViewState, - onButtonClicked: () -> Unit, - focusRequester: FocusRequester, - keyboardController: SoftwareKeyboardController?, - onTextChanged: (String) -> Unit, - onColorChanged: (ThemeColor) -> Unit -) { - -} \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/RelationsLazyList.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/RelationsLazyList.kt index 6ffe61f77f..52d6a7401e 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/RelationsLazyList.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/relations/RelationsLazyList.kt @@ -26,9 +26,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.anytypeio.anytype.core_models.ThemeColor import com.anytypeio.anytype.core_ui.R import com.anytypeio.anytype.core_ui.foundation.Divider import com.anytypeio.anytype.core_ui.foundation.Dragger @@ -42,7 +40,7 @@ import com.anytypeio.anytype.presentation.relations.value.tagstatus.TagStatusAct import com.anytypeio.anytype.presentation.relations.value.tagstatus.TagStatusViewState @Composable -fun RelationsValueScreen( +fun TagOrStatusValueScreen( state: TagStatusViewState, action: (TagStatusAction) -> Unit, onQueryChanged: (String) -> Unit @@ -193,12 +191,14 @@ fun RelationsViewLoading() { private fun isClearButtonVisible(state: TagStatusViewState): Boolean { if (state !is TagStatusViewState.Content) return false - return state.items.any { it is RelationsListItem.Item.Tag && it.isSelected - || it is RelationsListItem.Item.Status && it.isSelected } && state.isRelationEditable + return state.items.any { + it is RelationsListItem.Item.Tag && it.isSelected + || it is RelationsListItem.Item.Status && it.isSelected + } && state.isRelationEditable } private fun isPlusButtonVisible(state: TagStatusViewState): Boolean { - return when (state) { + return when (state) { is TagStatusViewState.Content -> state.isRelationEditable is TagStatusViewState.Empty -> state.isRelationEditable is TagStatusViewState.Loading -> false @@ -211,29 +211,4 @@ private fun getTitle(state: TagStatusViewState): String { is TagStatusViewState.Empty -> state.title is TagStatusViewState.Loading -> "" } -} - -@Preview(backgroundColor = 0xFFFFFFFF, showBackground = true) -@Composable -fun MyWidgetHeader() { - Header(state = TagStatusViewState.Content( - isRelationEditable = true, - title = "Tags", - items = listOf( - RelationsListItem.Item.Tag( - name = "Urgent", - color = ThemeColor.RED, - number = 1, - isSelected = true, - optionId = "1" - ), - RelationsListItem.Item.Tag( - name = "Personal", - color = ThemeColor.ORANGE, - number = 2, - isSelected = false, - optionId = "1" - ) - ) - ), action = {}) } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/option/CreateOrEditOptionViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/option/CreateOrEditOptionViewModel.kt index 4406469ce3..74e1db84d5 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/option/CreateOrEditOptionViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/option/CreateOrEditOptionViewModel.kt @@ -1,18 +1,26 @@ package com.anytypeio.anytype.presentation.relations.option +import androidx.lifecycle.viewModelScope import com.anytypeio.anytype.analytics.base.Analytics 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.Payload import com.anytypeio.anytype.core_models.ThemeColor +import com.anytypeio.anytype.core_models.Relations +import com.anytypeio.anytype.core_utils.ext.typeOf +import com.anytypeio.anytype.domain.base.fold import com.anytypeio.anytype.domain.`object`.SetObjectDetails import com.anytypeio.anytype.domain.relations.CreateRelationOption import com.anytypeio.anytype.domain.workspace.SpaceManager import com.anytypeio.anytype.presentation.common.BaseViewModel +import com.anytypeio.anytype.presentation.extension.sendAnalyticsRelationValueEvent import com.anytypeio.anytype.presentation.relations.providers.ObjectValueProvider import com.anytypeio.anytype.presentation.util.Dispatcher import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import timber.log.Timber class CreateOrEditOptionViewModel( private val viewModelParams: ViewModelParams, @@ -25,7 +33,133 @@ class CreateOrEditOptionViewModel( ) : BaseViewModel() { val command = MutableSharedFlow(replay = 0) - val viewState: MutableStateFlow? = null + val viewState: MutableStateFlow = + MutableStateFlow(initialViewState()) + + private fun initialViewState(): CreateOrEditOptionScreenViewState { + val optionId = viewModelParams.optionId + val color = getOptionColor() + return if (optionId != null) { + Timber.d("Editing option with id: $optionId") + CreateOrEditOptionScreenViewState.Edit( + optionId = optionId, + text = viewModelParams.name.orEmpty(), + color = color + ) + + } else { + Timber.d("Creating new option") + CreateOrEditOptionScreenViewState.Create( + text = viewModelParams.name.orEmpty(), + color = color + ) + } + } + + fun updateName(name: String) { + viewState.value = when (val state = viewState.value) { + is CreateOrEditOptionScreenViewState.Create -> state.copy(text = name) + is CreateOrEditOptionScreenViewState.Edit -> state.copy(text = name) + } + } + + fun updateColor(color: ThemeColor) { + viewState.value = when (val state = viewState.value) { + is CreateOrEditOptionScreenViewState.Create -> state.copy(color = color) + is CreateOrEditOptionScreenViewState.Edit -> state.copy(color = color) + } + } + + fun onButtonClick() { + when (viewState.value) { + is CreateOrEditOptionScreenViewState.Create -> proceedWithCreatingOption() + is CreateOrEditOptionScreenViewState.Edit -> proceedWithUpdatingOption() + } + } + + private fun proceedWithCreatingOption() { + viewModelScope.launch { + val params = CreateRelationOption.Params( + space = spaceManager.get(), + relation = viewModelParams.relationKey, + name = viewState.value.text, + color = viewState.value.color.code + ) + if (params.name.isNotEmpty()) { + createOption.invoke(params).proceed( + success = { option -> + proceedWithAddingTagToObject( + ctx = viewModelParams.ctx, + objectId = viewModelParams.objectId, + relationKey = viewModelParams.relationKey, + option = option + ) + }, + failure = { Timber.e(it, "Error while creating option") } + ) + } + } + } + + private fun proceedWithUpdatingOption() { + val optionId = viewModelParams.optionId ?: return + viewModelScope.launch { + val params = SetObjectDetails.Params( + ctx = optionId, + details = mapOf( + Relations.NAME to viewState.value.text, + Relations.RELATION_OPTION_COLOR to viewState.value.color.code + ) + ) + setObjectDetails.execute(params).fold( + onFailure = { Timber.e(it, "Error while updating option") }, + onSuccess = { + dispatcher.send(it) + viewModelScope.sendAnalyticsRelationValueEvent(analytics) + command.emit(Command.Dismiss) + } + ) + } + } + + private suspend fun proceedWithAddingTagToObject( + ctx: Id, + objectId: Id, + relationKey: Key, + option: ObjectWrapper.Option + ) { + Timber.d("Adding option to object with id: $objectId") + val obj = values.get(target = objectId, ctx = ctx) + val result = mutableListOf() + val value = obj[relationKey] + if (value is List<*>) { + result.addAll(value.typeOf()) + } else if (value is Id) { + result.add(value) + } + result.add(option.id) + val params = SetObjectDetails.Params( + ctx = objectId, + details = mapOf(relationKey to result) + ) + setObjectDetails.execute(params).fold( + onFailure = { Timber.e(it, "Error while adding tag to object") }, + onSuccess = { + dispatcher.send(it) + viewModelScope.sendAnalyticsRelationValueEvent(analytics) + command.emit(Command.Dismiss) + } + ) + } + + private fun getOptionColor(): ThemeColor { + val color = viewModelParams.color + return if (color != null) { + ThemeColor.fromCode(color) + } else { + ThemeColor.values().filter { it != ThemeColor.DEFAULT }.random() + } + } data class ViewModelParams( val ctx: Id, @@ -41,7 +175,7 @@ class CreateOrEditOptionViewModel( } } -sealed class OptionScreenViewState { +sealed class CreateOrEditOptionScreenViewState { abstract val text: String abstract val color: ThemeColor @@ -49,10 +183,10 @@ sealed class OptionScreenViewState { val optionId: Id, override val text: String, override val color: ThemeColor - ) : OptionScreenViewState() + ) : CreateOrEditOptionScreenViewState() data class Create( override val text: String, override val color: ThemeColor - ) : OptionScreenViewState() + ) : CreateOrEditOptionScreenViewState() } \ No newline at end of file