From a26d2d6f91b7569b10ddfa5da2535d703cad4263 Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:21:53 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt b/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt index 109a4484..abdf8050 100644 --- a/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt +++ b/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt @@ -325,6 +325,11 @@ object DateTimeFormatter { fun LocalTime.toIsoTimeString(): String = "${hour.pad2()}:${minute.pad2()}:${second.pad2()}" + /** + * @param: date 선택된 날짜 + * @param: time 선택된 시간 + * @return: LocalDate, LocalTime을 조합한 ISO8601 문자열 + * */ fun formatIsoDateTime( date: LocalDate, time: LocalTime, From e97ad6bf25f19f5aefa83100d94b42a77c8e4146 Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:22:19 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=E2=9C=A8=20Feat:=20AppResult=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EC=9D=BC=EC=A0=95=20=EC=82=AD=EC=A0=9C=20API=20?= =?UTF-8?q?=ED=86=B5=EC=8B=A0=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ondot/data/repository/ScheduleRepositoryImpl.kt | 8 ++++++++ .../com/ondot/domain/repository/ScheduleRepository.kt | 2 ++ 2 files changed, 10 insertions(+) diff --git a/data/src/commonMain/kotlin/com/ondot/data/repository/ScheduleRepositoryImpl.kt b/data/src/commonMain/kotlin/com/ondot/data/repository/ScheduleRepositoryImpl.kt index c275a212..e274a450 100644 --- a/data/src/commonMain/kotlin/com/ondot/data/repository/ScheduleRepositoryImpl.kt +++ b/data/src/commonMain/kotlin/com/ondot/data/repository/ScheduleRepositoryImpl.kt @@ -119,6 +119,14 @@ class ScheduleRepositoryImpl( ) } + override suspend fun deleteScheduleAppResult(scheduleId: Long): AppResult = + safeApiCall { + networkClient.requestOrThrow( + method = HttpMethod.DELETE, + path = "/schedules/$scheduleId", + ) + } + /** * Local * */ diff --git a/domain/src/commonMain/kotlin/com/ondot/domain/repository/ScheduleRepository.kt b/domain/src/commonMain/kotlin/com/ondot/domain/repository/ScheduleRepository.kt index 87700847..d2984b7f 100644 --- a/domain/src/commonMain/kotlin/com/ondot/domain/repository/ScheduleRepository.kt +++ b/domain/src/commonMain/kotlin/com/ondot/domain/repository/ScheduleRepository.kt @@ -48,6 +48,8 @@ interface ScheduleRepository { isEnabled: Boolean, ): AppResult + suspend fun deleteScheduleAppResult(scheduleId: Long): AppResult + /** * Local * */ From 1b0ce4e53b633510b11d28e0229cb5e401d8620c Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:23:12 +0900 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=BA=98=EB=A6=B0?= =?UTF-8?q?=EB=8D=94=20=EB=B0=94=ED=85=80=EC=8B=9C=ED=8A=B8=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9D=BC=EC=A0=95=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ondot/calendar/contract/CalendarIntent.kt | 1 + .../calendar/contract/CalendarViewModel.kt | 74 ++++++++++++++++++- .../com/ondot/calendar/ui/CalendarScreen.kt | 4 +- .../ui/component/CalendarBottomSheet.kt | 4 +- .../calendar/ui/component/CalendarDay.kt | 2 +- 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarIntent.kt b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarIntent.kt index e5d074ae..521d5f8c 100644 --- a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarIntent.kt +++ b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarIntent.kt @@ -21,5 +21,6 @@ sealed interface CalendarIntent : Intent { data class DeleteHistory( val scheduleId: Long, + val isPast: Boolean, ) : CalendarIntent } diff --git a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt index a37a1d41..0568712f 100644 --- a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt +++ b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt @@ -2,6 +2,7 @@ package com.ondot.calendar.contract import androidx.lifecycle.viewModelScope import com.dh.ondot.presentation.ui.theme.ERROR_GET_SCHEDULE_LIST +import com.dh.ondot.presentation.ui.theme.SUCCESS_DELETE_SCHEDULE import com.ondot.domain.model.enums.AlarmType import com.ondot.domain.model.enums.MapProvider import com.ondot.domain.model.enums.ToastType @@ -101,7 +102,13 @@ class CalendarViewModel( observeMapProvider() } - is CalendarIntent.DeleteHistory -> deleteHistory(intent.scheduleId) + is CalendarIntent.DeleteHistory -> { + if (intent.isPast) { + deleteHistory(intent.scheduleId) + } else { + deleteSchedule(intent.scheduleId) + } + } } } @@ -373,6 +380,71 @@ class CalendarViewModel( ) } + // --------------------------------------------일정 삭제------------------------------------------------ + + private fun deleteSchedule(scheduleId: Long) { + val selectedDate = currentState.selectedDate + val previousSchedules = currentState.selectedDateSchedules + val previousItems = currentState.selectedDateScheduleItems + val previousSchedulesByDate = currentState.schedulesByDate + + val targetSchedule = + previousSchedules.firstOrNull { it.scheduleId == scheduleId } + ?: run { + logger.e { "일정을 찾을 수 없습니다. $scheduleId" } + return + } + + val updatedSchedules = previousSchedules.filter { it.scheduleId != scheduleId } + val updatedItems = previousItems.filter { it.scheduleId != scheduleId } + + val previousMarkers = previousSchedulesByDate[selectedDate].orEmpty() + val updatedMarkers = previousMarkers.filter { it.scheduleId != scheduleId } + + val updatedSchedulesByDate = + previousSchedulesByDate.toMutableMap().apply { + if (updatedMarkers.isEmpty()) { + remove(selectedDate) + } else { + this[selectedDate] = updatedMarkers + } + } + + cancelScheduleAlarms(targetSchedule) + + reduce { + copy( + selectedDateSchedules = updatedSchedules, + selectedDateScheduleItems = updatedItems, + schedulesByDate = updatedSchedulesByDate, + ) + } + + launchResult( + block = { scheduleRepository.deleteScheduleAppResult(scheduleId) }, + onSuccess = { + emitEffect(CalendarSideEffect.ShowToast(SUCCESS_DELETE_SCHEDULE, ToastType.INFO)) + }, + onError = { + applySchedules( + date = selectedDate, + schedules = previousSchedules, + ) + + reduce { + copy( + schedulesByDate = previousSchedulesByDate, + ) + } + + applyAlarmLocally( + schedule = targetSchedule, + enabled = targetSchedule.hasActiveAlarm, + ) + }, + ) + } + /**--------------------------------------------기타 유틸-----------------------------------------------*/ private fun prepInfo(schedule: Schedule) = diff --git a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/CalendarScreen.kt b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/CalendarScreen.kt index 5969a302..be2740f0 100644 --- a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/CalendarScreen.kt +++ b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/CalendarScreen.kt @@ -85,7 +85,7 @@ fun CalendarRoute( onMoveToNextMonth = { viewModel.dispatch(CalendarIntent.MoveToNextMonth) }, onToggleAlarm = { scheduleId, enabled -> viewModel.dispatch(CalendarIntent.ToggleAlarm(scheduleId, enabled)) }, onAddSchedule = navigateToCreateGeneralSchedule, - onDelete = { viewModel.dispatch(CalendarIntent.DeleteHistory(it)) }, + onDelete = { id, isPast -> viewModel.dispatch(CalendarIntent.DeleteHistory(id, isPast)) }, ) } @@ -97,7 +97,7 @@ private fun CalendarScreen( onMoveToNextMonth: () -> Unit, onToggleAlarm: (Long, Boolean) -> Unit, onAddSchedule: () -> Unit, - onDelete: (Long) -> Unit, + onDelete: (Long, Boolean) -> Unit, ) { val scope = rememberCoroutineScope() val sheetState = rememberCalendarSheetState() diff --git a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarBottomSheet.kt b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarBottomSheet.kt index 7eb6115b..e38836cb 100644 --- a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarBottomSheet.kt +++ b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarBottomSheet.kt @@ -51,7 +51,7 @@ fun CalendarBottomSheet( schedules: List, togglingScheduleIds: Set = emptySet(), onToggleAlarm: (Long, Boolean) -> Unit = { _, _ -> }, - onDelete: (Long) -> Unit = {}, + onDelete: (Long, Boolean) -> Unit = { _, _ -> }, ) { Surface( modifier = modifier, @@ -123,7 +123,7 @@ fun CalendarBottomSheet( schedules.forEach { item -> SwipeableDeleteItem( enabled = item.isPast, - onDelete = { onDelete(item.scheduleId) }, + onDelete = { onDelete(item.scheduleId, item.isPast) }, ) { CalendarScheduleListItem( item = item, diff --git a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarDay.kt b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarDay.kt index 05d92fcd..2195c904 100644 --- a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarDay.kt +++ b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/ui/component/CalendarDay.kt @@ -106,7 +106,7 @@ fun CalendarDay( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(3.dp), ) { - cell.markers.take(2).forEach { marker -> + cell.markers.take(3).forEach { marker -> ScheduleChip( text = marker.title, ) From 7d4e83e44b27e2f4c0f5fb946bc0f13f0b5bbd6e Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:23:32 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B8=B0=EC=A1=B4?= =?UTF-8?q?=20=EC=95=8C=EB=9E=8C=20=EC=9D=BC=EA=B4=84=20=EC=B7=A8=EC=86=8C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commonMain/kotlin/com/ondot/edit/EditScheduleViewModel.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feature/edit/src/commonMain/kotlin/com/ondot/edit/EditScheduleViewModel.kt b/feature/edit/src/commonMain/kotlin/com/ondot/edit/EditScheduleViewModel.kt index da40a201..6a324fe8 100644 --- a/feature/edit/src/commonMain/kotlin/com/ondot/edit/EditScheduleViewModel.kt +++ b/feature/edit/src/commonMain/kotlin/com/ondot/edit/EditScheduleViewModel.kt @@ -63,6 +63,7 @@ class EditScheduleViewModel( @OptIn(ExperimentalTime::class) fun saveSchedule() { + // 새로 설정된 약속 날짜, 시간을 조합한 Iso8601 문자열 val newDate = DateTimeFormatter.formatIsoDateTime( date = @@ -82,7 +83,8 @@ class EditScheduleViewModel( .map { it + 1 }, ) - if (!newSchedule.preparationAlarm.enabled) cancelAlarm(newSchedule.preparationAlarm.alarmId) + // 변경된 데이터가 있을 수 있으므로 기존 알람 취소 + cancelAlarms() viewModelScope.launch { scheduleRepository.editSchedule(uiState.value.scheduleId, newSchedule).collect { From b8d8178246f141d13a08920fb9dde5f2097d09df Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:24:06 +0900 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=94=A5=20Remove:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20UI=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../general/check/CheckScheduleScreen.kt | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/feature/general/src/commonMain/kotlin/com/ondot/general/check/CheckScheduleScreen.kt b/feature/general/src/commonMain/kotlin/com/ondot/general/check/CheckScheduleScreen.kt index 05d17c90..dc5bd54d 100644 --- a/feature/general/src/commonMain/kotlin/com/ondot/general/check/CheckScheduleScreen.kt +++ b/feature/general/src/commonMain/kotlin/com/ondot/general/check/CheckScheduleScreen.kt @@ -41,7 +41,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.dh.ondot.presentation.ui.theme.ANDROID import com.dh.ondot.presentation.ui.theme.CREATE_SCHEDULE import com.dh.ondot.presentation.ui.theme.GENERAL_SCHEDULE_BOTTOM_SHEET_MATERIAL -import com.dh.ondot.presentation.ui.theme.GENERAL_SCHEDULE_BOTTOM_SHEET_MEDICINE import com.dh.ondot.presentation.ui.theme.GENERAL_SCHEDULE_BOTTOM_SHEET_TITLE import com.dh.ondot.presentation.ui.theme.OnDotTypo import com.dh.ondot.presentation.ui.theme.WORD_CONFIRM @@ -50,7 +49,6 @@ import com.ondot.designsystem.components.AlarmInfoItem import com.ondot.designsystem.components.DateTimeInfoBar import com.ondot.designsystem.components.OnDotBottomSheet import com.ondot.designsystem.components.OnDotButton -import com.ondot.designsystem.components.OnDotCheckBox import com.ondot.designsystem.components.OnDotText import com.ondot.designsystem.components.RoundedTextField import com.ondot.designsystem.components.RouteInputSection @@ -58,7 +56,6 @@ import com.ondot.designsystem.components.TopBar import com.ondot.designsystem.getPlatform import com.ondot.designsystem.theme.OnDotColor.GradientGreenTop import com.ondot.designsystem.theme.OnDotColor.Gray0 -import com.ondot.designsystem.theme.OnDotColor.Gray200 import com.ondot.designsystem.theme.OnDotColor.Gray600 import com.ondot.designsystem.theme.OnDotColor.Gray800 import com.ondot.designsystem.theme.OnDotColor.Gray900 @@ -230,27 +227,6 @@ private fun BottomSheetContent(onCreateSchedule: (Boolean, String) -> Unit) { Spacer(modifier = Modifier.height(20.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - ) { - OnDotCheckBox( - isChecked = isMedicineChecked, - onCheckedChange = { isMedicineChecked = !isMedicineChecked }, - ) - - Spacer(modifier = Modifier.width(8.dp)) - - OnDotText( - text = GENERAL_SCHEDULE_BOTTOM_SHEET_MEDICINE, - style = OnDotTextStyle.BodyLargeR1, - color = Gray200, - modifier = Modifier.clickable { isMedicineChecked = !isMedicineChecked }, - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - RoundedTextField( value = input, onValueChange = { input = it }, From 699fba00b94cd844b9d83fbb23d71d367fac0102 Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:34:20 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20FakeReposi?= =?UTF-8?q?tory=20=EB=AF=B8=EA=B5=AC=ED=98=84=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/ondot/testing/fake/FakeScheduleRepository.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/domain/testing/src/commonMain/kotlin/com/ondot/testing/fake/FakeScheduleRepository.kt b/domain/testing/src/commonMain/kotlin/com/ondot/testing/fake/FakeScheduleRepository.kt index 392cd488..7dc2de65 100644 --- a/domain/testing/src/commonMain/kotlin/com/ondot/testing/fake/FakeScheduleRepository.kt +++ b/domain/testing/src/commonMain/kotlin/com/ondot/testing/fake/FakeScheduleRepository.kt @@ -159,6 +159,10 @@ class FakeScheduleRepository : ScheduleRepository { TODO("Not yet implemented") } + override suspend fun deleteScheduleAppResult(scheduleId: Long): AppResult { + TODO("Not yet implemented") + } + override suspend fun getLocalScheduleById(scheduleId: Long): Flow = flow { emit(scheduleMap[scheduleId]) From 8bb0efa7bb2287e8874cf7d4935e4ad527e013d7 Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:35:57 +0900 Subject: [PATCH 7/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20KDoc=20?= =?UTF-8?q?=ED=91=9C=EC=A4=80=20=EB=AC=B8=EB=B2=95=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt b/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt index abdf8050..b942cb2b 100644 --- a/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt +++ b/core/util/src/commonMain/kotlin/com/ondot/util/DateTimeFormatter.kt @@ -326,9 +326,9 @@ object DateTimeFormatter { fun LocalTime.toIsoTimeString(): String = "${hour.pad2()}:${minute.pad2()}:${second.pad2()}" /** - * @param: date 선택된 날짜 - * @param: time 선택된 시간 - * @return: LocalDate, LocalTime을 조합한 ISO8601 문자열 + * `@param` date 선택된 날짜 + * `@param` time 선택된 시간 + * `@return` LocalDate, LocalTime을 조합한 ISO8601 문자열 * */ fun formatIsoDateTime( date: LocalDate, From 0a0062be4b8b5482428867e7132ccd99eb49cadf Mon Sep 17 00:00:00 2001 From: dogmania Date: Sun, 12 Apr 2026 21:42:40 +0900 Subject: [PATCH 8/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20=EB=A1=A4=EB=B0=B1?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/contract/CalendarViewModel.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt index 0568712f..4bd6dab9 100644 --- a/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt +++ b/feature/calendar/src/commonMain/kotlin/com/ondot/calendar/contract/CalendarViewModel.kt @@ -398,15 +398,15 @@ class CalendarViewModel( val updatedSchedules = previousSchedules.filter { it.scheduleId != scheduleId } val updatedItems = previousItems.filter { it.scheduleId != scheduleId } - val previousMarkers = previousSchedulesByDate[selectedDate].orEmpty() - val updatedMarkers = previousMarkers.filter { it.scheduleId != scheduleId } + val previousMarkersForDate = previousSchedulesByDate[selectedDate].orEmpty() + val updatedMarkersForDate = previousMarkersForDate.filter { it.scheduleId != scheduleId } val updatedSchedulesByDate = previousSchedulesByDate.toMutableMap().apply { - if (updatedMarkers.isEmpty()) { + if (updatedMarkersForDate.isEmpty()) { remove(selectedDate) } else { - this[selectedDate] = updatedMarkers + this[selectedDate] = updatedMarkersForDate } } @@ -431,9 +431,18 @@ class CalendarViewModel( schedules = previousSchedules, ) + val rolledBackSchedulesByDate = + currentState.schedulesByDate.toMutableMap().apply { + if (previousMarkersForDate.isEmpty()) { + remove(selectedDate) + } else { + this[selectedDate] = previousMarkersForDate + } + } + reduce { copy( - schedulesByDate = previousSchedulesByDate, + schedulesByDate = rolledBackSchedulesByDate, ) }