fix(mutual/radar): bigger radar shortcut; no bounce-back on finished pass

- Pass card header: radar icon button enlarged to 48dp touch target with a
  24dp icon, spanning both header rows vertically (name/time + elevations);
  the pass info column narrows so the Opposite elevation shifts left.
- RadarDestination no longer auto-returns instantly when the mutual pass has
  already ended — the auto-return now only runs while the pass is actually in
  progress. Previously the collapsed-card radar shortcut appeared broken
  ('flash back to Mutual') whenever the computed pass had finished.
- Fakes: add the 4 last-sync bookkeeping members missed by the LoTW commit.
This commit is contained in:
atsunatsu committed 2026-09-16 16:53:46 +08:00
1 parent f3fdf61784
commit 0ce177cfbf
3 files changed
+36 -16

No files matched your search

@@ -567,6 +567,12 @@ private fun MutualPassCard(
.clickable(onClick = onClick) .clickable(onClick = onClick)
) { ) {
Column(modifier = Modifier.padding(12.dp)) { Column(modifier = Modifier.padding(12.dp)) {
// Header: pass info (name/time + elevations) on the left, and a
// larger radar shortcut on the right that spans both rows vertically.
// The pass info column narrows, so the "Opposite" elevation shifts
// left to make room for the taller button.
Row(verticalAlignment = Alignment.CenterVertically) {
Column(modifier = Modifier.weight(1f)) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@@ -577,6 +583,8 @@ private fun MutualPassCard(
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) )
Text( Text(
@@ -584,16 +592,6 @@ private fun MutualPassCard(
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
// Radar shortcut, visible even on the collapsed card: icon only,
// rightmost position so the pass info shifts left. The card's own
// click (expand) is not triggered by the IconButton's tap.
IconButton(onClick = onNavigateToRadar) {
Icon(
painter = painterResource(id = R.drawable.ic_radar),
contentDescription = stringResource(R.string.mutual_open_radar),
modifier = Modifier.size(18.dp)
)
}
} }
Spacer(Modifier.height(4.dp)) Spacer(Modifier.height(4.dp))
Row( Row(
@@ -611,6 +609,21 @@ private fun MutualPassCard(
color = MaterialTheme.colorScheme.tertiary color = MaterialTheme.colorScheme.tertiary
) )
} }
}
// Radar shortcut, visible even on the collapsed card: a taller
// button spanning both header rows. The card's own click
// (expand) is not triggered by the IconButton's tap.
IconButton(
onClick = onNavigateToRadar,
modifier = Modifier.size(48.dp)
) {
Icon(
painter = painterResource(id = R.drawable.ic_radar),
contentDescription = stringResource(R.string.mutual_open_radar),
modifier = Modifier.size(24.dp)
)
}
}
AnimatedVisibility( AnimatedVisibility(
visible = isExpanded, visible = isExpanded,
@@ -116,4 +116,8 @@ class FakeSettingsRepo(initialPosition: GeoPos = GeoPos(23.13, 113.26)) : ISetti
override fun getRoamedGrids(): Set<String> = TODO() override fun getRoamedGrids(): Set<String> = TODO()
override fun setRoamedGrids(grids: Set<String>) = TODO() override fun setRoamedGrids(grids: Set<String>) = TODO()
override fun updateLoTWSettings(settings: LoTWSettings) = TODO() override fun updateLoTWSettings(settings: LoTWSettings) = TODO()
override fun getLastLotwSyncDate(): String = ""
override fun setLastLotwSyncDate(date: String) = Unit
override fun getLastLotwSyncCallsign(): String = ""
override fun setLastLotwSyncCallsign(callsign: String) = Unit
} }
@@ -101,14 +101,17 @@ fun RadarDestination(navigateUp: () -> Unit) {
} }
LaunchedEffect(mutualData.endTime) { LaunchedEffect(mutualData.endTime) {
if (mutualData.endTime <= 0L) return@LaunchedEffect if (mutualData.endTime <= 0L) return@LaunchedEffect
while (true) { // Auto-return only while the mutual pass is actually in progress. An
val remainingMs = mutualData.endTime - System.currentTimeMillis() // already-finished pass must NOT bounce the radar page back instantly
if (remainingMs <= 0L) { // (that made the pass-card radar shortcut look broken: tapping it while
navigateUpAndClearMutual() // the computed pass had ended returned to Mutual immediately).
return@LaunchedEffect var remainingMs = mutualData.endTime - System.currentTimeMillis()
} if (remainingMs <= 0L) return@LaunchedEffect
while (remainingMs > 0L) {
delay(remainingMs.coerceAtMost(1000L)) delay(remainingMs.coerceAtMost(1000L))
remainingMs = mutualData.endTime - System.currentTimeMillis()
} }
navigateUpAndClearMutual()
} }
// Sync actual permission state on every recomposition so it survives screen re-entry // Sync actual permission state on every recomposition so it survives screen re-entry
val hasPermission = ContextCompat.checkSelfPermission( val hasPermission = ContextCompat.checkSelfPermission(