Skip to content

Commit ede50dc

Browse files
claudeintelarc
authored andcommitted
Live: the bus card starts small and drags open
Tapping a bus shows a slim card (route, where it's going, how it's running, the next stop) so the map stays in view. Drag it up or tap the handle for the model, next stops and Follow; drag down to shrink it, and further to close it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011C2fAvFFcMRkaF7qSvRA1v
1 parent 9517004 commit ede50dc

1 file changed

Lines changed: 41 additions & 3 deletions

File tree

‎app/src/main/java/nz/aryan/akllive/ui/LiveScreen.kt‎

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ import nz.aryan.akllive.data.Nz
7070
import nz.aryan.akllive.gtfs.Timetable
7171
import nz.aryan.akllive.gtfs.TripInfo
7272
import nz.aryan.akllive.gtfs.tripInfo
73+
import androidx.compose.animation.animateContentSize
74+
import androidx.compose.foundation.gestures.detectVerticalDragGestures
75+
import androidx.compose.material.icons.filled.KeyboardArrowUp
76+
import androidx.compose.runtime.mutableFloatStateOf
77+
import androidx.compose.ui.input.pointer.pointerInput
7378
import nz.aryan.akllive.AppViewModel
7479
import nz.aryan.akllive.data.BusTrip
7580
import nz.aryan.akllive.data.Fleet
@@ -296,9 +301,27 @@ private fun FilterPill(text: String, count: Int, dot: Color?, on: Boolean, click
296301
private fun LiveBusCard(b: LiveBus, trip: BusTrip?, ahead: List<Ahead>, now: Long, follow: Boolean,
297302
onFollow: () -> Unit, onZoom: () -> Unit, onStop: (String) -> Unit, close: () -> Unit) {
298303
val color = operatorColor(b.info.code)
299-
Surface(Modifier.fillMaxWidth(), shape = RoundedCornerShape(28.dp), color = MaterialTheme.colorScheme.surfaceContainer,
300-
shadowElevation = 6.dp) {
301-
Column(Modifier.padding(start = 16.dp, end = 16.dp, top = 14.dp, bottom = 12.dp)) {
304+
// small by default so the map stays in view; drag up (or tap the handle) for the rest
305+
var expanded by rememberSaveable(b.v.id) { mutableStateOf(false) }
306+
var drag by remember { mutableFloatStateOf(0f) }
307+
Surface(Modifier.fillMaxWidth().pointerInput(b.v.id) {
308+
detectVerticalDragGestures(
309+
onDragStart = { drag = 0f },
310+
onDragEnd = {
311+
when {
312+
drag < -40 -> expanded = true
313+
drag > 40 && expanded -> expanded = false
314+
drag > 90 -> close()
315+
}
316+
},
317+
) { _, dy -> drag += dy }
318+
}, shape = RoundedCornerShape(28.dp), color = MaterialTheme.colorScheme.surfaceContainer, shadowElevation = 6.dp) {
319+
Column(Modifier.animateContentSize().padding(start = 16.dp, end = 16.dp, top = 6.dp, bottom = 10.dp)) {
320+
Box(Modifier.fillMaxWidth().clickable(interactionSource = null, indication = null) { expanded = !expanded }
321+
.padding(vertical = 6.dp), contentAlignment = Alignment.Center) {
322+
Box(Modifier.size(width = 36.dp, height = 4.dp).background(MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f),
323+
RoundedCornerShape(50)))
324+
}
302325
Row(verticalAlignment = Alignment.CenterVertically) {
303326
Box(Modifier.background(color, RoundedCornerShape(10.dp)).padding(horizontal = 10.dp, vertical = 3.dp)) {
304327
Text(b.route ?: "—", color = Color.White, fontWeight = FontWeight.Black, fontSize = 17.sp)
@@ -316,6 +339,21 @@ private fun LiveBusCard(b: LiveBus, trip: BusTrip?, ahead: List<Ahead>, now: Lon
316339
}
317340
IconButton(onClick = close) { Icon(Icons.Filled.Close, "Close", tint = MaterialTheme.colorScheme.onSurfaceVariant) }
318341
}
342+
if (!expanded) {
343+
// one line: how it's running and what's next
344+
Row(Modifier.fillMaxWidth().clickable { expanded = true }.padding(top = 4.dp), verticalAlignment = Alignment.CenterVertically) {
345+
if (b.route != null) {
346+
val (text, c) = punctuality(trip?.delay)
347+
Chip(if (trip?.delay == null) "Timing unknown" else text, if (trip?.delay == null) Pal.Ink else c)
348+
Spacer(Modifier.width(8.dp))
349+
}
350+
Text(ahead.firstOrNull()?.let { "Next: ${it.stop.name} · ${countdown(it.eta - now)}" }
351+
?: (b.info.model?.short ?: b.info.fleetNo),
352+
style = MaterialTheme.typography.bodyMedium, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))
353+
Icon(Icons.Filled.KeyboardArrowUp, "More", tint = MaterialTheme.colorScheme.onSurfaceVariant)
354+
}
355+
return@Column
356+
}
319357
Spacer(Modifier.height(8.dp))
320358
VehicleInfo(b.v, big = true)
321359
Spacer(Modifier.height(8.dp))

0 commit comments

Comments
 (0)