Коммит 44c800c0 создал по автору Radch-enko's avatar Radch-enko
Просмотр файлов

Refactor: unify date handling across components and optimize slot update logic

- Replaced `LocalDate` with `LocalDateTime` in `SlotComponent`, `MainComponent`, and related intents for better consistency.
- Improved `updateSlots` logic by migrating to cleaner coroutine handling and state updates.
- Fixed `DatePickerView` and `DateTimePickerComponent` to standardize month handling and date manipulation.
- Updated `NetworkEventRepository` to retain hour and minute components when resetting time.
владелец 32fcc2b6
......@@ -50,8 +50,8 @@ class NetworkEventRepository(
year = adjustedNow.year,
month = adjustedNow.month,
day = adjustedNow.day,
hour = 0,
minute = 0,
hour = adjustedNow.hour,
minute = adjustedNow.minute,
second = 0,
nanosecond = 0
)
......
package band.effective.office.tablet.feature.bookingEditor.presentation
import band.effective.office.tablet.core.domain.OfficeTime
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.model.Organizer
import band.effective.office.tablet.core.domain.model.Slot
......@@ -165,7 +166,7 @@ class BookingEditorComponent(
private fun setDay(newDate: LocalDateTime) = scope.launch {
with(state.value) {
val busyEvent: List<EventInfo> = checkBookingUseCase.busyEvents(
val busyEvents: List<EventInfo> = checkBookingUseCase.busyEvents(
event = copy(date = newDate).let(stateToEventInfoMapper::map),
room = room
).filter { it.startTime != date }
......@@ -181,14 +182,14 @@ class BookingEditorComponent(
newDuration = duration,
organizer = selectOrganizer,
),
isBusyEvent = busyEvent.isNotEmpty()
isBusyEvent = busyEvents.isNotEmpty()
)
}
if (selectOrganizer != Organizer.default) {
checkEnableButton(
inputError = isInputError,
busyEvent = busyEvent.isNotEmpty()
busyEvent = busyEvents.isNotEmpty()
)
}
}
......@@ -212,13 +213,15 @@ class BookingEditorComponent(
room = room
).filter { it.startTime != date }
fun today(): LocalDateTime {
val now = currentLocalDateTime
return now.date.atStartOfDayIn(defaultTimeZone).asLocalDateTime
}
if (newDuration > 0 && newDate > today()) {
val officeEndTime = OfficeTime.finishWorkTime(newDate.date)
val newEventFinish = newDate.asInstant.plus(newDuration.minutes).asLocalDateTime
if (newDuration > 0 && newDate > today() && newEventFinish < officeEndTime) {
mutableState.update {
it.copy(
date = newDate,
......
......@@ -18,6 +18,7 @@ import kotlinx.coroutines.launch
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.LocalTime
import kotlinx.datetime.Month
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
......@@ -45,8 +46,8 @@ class DateTimePickerComponent(
}
is Intent.OnChangeDate -> changeDate(
intent.date.year,
intent.date.monthNumber,
intent.date.dayOfMonth
intent.date.month,
intent.date.day,
)
is Intent.OnChangeTime -> changeTime(
intent.time.hour,
......@@ -57,14 +58,14 @@ class DateTimePickerComponent(
private fun changeDate(
year: Int,
month: Int,
month: Month,
dayOfMonth: Int
) = scope.launch {
val currentDate = state.value.currentDate
val newDate = LocalDateTime(
year = year,
monthNumber = month,
dayOfMonth = dayOfMonth,
month = month,
day = dayOfMonth,
hour = currentDate.hour,
minute = currentDate.minute,
second = 0,
......
......@@ -37,7 +37,7 @@ fun DatePickerView(
val year = it.year
val month = it.month
val day = it.day
onChangeDate(LocalDate(year, month.ordinal, day))
onChangeDate(LocalDate(year, month, day))
}
}
......
......@@ -47,7 +47,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
......@@ -130,7 +130,7 @@ class MainComponent(
}
}
// update events list
CoroutineScope(Dispatchers.Main).launch() {
CoroutineScope(Dispatchers.Main).launch {
roomInfoUseCase.subscribe().collect { roomsInfo ->
if (roomsInfo.isNotEmpty())
reboot(resetSelectRoom = false)
......@@ -158,7 +158,7 @@ class MainComponent(
currentDate = currentLocalDateTime,
)
}
slotComponent.sendIntent(SlotIntent.UpdateDate(currentLocalDate))
slotComponent.sendIntent(SlotIntent.UpdateDate(currentLocalDateTime))
}
}
}
......@@ -253,7 +253,7 @@ class MainComponent(
// there is no point in looking at bookings from the past days
if (newDate.date >= currentLocalDateTime.date) {
mutableState.update { it.copy(selectedDate = newDate) }
slotComponent.sendIntent(SlotIntent.UpdateDate(newDate.date))
slotComponent.sendIntent(SlotIntent.UpdateDate(newDate))
}
}
......@@ -268,19 +268,12 @@ class MainComponent(
)
)
}
updateComponents(state.value.roomList[index], state.value.selectedDate.date)
updateComponents(state.value.roomList[index], state.value.selectedDate)
}
private fun updateComponents(roomInfo: RoomInfo, date: LocalDate) {
slotComponent.sendIntent(
SlotIntent.UpdateRequest(
room = roomInfo.name,
refresh = false
)
)
slotComponent.sendIntent(
SlotIntent.UpdateDate(date)
)
private fun updateComponents(roomInfo: RoomInfo, date: LocalDateTime) {
slotComponent.sendIntent(SlotIntent.UpdateRequest(room = roomInfo.name))
slotComponent.sendIntent(SlotIntent.UpdateDate(date))
}
private fun loadRooms() = coroutineScope.launch {
......@@ -345,7 +338,7 @@ class MainComponent(
}
loadRooms()
state.roomList.getOrNull(roomIndex)?.let { roomInfo ->
updateComponents(roomInfo, state.selectedDate.date)
updateComponents(roomInfo, state.selectedDate)
}
}
}
......@@ -18,14 +18,13 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
......@@ -62,14 +61,16 @@ class SlotComponent(
updateSlots(uiSlots)
}
}
coroutineScope.launch(Dispatchers.IO) {
/*coroutineScope.launch(Dispatchers.IO) {
roomInfoUseCase.subscribe().collect { roomsInfo ->
val roomInfo = roomsInfo.firstOrNull { it.name == roomName() } ?: return@collect
val uiSlots = getSlotsByRoomUseCase(roomInfo).map(slotUiMapper::map)
val uiSlots = getSlotsByRoomUseCase(
roomInfo = roomInfo,
).map(slotUiMapper::map)
updateSlots(uiSlots)
}
}
}*/
}
private suspend fun updateSlots(uiSlots: List<SlotUi>) = withContext(Dispatchers.Main.immediate) {
......@@ -92,6 +93,14 @@ class SlotComponent(
}
}
private fun updateRequest(intent: SlotIntent.UpdateRequest) = coroutineScope.launch {
roomInfoUseCase.getRoom(intent.room)?.let { roomInfo ->
val slots = getSlotsByRoomUseCase(roomInfo = roomInfo)
val uiSlots = slots.map(slotUiMapper::map)
mutableState.update { it.copy(slots = uiSlots) }
}
}
private fun cancelDeletingSlot(intent: SlotIntent.OnCancelDelete) {
val slots = state.value.slots
val original = intent.slot.original
......@@ -211,32 +220,14 @@ class SlotComponent(
isLoading = false,
)
private fun updateRequest(intent: SlotIntent.UpdateRequest) {
if (!state.value.slots.any { it is SlotUi.DeleteSlot } || intent.refresh) {
updateSlot(intent.room, intent.refresh)
}
}
private fun updateSlot(roomName: String, refresh: Boolean) = coroutineScope.launch {
if (refresh) {
withContext(Dispatchers.IO) {
roomInfoUseCase.updateCache()
}
}
roomInfoUseCase.getRoom(roomName)?.let { roomInfo ->
val slots = getSlotsByRoomUseCase(
roomInfo = roomInfo,
)
val uiSlots = slots.map(slotUiMapper::map)
mutableState.update { it.copy(slots = uiSlots) }
}
}
private fun updateDate(newDate: LocalDate) = coroutineScope.launch {
private fun updateDate(newDate: LocalDateTime) = coroutineScope.launch {
roomInfoUseCase.getRoom(room = roomName())?.let { roomInfo ->
val slots = getSlotsByRoomUseCase(
roomInfo = roomInfo,
start = OfficeTime.startWorkTime(newDate)
start = maxOf(
OfficeTime.startWorkTime(newDate.date).asInstant,
currentInstant,
).asLocalDateTime
)
val uiSlots = slots.map(slotUiMapper::map)
mutableState.update { it.copy(slots = uiSlots) }
......
package band.effective.office.tablet.feature.slot.presentation
import band.effective.office.tablet.core.domain.model.Slot
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
sealed interface SlotIntent {
data class ClickOnSlot(val slot: SlotUi) : SlotIntent
data class UpdateRequest(val room: String, val refresh: Boolean = true) : SlotIntent
data class UpdateDate(val newDate: LocalDate) : SlotIntent
data class UpdateDate(val newDate: LocalDateTime) : SlotIntent
data class UpdateRequest(val room: String) : SlotIntent
data class Delete(val slot: Slot, val onDelete: () -> Unit) : SlotIntent
data class OnCancelDelete(val slot: SlotUi.DeleteSlot) : SlotIntent
}
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать