Put the water's direction back on the tide card

b4bebfd · Gabriel Morell · 2026-09-08 20:35

19 files +32 -9
Message
{commit_body(@commit)}

Files changed

modified clients/android/app/src/main/java/io/neiam/apolloscrib/ui/RichFacts.kt
+10 −6
@@ -122,13 +122,17 @@ private fun tidal(entry: VisionEntry): RichFacts? {
122 122 iconRes = R.drawable.fa_water,
123 123 // The next tide, not the first field the publisher filled in.
124 124 headline = next?.at?.asClockTime(),
125 − // Which tide is coming and how long until it. Named outright rather
126 − // than left to be worked out from the three below it -- and naming it
127 − // says which way the water is going, so saying that as well would be
128 − // the same fact twice.
125 + // What the water is doing, which tide brings it, and how long: the
126 + // three in that order, because that is the order they are wanted in.
127 + // The first needs nothing known to read, the second names what the
128 + // headline is a time for, and the third is the only one that is
129 + // arithmetic.
129 130 caption = next?.let { extreme ->
130 − val kind = if (extreme.high) "Next high" else "Next low"
131 − "$kind · ${Tides.until(now, extreme.minutes)}"
131 + listOfNotNull(
132 + Tides.state(extreme),
133 + if (extreme.high) "Next high" else "Next low",
134 + Tides.until(now, extreme.minutes)
135 + ).joinToString(" · ")
132 136 },
133 137 // The rest in clock order, each saying which it is and how high.
134 138 facts = extremes
modified clients/android/app/src/main/java/io/neiam/apolloscrib/ui/Tides.kt
+15 −0
@@ -42,6 +42,21 @@ object Tides {
42 42 fun next(extremes: List<Extreme>, nowMinutes: Int): Extreme? =
43 43 extremes.firstOrNull { it.minutes > nowMinutes } ?: extremes.firstOrNull()
44 44
45 + /**
46 + * Whether the water is rising or falling, from what comes next.
47 + *
48 + * Strictly it is implied by the tide being named beside it -- on its way
49 + * to a high means filling. Kept anyway, and first, because it is the part
50 + * you can read without knowing that: "coming in" needs no arithmetic and
51 + * no tide tables, and it is the answer to the question actually being
52 + * asked at the water's edge.
53 + */
54 + fun state(next: Extreme?): String? = when (next?.high) {
55 + true -> "Coming in"
56 + false -> "Going out"
57 + null -> null
58 + }
59 +
45 60 /**
46 61 * How long until then, as a person would say it.
47 62 *
modified clients/android/app/src/test/java/io/neiam/apolloscrib/ui/TidesTest.kt
+7 −3
@@ -50,13 +50,17 @@ class TidesTest {
50 50 }
51 51
52 52 @Test
53 − fun `the next tide says which kind it is`() {
53 + fun `the next tide says which kind it is, and which way the water goes`() {
54 54 val extremes = Tides.order(day)
55 55
56 − // Which is the thing the card names, rather than leaving it to be
57 − // deduced from the three tides underneath it.
56 + // Both, and named rather than deduced from the three underneath.
58 57 assertEquals(true, Tides.next(extremes, 5 * 60)?.high)
58 + assertEquals("Coming in", Tides.state(Tides.next(extremes, 5 * 60)))
59 +
59 60 assertEquals(false, Tides.next(extremes, 10 * 60)?.high)
61 + assertEquals("Going out", Tides.state(Tides.next(extremes, 10 * 60)))
62 +
63 + assertNull(Tides.state(null))
60 64 }
61 65
62 66 @Test

Parents: 778a0b4