Compare commits

..

No commits in common. "b4c929eca234f01c82281c7f7bb31c104996dda3" and "7eac15374061fcb580dfd9c934ca245a139e2461" have entirely different histories.

5 changed files with 4 additions and 59 deletions

View file

@ -33,8 +33,8 @@ android {
targetSdk = 35 targetSdk = 35
// Bump both for every release installed on the phone — versionName for // Bump both for every release installed on the phone — versionName for
// humans, versionCode so dumpsys/install history can tell builds apart. // humans, versionCode so dumpsys/install history can tell builds apart.
versionCode = 4 versionCode = 3
versionName = "0.4.0" versionName = "0.3.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }

View file

@ -37,21 +37,11 @@ import java.time.format.DateTimeFormatter
import java.util.Locale import java.util.Locale
import no.naiv.meddetsamme.R import no.naiv.meddetsamme.R
import no.naiv.meddetsamme.data.DoseLog import no.naiv.meddetsamme.data.DoseLog
import no.naiv.meddetsamme.data.DoseStatus
import no.naiv.meddetsamme.data.MedDatabase import no.naiv.meddetsamme.data.MedDatabase
import no.naiv.meddetsamme.domain.ScheduleEngine import no.naiv.meddetsamme.domain.ScheduleEngine
private const val HISTORY_DAYS = 30L private const val HISTORY_DAYS = 30L
/**
* Status text in a *past* context. Differs from [label] only for PENDING: on
* the Today screen a due dose is legitimately "Venter", but a dose from days
* ago that was never acted on was simply not taken "Venter" there is the
* nonsense this screen used to show.
*/
private val DoseStatus.historyLabel: String
get() = if (this == DoseStatus.PENDING) "Ikke tatt" else label
/** /**
* Adherence history: the last 30 days of dose logs, newest first, with * Adherence history: the last 30 days of dose logs, newest first, with
* 7- and 30-day adherence percentages on top. Read-only corrections happen * 7- and 30-day adherence percentages on top. Read-only corrections happen
@ -140,36 +130,22 @@ fun HistoryScreen(nav: Nav) {
} }
items(dayLogs, key = { it.first.id }) { (log, medName) -> items(dayLogs, key = { it.first.id }) { (log, medName) ->
val time = timeFmt.format(Instant.ofEpochMilli(log.scheduledAtMillis).atZone(zone)) val time = timeFmt.format(Instant.ofEpochMilli(log.scheduledAtMillis).atZone(zone))
val taken = log.status == DoseStatus.TAKEN
Card( Card(
modifier = Modifier.fillMaxWidth().semantics(mergeDescendants = true) { modifier = Modifier.fillMaxWidth().semantics(mergeDescendants = true) {
contentDescription = "$time, $medName, ${log.status.historyLabel}" contentDescription = "$time, $medName, ${log.status.label}"
}, },
) { ) {
Row( Row(
Modifier.padding(horizontal = 12.dp, vertical = 10.dp), Modifier.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// Green ✓ taken / red ✕ not-taken, first on the line for an
// at-a-glance scan down the day. Decorative here — the row's
// merged contentDescription already speaks the status.
Icon(
painterResource(if (taken) R.drawable.ic_check else R.drawable.ic_close),
contentDescription = null,
tint = if (taken) takenGreen() else missedRed(),
modifier = Modifier.padding(end = 12.dp),
)
Text(time, style = MaterialTheme.typography.titleSmall) Text(time, style = MaterialTheme.typography.titleSmall)
Text( Text(
medName, medName,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(start = 12.dp).weight(1f), modifier = Modifier.padding(start = 12.dp).weight(1f),
) )
Text( DoseStatusBadge(log.status)
log.status.historyLabel,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
} }
} }
} }

View file

@ -37,19 +37,6 @@ fun MedDetSammeTheme(content: @Composable () -> Unit) {
MaterialTheme(colorScheme = scheme, typography = AppTypography, content = content) MaterialTheme(colorScheme = scheme, typography = AppTypography, content = content)
} }
/**
* Fixed adherence semantics for the history glance icons: green = taken,
* red = not taken. Deliberately *not* derived from the (possibly dynamic)
* brand palette a wallpaper-blue "primary" must never make a "taken" tick
* read as anything but green. Paired with a distinct shape ( vs ) and text
* so meaning never rests on colour alone (WCAG 1.4.1).
*/
@Composable
fun takenGreen(): Color = if (isSystemInDarkTheme()) Color(0xFF7CC97F) else Color(0xFF2E7D32)
@Composable
fun missedRed(): Color = if (isSystemInDarkTheme()) Color(0xFFFFB4AB) else Color(0xFFBA1A1A)
// Manrope for headings/titles (friendly, confident), Inter for body/labels // Manrope for headings/titles (friendly, confident), Inter for body/labels
// (built for UI legibility at small sizes). Both OFL, full æøå/µ coverage. // (built for UI legibility at small sizes). Both OFL, full æøå/µ coverage.
private val Manrope = FontFamily( private val Manrope = FontFamily(

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportHeight="24"
>
<path
android:fillColor="#FF000000"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
</vector>

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportHeight="24"
>
<path
android:fillColor="#FF000000"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
</vector>