refactor: route ad-hoc status colors through existing semantic tokens

Status telemetry (broadcast result, relay latency ping, memory heap gauge)
hardcoded its own greens/ambers/reds instead of using the app's existing
semantic tokens, so the same "success"/"warning" meaning drifted across a
handful of near-identical shades.

Route them onto the tokens already used everywhere else for that meaning:
green -> allGoodColor, amber -> warningColor, the fixed critical red ->
colorScheme.error. Also point OtsSettingsSection's re-hardcoded #F7931A at the
shared BitcoinOrange constant. No new colors introduced.

Brand/categorical palettes (git diff, crypto brands, road-event categories,
chess, call UI, live-red indicators, medals) are intentionally left as-is —
they are meaning-carrying and unique by design.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D1F9jXNwRGTP8qmsV3Wd69
This commit is contained in:
Claude
2026-07-16 20:51:32 +00:00
parent ec466d8bc0
commit abdb3be021
6 changed files with 31 additions and 27 deletions
@@ -58,7 +58,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.text.style.TextOverflow
@@ -78,6 +77,8 @@ import com.vitorpamplona.amethyst.service.pow.formatTimeLeft
import com.vitorpamplona.amethyst.service.pow.powKindLabelRes
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.ui.theme.warningColor
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
@@ -440,8 +441,8 @@ fun CompletedBroadcastContent(
modifier = Modifier.fillMaxWidth(),
) {
// Status colors (for icon tint only)
val successColor = Color(0xFF22C55E)
val warningColor = Color(0xFFF59E0B)
val successColor = MaterialTheme.colorScheme.allGoodColor
val warningColor = MaterialTheme.colorScheme.warningColor
val (statusIcon, iconTint) =
when (broadcast.status) {
@@ -530,8 +531,8 @@ fun MultipleCompletedBroadcastContent(
modifier = Modifier.fillMaxWidth(),
) {
// Status colors (for icon tint only)
val successColor = Color(0xFF22C55E)
val warningColor = Color(0xFFF59E0B)
val successColor = MaterialTheme.colorScheme.allGoodColor
val warningColor = MaterialTheme.colorScheme.warningColor
val totalRelayCount = broadcasts.sumOf { it.totalRelays }
val failedRelayCount = broadcasts.sumOf { it.failedRelays.size }
@@ -77,6 +77,8 @@ import com.vitorpamplona.amethyst.commons.service.broadcast.BroadcastStatus
import com.vitorpamplona.amethyst.commons.service.broadcast.RelayResult
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.ui.theme.warningColor
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
@@ -299,8 +301,8 @@ private fun BroadcastSection(
@Composable
private fun statusColor(status: BroadcastStatus): Color =
when (status) {
BroadcastStatus.SUCCESS -> Color(0xFF22C55E)
BroadcastStatus.PARTIAL -> Color(0xFFF59E0B)
BroadcastStatus.SUCCESS -> MaterialTheme.colorScheme.allGoodColor
BroadcastStatus.PARTIAL -> MaterialTheme.colorScheme.warningColor
BroadcastStatus.FAILED -> MaterialTheme.colorScheme.error
BroadcastStatus.IN_PROGRESS -> MaterialTheme.colorScheme.primary
}
@@ -312,8 +314,8 @@ private fun StatusIcon(
) {
val (icon, tint, shouldRotate) =
when (status) {
BroadcastStatus.SUCCESS -> Triple(MaterialSymbols.CheckCircle, Color(0xFF22C55E), false)
BroadcastStatus.PARTIAL -> Triple(MaterialSymbols.Error, Color(0xFFF59E0B), false)
BroadcastStatus.SUCCESS -> Triple(MaterialSymbols.CheckCircle, MaterialTheme.colorScheme.allGoodColor, false)
BroadcastStatus.PARTIAL -> Triple(MaterialSymbols.Error, MaterialTheme.colorScheme.warningColor, false)
BroadcastStatus.FAILED -> Triple(MaterialSymbols.Error, MaterialTheme.colorScheme.error, false)
BroadcastStatus.IN_PROGRESS -> Triple(MaterialSymbols.HourglassEmpty, MaterialTheme.colorScheme.primary, true)
}
@@ -342,9 +344,9 @@ private fun RelayResultRow(
onRetry: () -> Unit,
rotationAngle: Float = 0f,
) {
val successColor = Color(0xFF22C55E)
val successColor = MaterialTheme.colorScheme.allGoodColor
val errorColor = MaterialTheme.colorScheme.error
val warningColor = Color(0xFFF59E0B)
val warningColor = MaterialTheme.colorScheme.warningColor
Row(
modifier =
@@ -38,7 +38,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@@ -52,6 +51,8 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.ui.theme.warningColor
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
import com.vitorpamplona.quartz.nip66RelayMonitor.discovery.RelayDiscoveryEvent
@@ -215,8 +216,8 @@ private fun RttMetricChip(
) {
val color =
when {
ms < 200 -> Color(0xFF4CAF50)
ms < 500 -> Color(0xFFFFC107)
ms < 200 -> MaterialTheme.colorScheme.allGoodColor
ms < 500 -> MaterialTheme.colorScheme.warningColor
else -> MaterialTheme.colorScheme.error
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
@@ -107,8 +107,10 @@ import com.vitorpamplona.amethyst.ui.theme.SpacedBy10dp
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.ui.theme.bitcoinColor
import com.vitorpamplona.amethyst.ui.theme.redColorOnSecondSurface
import com.vitorpamplona.amethyst.ui.theme.warningColor
import com.vitorpamplona.quartz.kinds.KindNames
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.stats.ErrorDebugMessage
@@ -1437,12 +1439,8 @@ private fun RttChip(
) {
val color =
when {
ms < 200 -> Color(0xFF4CAF50)
// green
ms < 500 -> Color(0xFFFFC107)
// amber
ms < 200 -> MaterialTheme.colorScheme.allGoodColor
ms < 500 -> MaterialTheme.colorScheme.warningColor
else -> MaterialTheme.colorScheme.error
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
@@ -48,7 +48,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
@@ -60,6 +59,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
import com.vitorpamplona.amethyst.model.nip03Timestamp.OtsSettings
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.quartz.nip03Timestamp.okhttp.OkHttpBitcoinExplorer
/**
@@ -149,7 +149,7 @@ private fun SectionHeaderOts() {
Icon(
MaterialSymbols.Search,
contentDescription = null,
tint = Color(0xFFF7931A), // Bitcoin orange
tint = BitcoinOrange,
modifier = Modifier.size(22.dp),
)
Spacer(Modifier.width(10.dp))
@@ -194,11 +194,11 @@ private fun ActiveExplorerDisplay(
"CUSTOM",
style = MaterialTheme.typography.labelSmall,
fontWeight = FontWeight.Bold,
color = Color(0xFFF7931A),
color = BitcoinOrange,
modifier =
Modifier
.background(
Color(0xFFF7931A).copy(alpha = 0.1f),
BitcoinOrange.copy(alpha = 0.1f),
RoundedCornerShape(4.dp),
).padding(horizontal = 6.dp, vertical = 2.dp),
)
@@ -73,6 +73,8 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.routeToMessage
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.ui.theme.warningColor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
@@ -447,9 +449,9 @@ private fun MemorySection(memory: MemorySnapshot?) {
if (memory == null) return
val heapColor =
when {
memory.heapFraction > 0.80f -> Color(0xFFE53935)
memory.heapFraction > 0.60f -> Color(0xFFFFA000)
else -> Color(0xFF43A047)
memory.heapFraction > 0.80f -> MaterialTheme.colorScheme.error
memory.heapFraction > 0.60f -> MaterialTheme.colorScheme.warningColor
else -> MaterialTheme.colorScheme.allGoodColor
}
SettingsSection(R.string.resource_usage_memory_section) {
BarRow(