diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableItem.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableItem.kt index 0bcdb5cb9..53f0740c6 100644 --- a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableItem.kt +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableItem.kt @@ -7,6 +7,7 @@ import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.LocalTime import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant import kotlinx.datetime.toLocalDateTime @@ -78,6 +79,14 @@ public sealed class TimetableItem { endsAt.toTimetableTimeString() } + public val startsLocalTime: LocalTime by lazy { + startsAt.toLocalTime() + } + + public val endsLocalTime: LocalTime by lazy { + endsAt.toLocalTime() + } + private val minutesString: String by lazy { val minutes = (endsAt - startsAt) .toComponents { minutes, _, _ -> minutes } @@ -119,11 +128,16 @@ public sealed class TimetableItem { } } -public fun Instant.toTimetableTimeString(): String { +private fun Instant.toTimetableTimeString(): String { val localDate = toLocalDateTime(TimeZone.currentSystemDefault()) return "${localDate.hour}".padStart(2, '0') + ":" + "${localDate.minute}".padStart(2, '0') } +private fun Instant.toLocalTime(): LocalTime { + val localDateTime = toLocalDateTime(TimeZone.currentSystemDefault()) + return localDateTime.time +} + public fun Session.Companion.fake(): Session { return Session( id = TimetableItemId("2"), diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt index 546fe08f3..f5613eb06 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/SearchScreenPresenter.kt @@ -174,8 +174,8 @@ fun searchScreenPresenter( timetableListUiState = TimetableListUiState( timetableItemMap = filteredSessions.groupBy { TimetableListUiState.TimeSlot( - startTime = it.startsAt, - endTime = it.endsAt, + startTime = it.startsLocalTime, + endTime = it.endsLocalTime, ) }.mapValues { entries -> entries.value.sortedWith( diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt index 4c8067377..574eb4970 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/TimetableScreenPresenter.kt @@ -101,8 +101,8 @@ fun timetableSheet( ), ).timetableItems.groupBy { TimetableListUiState.TimeSlot( - startTime = it.startsAt, - endTime = it.endsAt, + startTime = it.startsLocalTime, + endTime = it.endsLocalTime, ) }.mapValues { entries -> entries.value.sortedWith( diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt index abbfacade..82f486158 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt @@ -45,7 +45,6 @@ import io.github.droidkaigi.confsched.droidkaigiui.compositionlocal.LocalSharedT import io.github.droidkaigi.confsched.droidkaigiui.icon import io.github.droidkaigi.confsched.model.Timetable import io.github.droidkaigi.confsched.model.TimetableItem -import io.github.droidkaigi.confsched.model.toTimetableTimeString import io.github.droidkaigi.confsched.sessions.component.TimetableNestedScrollStateHolder import io.github.droidkaigi.confsched.sessions.component.rememberTimetableNestedScrollConnection import io.github.droidkaigi.confsched.sessions.component.rememberTimetableNestedScrollStateHolder @@ -54,11 +53,9 @@ import io.github.droidkaigi.confsched.sessions.timetableDetailSharedContentState import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.toImmutableSet -import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.Instant +import kotlinx.datetime.LocalTime import kotlinx.datetime.TimeZone -import kotlinx.datetime.atStartOfDayIn -import kotlinx.datetime.plus import kotlinx.datetime.toLocalDateTime const val TimetableListTestTag = "TimetableList" @@ -68,10 +65,17 @@ data class TimetableListUiState( val timetable: Timetable, ) { data class TimeSlot( - val startTime: Instant, - val endTime: Instant, + val startTime: LocalTime, + val endTime: LocalTime, ) { + val startTimeString: String get() = startTime.toTimetableTimeString() + val endTimeString: String get() = endTime.toTimetableTimeString() + val key: String get() = "$startTime-$endTime" + + private fun LocalTime.toTimetableTimeString(): String { + return "$hour".padStart(2, '0') + ":" + "$minute".padStart(2, '0') + } } } @@ -112,7 +116,7 @@ internal fun TimetableList( val progressingSessionIndex = uiState.timetableItemMap.keys .insertDummyEndOfTheDayItem() // Insert dummy at a position after last session to allow scrolling .windowed(2, 1, true) - .indexOfFirst { clock.now() in it.first().startTime..it.last().startTime } + .indexOfFirst { clock.now().toLocalTime() in it.first().startTime..it.last().startTime } progressingSessionIndex.takeIf { it != -1 }?.let { scrollState.scrollToItem(it) @@ -165,8 +169,8 @@ internal fun TimetableList( timeTextHeight = it.size.height } .offset { IntOffset(0, timeTextOffset) }, - startTime = time.startTime.toTimetableTimeString(), - endTime = time.endTime.toTimetableTimeString(), + startTime = time.startTimeString, + endTime = time.endTimeString, ) Spacer(modifier = Modifier.width(12.dp)) Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { @@ -230,10 +234,7 @@ internal fun TimetableList( } private fun ImmutableSet.insertDummyEndOfTheDayItem(): ImmutableSet { - val endOfTheDayInstant = first().startTime.toLocalDateTime(TimeZone.currentSystemDefault()) - .date - .plus(1, DateTimeUnit.DAY) - .atStartOfDayIn(TimeZone.currentSystemDefault()) + val endOfTheDayInstant = LocalTime(23, 59, 59) return plus( TimeSlot( startTime = endOfTheDayInstant, @@ -241,3 +242,8 @@ private fun ImmutableSet.insertDummyEndOfTheDayItem(): ImmutableSet