DRY pass #2, batch 6, F19: TitleAndBody, TintChip and Swatch (#5372)

- BoardScreen TitleAndBody: the title plus quieter body that the empty
  board and the store-unavailable screen each wrote.
- NoteCard TintChip: the one-line palette chip that the reminder and
  shared-by chips each drew in full.
- TagsScreen Swatch: the colour dot that the tag row (tappable) and the
  colour picker each built.

Kept: the label chips. Each uses its tag's ink and a bigger shape, not
the card's chip pair. Checked with ktlint in the CI image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 14:56:18 -04:00
co-authored by Claude Opus 5.5
parent 4a810df0a9
commit 9b8c9474bc
3 changed files with 51 additions and 49 deletions
@@ -641,13 +641,7 @@ private fun EmptyBoard(state: BoardState) {
) {
item {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = title, style = MaterialTheme.typography.titleMedium)
Spacer(Modifier.height(8.dp))
Text(
text = body,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
TitleAndBody(title, body)
}
}
}
@@ -677,19 +671,28 @@ fun StoreUnavailableScreen(reason: String?) {
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(
text = stringResource(R.string.store_unavailable_title),
style = MaterialTheme.typography.titleMedium,
)
Spacer(Modifier.height(8.dp))
Text(
text = reason ?: stringResource(R.string.store_unavailable_body),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
TitleAndBody(
title = stringResource(R.string.store_unavailable_title),
body = reason ?: stringResource(R.string.store_unavailable_body),
)
}
}
/** A whole-screen message: what is the case, then what it means, in the quieter ink. */
@Composable
private fun TitleAndBody(
title: String,
body: String,
) {
Text(text = title, style = MaterialTheme.typography.titleMedium)
Spacer(Modifier.height(8.dp))
Text(
text = body,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
// Not private: the reminder notice is board content and has to line up with the
// search bar and the cards, so it shares the board's gutter rather than guessing.
internal val GUTTER = 12.dp
@@ -424,20 +424,7 @@ private fun ReminderChip(
instant: String,
recurrence: String?,
) {
val dark = isSystemInDarkTheme()
val tint = noteTint(if (isPast(instant)) "red" else "default")
Text(
text = reminderLabel(instant, recurrence),
style = MaterialTheme.typography.labelSmall,
color = tint.chipForeground(dark),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier =
Modifier
.clip(RoundedCornerShape(CHIP_RADIUS))
.background(tint.chipBackground(dark))
.padding(horizontal = 6.dp, vertical = 2.dp),
)
TintChip(reminderLabel(instant, recurrence), if (isPast(instant)) "red" else "default")
}
/**
@@ -453,9 +440,18 @@ private fun SharedChip(note: Note) {
note.shared -> stringResource(R.string.share_chip_shared)
else -> return
}
val dark = isSystemInDarkTheme()
val tint = noteTint("default")
Spacer(Modifier.height(8.dp))
TintChip(text, "default")
}
/** A one-line chip on a card, in the chip colours of the palette entry [tintKey]. */
@Composable
private fun TintChip(
text: String,
tintKey: String,
) {
val dark = isSystemInDarkTheme()
val tint = noteTint(tintKey)
Text(
text = text,
style = MaterialTheme.typography.labelSmall,
@@ -235,6 +235,24 @@ fun TagsScreen(
*/
internal fun hashtag(name: String): String = "#$name"
/** A tag's colour as a dot: the row's at-a-glance colour, and each choice in the picker. */
@Composable
private fun Swatch(
tint: NoteTint,
dark: Boolean,
modifier: Modifier = Modifier,
) {
Box(
modifier =
Modifier
.size(SWATCH)
.clip(CircleShape)
.background(tint.chipBackground(dark))
.border(1.dp, tint.chipBorder(dark), CircleShape)
.then(modifier),
)
}
@Composable
private fun NewTagField(
enabled: Boolean,
@@ -313,15 +331,7 @@ private fun TagRow(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Box(
modifier =
Modifier
.size(SWATCH)
.clip(CircleShape)
.background(tint.chipBackground(dark))
.border(1.dp, tint.chipBorder(dark), CircleShape)
.clickable(enabled = enabled, onClick = onColour),
)
Swatch(tint, dark, Modifier.clickable(enabled = enabled, onClick = onColour))
Column(modifier = Modifier.weight(1f)) {
Text(
@@ -512,14 +522,7 @@ private fun ColourDialog(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Box(
modifier =
Modifier
.size(SWATCH)
.clip(CircleShape)
.background(tint.chipBackground(dark))
.border(1.dp, tint.chipBorder(dark), CircleShape),
)
Swatch(tint, dark)
Text(
text = tint.label,
style = MaterialTheme.typography.bodyMedium,