Merge pull request 'fix(ui): Show event dates in card view' (#1) from fix/event-card-date-display into main
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Card
|
||||
@@ -35,6 +34,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ch.parano.myice.models.Event
|
||||
import ch.parano.myice.util.formatEventDateTime
|
||||
|
||||
@Composable
|
||||
fun EventCard(
|
||||
@@ -51,9 +51,7 @@ fun EventCard(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.height(120.dp),
|
||||
) {
|
||||
Row {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(4.dp)
|
||||
@@ -62,8 +60,7 @@ fun EventCard(
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.fillMaxHeight(),
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
@@ -83,7 +80,7 @@ fun EventCard(
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Text(
|
||||
text = "${event.start} - ${event.end}",
|
||||
text = formatEventDateTime(event.start, event.end),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// MyIce Kotlin Multiplatform — schedule/convocation viewer
|
||||
// Copyright (C) 2026 parano.ch
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package ch.parano.myice.util
|
||||
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
|
||||
private fun parseOrNull(iso: String): LocalDateTime? = runCatching {
|
||||
LocalDateTime.parse(iso)
|
||||
}.getOrNull()
|
||||
|
||||
private fun LocalDateTime.dateStr(): String =
|
||||
"${day.toString().padStart(2, '0')}.${monthNumber.toString().padStart(2, '0')}.${year.toString().padStart(4, '0')}"
|
||||
|
||||
private fun LocalDateTime.timeStr(): String =
|
||||
"${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}"
|
||||
|
||||
fun formatEventDateTime(start: String, end: String): String {
|
||||
val startDt = parseOrNull(start)
|
||||
val endDt = parseOrNull(end)
|
||||
if (startDt == null || endDt == null) return "$start - $end"
|
||||
return if (startDt.date == endDt.date) {
|
||||
"${startDt.dateStr()} ${startDt.timeStr()} - ${endDt.timeStr()}"
|
||||
} else {
|
||||
"${startDt.dateStr()} ${startDt.timeStr()} - ${endDt.timeStr()} (${endDt.dateStr()})"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// MyIce Kotlin Multiplatform — schedule/convocation viewer
|
||||
// Copyright (C) 2026 parano.ch
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package ch.parano.myice.util
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class EventDateTimeFormatterTest {
|
||||
|
||||
@Test
|
||||
fun formatsSameDayEventAsDateFollowedByTimeRange() {
|
||||
val formatted = formatEventDateTime(
|
||||
start = "2024-11-10T14:00:00",
|
||||
end = "2024-11-10T16:15:00",
|
||||
)
|
||||
assertEquals("10.11.2024 14:00 - 16:15", formatted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun formatsCrossingMidnightEventWithBothDates() {
|
||||
val formatted = formatEventDateTime(
|
||||
start = "2024-11-10T20:00:00",
|
||||
end = "2024-11-11T01:30:00",
|
||||
)
|
||||
assertEquals("10.11.2024 20:00 - 01:30 (11.11.2024)", formatted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsRawStartWhenStartUnparseable() {
|
||||
val formatted = formatEventDateTime(start = "s", end = "2024-11-10T16:15:00")
|
||||
assertEquals("s - 2024-11-10T16:15:00", formatted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsRawEndWhenEndUnparseable() {
|
||||
val formatted = formatEventDateTime(start = "2024-11-10T14:00:00", end = "e")
|
||||
assertEquals("2024-11-10T14:00:00 - e", formatted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsRawWhenBothUnparseable() {
|
||||
val formatted = formatEventDateTime(start = "s", end = "e")
|
||||
assertEquals("s - e", formatted)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user