fix(map): worked grids follow the selected operated grid; add All option

Switching the operated-grid selector now re-filters the green worked
cells on the map (the overlay receives the per-grid worked set instead
of the global one, on every recomposition via setGridMode). Previously
only the VUCC progress count changed while the map stayed green for all
operated grids.

The selector gains an 'All (n)' entry at the bottom of the list: it
selects no operated grid (null), showing every worked grid combined and
restoring the global VUCC count.
This commit is contained in:
atsunatsu committed 2026-09-15 00:25:12 +08:00
1 parent 826f44829b
commit 3b3579696b
1 file changed
+36 -10
@@ -207,8 +207,13 @@ private fun MapScreen(uiState: MapState, onAction: (MapAction) -> Unit, mapView:
if (p.type == AwardType.VUCC) p.copy(workedKeys = vuccGrids, count = vuccGrids.size) else p if (p.type == AwardType.VUCC) p.copy(workedKeys = vuccGrids, count = vuccGrids.size) else p
} }
} }
// Attach the tap listener whenever grid mode / worked grids change. // Worked grids drawn on the map: filtered by the selected operated grid
val workedGrids = uiState.workedGrids // (null = all operated grids). Drives both the green fills and the tap
// listener below, so switching the selector changes which cells are green.
val workedGrids = remember(uiState.workedGrids, vuccByMyGrid, selectedMyGrid) {
if (selectedMyGrid == null) uiState.workedGrids
else vuccByMyGrid[selectedMyGrid] ?: emptySet()
}
val isGridMode = uiState.isGridMode val isGridMode = uiState.isGridMode
DisposableEffect(isGridMode, workedGrids) { DisposableEffect(isGridMode, workedGrids) {
val receiver = object : org.osmdroid.events.MapEventsReceiver { val receiver = object : org.osmdroid.events.MapEventsReceiver {
@@ -297,7 +302,7 @@ private fun MapScreen(uiState: MapState, onAction: (MapAction) -> Unit, mapView:
// stationPosition would swallow the centering forever. // stationPosition would swallow the centering forever.
val shouldCenter = uiState.isGridMode && !prevGridMode val shouldCenter = uiState.isGridMode && !prevGridMode
setGridMode( setGridMode(
uiState.isGridMode, uiState.workedGrids, uiState.roamedGrids, view, uiState.isGridMode, workedGrids, uiState.roamedGrids, view,
uiState.stationPosition, uiState.stationPosition,
centerOnStation = shouldCenter centerOnStation = shouldCenter
) )
@@ -322,11 +327,12 @@ private fun MapScreen(uiState: MapState, onAction: (MapAction) -> Unit, mapView:
} }
} }
// Top-left: operated-grid selector for VUCC counting (grid mode only). // Top-left: operated-grid selector for VUCC counting (grid mode only).
val myGrid = selectedMyGrid // Shown whenever per-grid QSO data exists; "All" (null) is available.
if (uiState.isGridMode && selectedAward == AwardType.VUCC && myGrid != null) { if (uiState.isGridMode && selectedAward == AwardType.VUCC && vuccByMyGrid.isNotEmpty()) {
VuccGridSelector( VuccGridSelector(
options = vuccByMyGrid, options = vuccByMyGrid,
selected = myGrid, allCount = uiState.workedGrids.size,
selected = selectedMyGrid,
onSelect = { selectedMyGrid = it }, onSelect = { selectedMyGrid = it },
modifier = Modifier modifier = Modifier
.align(Alignment.TopStart) .align(Alignment.TopStart)
@@ -638,12 +644,13 @@ private fun AwardChipsRow(
@Composable @Composable
private fun VuccGridSelector( private fun VuccGridSelector(
options: Map<String, Set<String>>, options: Map<String, Set<String>>,
selected: String, allCount: Int,
onSelect: (String) -> Unit, selected: String?,
onSelect: (String?) -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
// Most-worked grid first; selection is made on tap. // Most-worked grid first; selection is made on tap. "All" sits last.
val sorted = remember(options) { options.entries.sortedByDescending { it.value.size } } val sorted = remember(options) { options.entries.sortedByDescending { it.value.size } }
Surface( Surface(
color = ComposeColor.Black.copy(alpha = 0.45f), color = ComposeColor.Black.copy(alpha = 0.45f),
@@ -658,7 +665,8 @@ private fun VuccGridSelector(
.padding(start = 10.dp, end = 6.dp, top = 4.dp, bottom = 4.dp) .padding(start = 10.dp, end = 6.dp, top = 4.dp, bottom = 4.dp)
) { ) {
Text( Text(
text = "$selected (${options[selected]?.size ?: 0})", text = if (selected == null) "All ($allCount)"
else "$selected (${options[selected]?.size ?: 0})",
color = ComposeColor.White, color = ComposeColor.White,
fontSize = 12.sp, fontSize = 12.sp,
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace
@@ -691,6 +699,24 @@ private fun VuccGridSelector(
) )
} }
} }
// "All" always listed last: shows every worked grid combined.
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable {
onSelect(null)
expanded = false
}
.padding(horizontal = 10.dp, vertical = 3.dp)
) {
Text(
text = "All ($allCount)",
color = if (selected == null) MaterialTheme.colorScheme.primary else ComposeColor.White,
fontSize = 12.sp,
fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace
)
}
} }
} }
} }