Не подтверждена Коммит 80ea433e создал по автору Stanislav Radchenko's avatar Stanislav Radchenko Зафиксировано автором GitHub
Просмотр файлов

Merge pull request #13 from Radch-enko/feature/nested-slot-deletion

feat: implement nested slot deletion functionality
владельцы 17ed300e e85fafff
...@@ -22,6 +22,7 @@ import band.effective.office.tablet.core.ui.date.DateTimeView ...@@ -22,6 +22,7 @@ import band.effective.office.tablet.core.ui.date.DateTimeView
import band.effective.office.tablet.feature.main.components.RoomInfoComponent import band.effective.office.tablet.feature.main.components.RoomInfoComponent
import band.effective.office.tablet.feature.slot.presentation.SlotComponent import band.effective.office.tablet.feature.slot.presentation.SlotComponent
import band.effective.office.tablet.feature.slot.presentation.SlotIntent import band.effective.office.tablet.feature.slot.presentation.SlotIntent
import band.effective.office.tablet.feature.slot.presentation.SlotUi
import band.effective.office.tablet.feature.slot.presentation.components.SlotView import band.effective.office.tablet.feature.slot.presentation.components.SlotView
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalDateTime
...@@ -88,7 +89,8 @@ fun RoomInfoLeftPanel( ...@@ -88,7 +89,8 @@ fun RoomInfoLeftPanel(
) { ) {
SlotView( SlotView(
slotUi = it, slotUi = it,
onClick = { slotComponent.sendIntent(SlotIntent.ClickOnSlot(it)) }, onClick = { slotComponent.sendIntent(SlotIntent.ClickToEdit(this)) },
onToggle = { (it as? SlotUi.MultiSlot)?.let { slotComponent.sendIntent(SlotIntent.ClickToToggle(it)) } },
onCancel = { deleteSlot -> slotComponent.sendIntent(SlotIntent.OnCancelDelete(deleteSlot)) } onCancel = { deleteSlot -> slotComponent.sendIntent(SlotIntent.OnCancelDelete(deleteSlot)) }
) )
} }
......
...@@ -82,7 +82,8 @@ class SlotComponent( ...@@ -82,7 +82,8 @@ class SlotComponent(
fun sendIntent(intent: SlotIntent) { fun sendIntent(intent: SlotIntent) {
when (intent) { when (intent) {
is SlotIntent.ClickOnSlot -> intent.slot.execute(state.value) is SlotIntent.ClickToEdit -> handleClickToEdit(intent.slot)
is SlotIntent.ClickToToggle -> openMultislot(intent.slot)
is SlotIntent.Delete -> deleteSlot(intent) is SlotIntent.Delete -> deleteSlot(intent)
is SlotIntent.OnCancelDelete -> cancelDeletingSlot(intent) is SlotIntent.OnCancelDelete -> cancelDeletingSlot(intent)
is SlotIntent.UpdateDate -> updateDate(intent.newDate) is SlotIntent.UpdateDate -> updateDate(intent.newDate)
...@@ -90,6 +91,14 @@ class SlotComponent( ...@@ -90,6 +91,14 @@ class SlotComponent(
} }
} }
private fun handleClickToEdit(slot: SlotUi) {
when (slot) {
is SlotUi.SimpleSlot -> slot.slot.execute()
is SlotUi.NestedSlot -> slot.slot.execute()
else -> {}
}
}
private fun updateRequest(intent: SlotIntent.UpdateRequest) = coroutineScope.launch { private fun updateRequest(intent: SlotIntent.UpdateRequest) = coroutineScope.launch {
roomInfoUseCase.getRoom(intent.room)?.let { roomInfo -> roomInfoUseCase.getRoom(intent.room)?.let { roomInfo ->
val slots = getSlotsByRoomUseCase(roomInfo = roomInfo) val slots = getSlotsByRoomUseCase(roomInfo = roomInfo)
...@@ -129,10 +138,10 @@ class SlotComponent( ...@@ -129,10 +138,10 @@ class SlotComponent(
when { when {
uiSlot == null -> {} uiSlot == null -> {}
mainSlot != null -> { mainSlot != null -> {
val indexInMultiSlot = mainSlot.subSlots.indexOf(uiSlot) val indexInMultiSlot = mainSlot!!.subSlots.indexOf(uiSlot)
val indexMultiSlot = slots.indexOf(mainSlot) val indexMultiSlot = slots.indexOf(mainSlot)
val newMainSlot = mainSlot.copy( val newMainSlot = mainSlot!!.copy(
subSlots = mainSlot.subSlots.toMutableList().apply { subSlots = mainSlot!!.subSlots.toMutableList().apply {
this[indexInMultiSlot] = this[indexInMultiSlot] =
SlotUi.DeleteSlot( SlotUi.DeleteSlot(
slot = intent.slot, slot = intent.slot,
...@@ -168,27 +177,16 @@ class SlotComponent( ...@@ -168,27 +177,16 @@ class SlotComponent(
} }
} }
} }
private fun Slot.execute() = when (this) {
private fun SlotUi.execute(state: State) = when (this) {
is SlotUi.DeleteSlot -> {}
is SlotUi.MultiSlot -> openMultislot(this, state)
is SlotUi.SimpleSlot -> slot.execute(state)
is SlotUi.NestedSlot -> slot.execute(state)
is SlotUi.LoadingSlot -> {
slot.execute(state)
}
}
private fun Slot.execute(state: State) = when (this) {
is Slot.EmptySlot -> executeFreeSlot(this) is Slot.EmptySlot -> executeFreeSlot(this)
is Slot.EventSlot -> executeEventSlot(this) is Slot.EventSlot -> executeEventSlot(this)
is Slot.MultiEventSlot -> {} else -> {}
is Slot.LoadingEventSlot -> {}
} }
private fun openMultislot(multislot: SlotUi.MultiSlot, state: State) { private fun openMultislot(multislot: SlotUi.MultiSlot) {
val slots = state.slots.toMutableList() val slots = state.value.slots.toMutableList()
val index = slots.indexOf(multislot) val index = slots.indexOf(multislot)
if (index < 0) return
slots[index] = multislot.copy(isOpen = !multislot.isOpen) slots[index] = multislot.copy(isOpen = !multislot.isOpen)
mutableState.update { it.copy(slots = slots) } mutableState.update { it.copy(slots = slots) }
} }
......
...@@ -4,7 +4,8 @@ import band.effective.office.tablet.core.domain.model.Slot ...@@ -4,7 +4,8 @@ import band.effective.office.tablet.core.domain.model.Slot
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalDateTime
sealed interface SlotIntent { sealed interface SlotIntent {
data class ClickOnSlot(val slot: SlotUi) : SlotIntent data class ClickToEdit(val slot: SlotUi) : SlotIntent
data class ClickToToggle(val slot: SlotUi.MultiSlot) : SlotIntent
data class UpdateDate(val newDate: LocalDateTime) : SlotIntent data class UpdateDate(val newDate: LocalDateTime) : SlotIntent
data class UpdateRequest(val room: String) : SlotIntent data class UpdateRequest(val room: String) : SlotIntent
data class Delete(val slot: Slot, val onDelete: () -> Unit) : SlotIntent data class Delete(val slot: Slot, val onDelete: () -> Unit) : SlotIntent
......
...@@ -2,6 +2,7 @@ package band.effective.office.tablet.feature.slot.presentation.components ...@@ -2,6 +2,7 @@ package band.effective.office.tablet.feature.slot.presentation.components
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
...@@ -19,24 +20,32 @@ import org.jetbrains.compose.resources.painterResource ...@@ -19,24 +20,32 @@ import org.jetbrains.compose.resources.painterResource
fun MultiSlotView( fun MultiSlotView(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
slotUi: SlotUi.MultiSlot, slotUi: SlotUi.MultiSlot,
onItemClick: (SlotUi) -> Unit, onItemClick: SlotUi.() -> Unit,
onToggle: SlotUi.() -> Unit,
onCancel: (SlotUi.DeleteSlot) -> Unit onCancel: (SlotUi.DeleteSlot) -> Unit
) { ) {
Column(Modifier.animateContentSize()) { Column(Modifier.animateContentSize()) {
CommonSlotView(modifier, slotUi) { CommonSlotView(
val rotateDegrees = if (slotUi.isOpen) 180f else 0f modifier = modifier.clickable { onToggle(slotUi) },
slotUi = slotUi
) {
Image( Image(
modifier = Modifier.fillMaxHeight().rotate(rotateDegrees), modifier = Modifier
.fillMaxHeight()
.rotate(if (slotUi.isOpen) 180f else 0f)
.clickable { onToggle(slotUi) },
painter = painterResource(Res.drawable.arrow_to_down), painter = painterResource(Res.drawable.arrow_to_down),
contentDescription = null contentDescription = null
) )
} }
if (slotUi.isOpen) { if (slotUi.isOpen) {
slotUi.subSlots.forEach { slotUi.subSlots.forEach {
Spacer(Modifier.height(20.dp)) Spacer(Modifier.height(20.dp))
SlotView( SlotView(
slotUi = it, slotUi = it,
onClick = onItemClick, onClick = onItemClick,
onToggle = onToggle,
onCancel = onCancel onCancel = onCancel
) )
} }
......
...@@ -29,21 +29,30 @@ import org.jetbrains.compose.resources.stringResource ...@@ -29,21 +29,30 @@ import org.jetbrains.compose.resources.stringResource
fun SlotView( fun SlotView(
slotUi: SlotUi, slotUi: SlotUi,
onClick: SlotUi.() -> Unit, onClick: SlotUi.() -> Unit,
onToggle: SlotUi.() -> Unit,
onCancel: (SlotUi.DeleteSlot) -> Unit onCancel: (SlotUi.DeleteSlot) -> Unit
) { ) {
val borderShape = CircleShape val borderShape = CircleShape
val itemModifier = Modifier val baseModifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clip(borderShape) .clip(borderShape)
.background(MaterialTheme.colorScheme.surface) .background(MaterialTheme.colorScheme.surface)
.clickable { slotUi.onClick() }
val itemModifier = baseModifier
.run { .run {
if (slotUi !is SlotUi.DeleteSlot) border( when (slotUi) {
is SlotUi.MultiSlot -> this
else -> clickable { slotUi.onClick() }
}
}
.then(
if (slotUi !is SlotUi.DeleteSlot) Modifier.border(
width = 5.dp, width = 5.dp,
color = slotUi.borderColor(), color = slotUi.borderColor(),
shape = borderShape shape = borderShape
).padding(vertical = 15.dp, horizontal = 30.dp) else this ).padding(vertical = 15.dp, horizontal = 30.dp)
} else Modifier
)
when (slotUi) { when (slotUi) {
is SlotUi.DeleteSlot -> DeletedSlotView( is SlotUi.DeleteSlot -> DeletedSlotView(
...@@ -56,7 +65,8 @@ fun SlotView( ...@@ -56,7 +65,8 @@ fun SlotView(
is SlotUi.MultiSlot -> MultiSlotView( is SlotUi.MultiSlot -> MultiSlotView(
modifier = itemModifier, modifier = itemModifier,
slotUi = slotUi, slotUi = slotUi,
onItemClick = { item -> item.onClick() }, onItemClick = onClick,
onToggle = onToggle,
onCancel = onCancel onCancel = onCancel
) )
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать