DRY pass #2, batch 6, F19: Banner, the tinted strip (#5372)

ErrorBanner.kt Banner(tintKey) { … } is the rounded, palette-tinted row
that ErrorBanner (red) and UpdateBanner (blue) each built. TintChip moves
to Chips.kt with CHIP_RADIUS, which keeps NoteCard.kt under detekt's
function count. Checked with ktlint and detekt in the CI image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 14:57:25 -04:00
co-authored by Claude Opus 5.5
parent 7ee4fed246
commit f46dd7a707
4 changed files with 61 additions and 50 deletions
@@ -0,0 +1,38 @@
package com.fabledsword.inkwell.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
/** The corner of every chip on a card: tags, reminders, who shared it. */
internal val CHIP_RADIUS = 6.dp
/** A one-line chip on a card, in the chip colours of the palette entry [tintKey]. */
@Composable
internal fun TintChip(
text: String,
tintKey: String,
) {
val dark = isSystemInDarkTheme()
val tint = noteTint(tintKey)
Text(
text = text,
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),
)
}
@@ -4,6 +4,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
@@ -28,9 +29,28 @@ import com.fabledsword.inkwell.R
fun ErrorBanner( fun ErrorBanner(
message: String, message: String,
onDismiss: () -> Unit, onDismiss: () -> Unit,
) {
Banner("red") {
Text(
text = message,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(1f),
)
TextButton(onClick = onDismiss) { Text(stringResource(R.string.error_dismiss)) }
}
}
/**
* A strip across the top of a screen, tinted from the note palette by [tintKey]: a
* message on the left and what can be done about it on the right.
*/
@Composable
fun Banner(
tintKey: String,
content: @Composable RowScope.() -> Unit,
) { ) {
val dark = isSystemInDarkTheme() val dark = isSystemInDarkTheme()
val tint = noteTint("red") val tint = noteTint(tintKey)
Row( Row(
modifier = modifier =
Modifier Modifier
@@ -42,12 +62,7 @@ fun ErrorBanner(
.padding(start = 12.dp), .padding(start = 12.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
Text( content()
text = message,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(1f),
)
TextButton(onClick = onDismiss) { Text(stringResource(R.string.error_dismiss)) }
} }
} }
@@ -444,28 +444,6 @@ private fun SharedChip(note: Note) {
TintChip(text, "default") 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,
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),
)
}
/** A box that does nothing when tapped: someone else's note, shared to view. */ /** A box that does nothing when tapped: someone else's note, shared to view. */
private val INERT_TOGGLE: (Int, Boolean) -> Unit = { _, _ -> } private val INERT_TOGGLE: (Int, Boolean) -> Unit = { _, _ -> }
@@ -539,4 +517,3 @@ private val CARD_SURFACE_DARK = Color(0xFF171717)
// surfaces stay the same card. Contrast: #B8B8B8 on white 1.98, #404040 on #171717 1.73. // surfaces stay the same card. Contrast: #B8B8B8 on white 1.98, #404040 on #171717 1.73.
private val CARD_EDGE_LIGHT = Color(0xFFB8B8B8) private val CARD_EDGE_LIGHT = Color(0xFFB8B8B8)
private val CARD_EDGE_DARK = Color(0xFF404040) private val CARD_EDGE_DARK = Color(0xFF404040)
private val CHIP_RADIUS = 6.dp
@@ -1,8 +1,5 @@
package com.fabledsword.inkwell.ui package com.fabledsword.inkwell.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -10,7 +7,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
@@ -23,9 +19,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -152,19 +146,7 @@ fun UpdateBanner(
onInstall: () -> Unit, onInstall: () -> Unit,
onDismiss: () -> Unit, onDismiss: () -> Unit,
) { ) {
val dark = isSystemInDarkTheme() Banner("blue") {
val tint = noteTint("blue")
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 4.dp)
.clip(RoundedCornerShape(BANNER_RADIUS))
.background(tint.background(dark))
.border(1.dp, tint.border(dark), RoundedCornerShape(BANNER_RADIUS))
.padding(start = 12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text( Text(
text = stringResource(R.string.update_banner_ready, version), text = stringResource(R.string.update_banner_ready, version),
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
@@ -180,7 +162,6 @@ fun UpdateBanner(
} }
} }
private val BANNER_RADIUS = 12.dp
private val BANNER_SPINNER = 18.dp private val BANNER_SPINNER = 18.dp
/** /**