Localise the untitled-event placeholder (#321)

This commit is contained in:
Jean-Luc Makiola
2026-09-23 22:30:46 +02:00
6 changed files with 14 additions and 12 deletions
@@ -21,8 +21,9 @@ internal fun ColumnReader.toEventInstance(): EventInstance? {
return null
}
val rawTitle = getString(InstanceProjection.IDX_TITLE)
val title = if (rawTitle.isNullOrEmpty()) Fallbacks.UNTITLED_EVENT else rawTitle
// Left blank when the event has no title: the placeholder is a display
// string, so it belongs to the UI layer where it can be localised (#321).
val title = getString(InstanceProjection.IDX_TITLE).orEmpty()
val color = if (isNull(InstanceProjection.IDX_EVENT_COLOR)) {
getInt(InstanceProjection.IDX_CALENDAR_COLOR)
@@ -315,5 +315,4 @@ internal object ReminderProjection {
internal object Fallbacks {
const val UNNAMED_CALENDAR = "(Unbenannter Kalender)"
const val UNTITLED_EVENT = "(Ohne Titel)"
}
@@ -21,8 +21,7 @@ internal fun ColumnReader.toSearchResult(): EventInstance? {
else -> dtStart + parseRfc2445DurationMillis(getString(SearchProjection.IDX_DURATION))
}.coerceAtLeast(dtStart)
val rawTitle = getString(SearchProjection.IDX_TITLE)
val title = if (rawTitle.isNullOrEmpty()) Fallbacks.UNTITLED_EVENT else rawTitle
val title = getString(SearchProjection.IDX_TITLE).orEmpty()
val color = if (isNull(SearchProjection.IDX_EVENT_COLOR)) {
getInt(SearchProjection.IDX_CALENDAR_COLOR)
} else {
@@ -509,6 +509,9 @@ private fun SearchResultRow(
onLongClick: (() -> Unit)? = null,
) {
val event = hit.event
// Spans are empty for a blank title — the query never matches the
// placeholder — so marking the substitute is safe.
val title = event.title.ifBlank { stringResource(R.string.event_untitled) }
val dark = isSystemInDarkTheme()
val soften = LocalSoftenColors.current
// On a picked row the headline is already recoloured for the secondary
@@ -521,7 +524,7 @@ private fun SearchResultRow(
// Faded like a past event anywhere else in the app — search reaches back
// through the whole history.
modifier = if (hit.isPast) modifier.alpha(EventDimAlpha) else modifier,
title = declinedTitle(marked(event.title, hit.titleSpans, highlight), event.isDeclined),
title = declinedTitle(marked(title, hit.titleSpans, highlight), event.isDeclined),
summary = searchSummary(hit, highlight),
position = position,
minHeight = 64.dp,
@@ -61,15 +61,15 @@ class InstanceMapperTest {
}
@Test
fun `null title falls back to placeholder`() {
fun `null title is left blank for the UI to fill in`() {
val inst = reader(title = null).toEventInstance()
assertThat(inst!!.title).isEqualTo(Fallbacks.UNTITLED_EVENT)
assertThat(inst!!.title).isEmpty()
}
@Test
fun `empty title falls back to placeholder`() {
fun `empty title is left blank for the UI to fill in`() {
val inst = reader(title = "").toEventInstance()
assertThat(inst!!.title).isEqualTo(Fallbacks.UNTITLED_EVENT)
assertThat(inst!!.title).isEmpty()
}
@Test
@@ -242,8 +242,8 @@ class EventSearchTest {
}
@Test
fun `an untitled event's placeholder is not something the query can match`() {
val untitled = candidate("(Ohne Titel)", description = "Titel folgt noch").copy(title = null)
fun `an untitled event's blank title is not something the query can match`() {
val untitled = candidate("", description = "Titel folgt noch").copy(title = null)
val results = search(untitled, query = "titel")