fix: dedup node lists to prevent LazyColumn duplicate-key crash (#6193)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
James Rich
2026-07-10 08:31:54 -05:00
committed by GitHub
parent f6a3f091ed
commit 228fa8a368
2 changed files with 9 additions and 2 deletions

View File

@@ -48,7 +48,9 @@ fun ClusterItemsListDialog(
text = {
// Use a LazyColumn for potentially long lists of items
LazyColumn(contentPadding = PaddingValues(vertical = 8.dp)) {
items(items, key = { it.node.num }) { item ->
// Dedup by node.num: it's the LazyColumn key and must be unique, but filteredNodes can
// contain the same node from two sources (or a num=0 placeholder). See NodeListScreen.
items(items.distinctBy { it.node.num }, key = { it.node.num }) { item ->
ClusterDialogListItem(item = item, onClick = { onItemClick(item) })
}
}

View File

@@ -106,7 +106,12 @@ fun NodeListScreen(
val scope = rememberCoroutineScope()
val state by viewModel.nodesUiState.collectAsStateWithLifecycle()
val nodes by viewModel.nodeList.collectAsStateWithLifecycle()
// Dedup by num: it's the LazyColumn key (must be unique) but the upstream flow can momentarily emit
// two entries with the same num (a num=0 unknown-node placeholder, or a brief double-emission during
// an active-DB switch). Dedup once here so the count in the app bar and the rendered rows agree.
// Composite "num_index" keys would also fix the crash but break animateItem() reorder animations.
val allNodes by viewModel.nodeList.collectAsStateWithLifecycle()
val nodes = remember(allNodes) { allNodes.distinctBy { it.num } }
val ourNode by viewModel.ourNodeInfo.collectAsStateWithLifecycle()
val onlineNodeCount by viewModel.onlineNodeCount.collectAsStateWithLifecycle(0)
val totalNodeCount by viewModel.totalNodeCount.collectAsStateWithLifecycle(0)