mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-11 00:12:24 +01:00
Today's weather card shows the next few hours beside the weather now
This commit is contained in:
1 parent
59a2d38480
commit
542dd6751f
1 file changed
+53
-2
@@ -14,6 +14,10 @@ import androidx.compose.foundation.layout.Row
|
|||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
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.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -94,19 +98,66 @@ private fun WeatherCard(context: Context) {
|
|||||||
is WeatherState.Ready -> {
|
is WeatherState.Ready -> {
|
||||||
val w = s.data
|
val w = s.data
|
||||||
WeatherIcon(w.code, w.isDay, size = 44.dp)
|
WeatherIcon(w.code, w.isDay, size = 44.dp)
|
||||||
Column {
|
Column(Modifier.weight(1f)) {
|
||||||
Text(
|
Text(
|
||||||
"${w.temp}${w.tempUnit} · ${Weather.condition(w.code)}",
|
"${w.temp}${w.tempUnit} · ${Weather.condition(w.code)}",
|
||||||
style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.SemiBold,
|
style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.SemiBold,
|
||||||
|
maxLines = 1, overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
Text(w.place, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
|
Text(w.place, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1)
|
||||||
}
|
}
|
||||||
|
NextHours(w.hours, Modifier.weight(1.3f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next few hours beside the weather now, in the same card, so a glance answers "will it rain
|
||||||
|
* on the way" without opening Weather. As many as fit, up to five; none if fewer than three would.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
private fun NextHours(all: List<HourForecast>, modifier: Modifier) {
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
// The forecast is cached, so its first hours may already be past.
|
||||||
|
val hours = all.filter { it.time > now }
|
||||||
|
androidx.compose.foundation.layout.BoxWithConstraints(modifier) {
|
||||||
|
val fit = (maxWidth / HOUR_WIDTH).toInt().coerceAtMost(5)
|
||||||
|
if (fit < 3 || hours.size < 3) return@BoxWithConstraints
|
||||||
|
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Box(Modifier.width(1.dp).height(64.dp).background(MaterialTheme.colorScheme.outlineVariant))
|
||||||
|
hours.take(fit).forEach { h ->
|
||||||
|
Column(
|
||||||
|
Modifier.weight(1f),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
DateFormat.getTimeInstance(DateFormat.SHORT).format(Date(h.time)).replace(":00", ""),
|
||||||
|
style = MaterialTheme.typography.labelMedium,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
maxLines = 1,
|
||||||
|
)
|
||||||
|
WeatherIcon(h.code, h.isDay, size = 24.dp)
|
||||||
|
Text("${h.temp}°", style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.SemiBold)
|
||||||
|
// Kept as a blank line when dry, so every column lines up.
|
||||||
|
Text(
|
||||||
|
if (h.rainChance >= RAIN_SHOWN) "${h.rainChance}%" else " ",
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val HOUR_WIDTH = 64.dp
|
||||||
|
|
||||||
|
/** Below this a chance of rain is noise on a glance card; the Weather screen still shows it. */
|
||||||
|
private const val RAIN_SHOWN = 20
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AgendaCard(context: Context) {
|
private fun AgendaCard(context: Context) {
|
||||||
val events by produceState<List<AgendaEvent>?>(cachedAgenda) {
|
val events by produceState<List<AgendaEvent>?>(cachedAgenda) {
|
||||||
|
|||||||
Reference in new issue
Block a user