Skip to content

Commit c7ec8b9

Browse files
fix: resolve channel detail black screen and navigation issues
- Change Routes.ChannelDetail to accept channelId parameter - Update ChannelDetailScreen to fetch channel on initialization - Replace early return with loading state when channel is null - Navigate directly to detail screen with channelId - Remove intermediate navigation through list screen - Fix predictive back gesture by eliminating blank composable state Fixes #668 Co-authored-by: Ovi Trif <[email protected]>
1 parent ed9a2e0 commit c7ec8b9

File tree

3 files changed

+54
-24
lines changed

3 files changed

+54
-24
lines changed

app/src/main/java/to/bitkit/ui/ContentView.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1204,9 +1204,11 @@ private fun NavGraphBuilder.lightningConnections(
12041204
composableWithDefaultTransitions<Routes.ChannelDetail> {
12051205
val parentEntry = remember(it) { navController.getBackStackEntry(Routes.ConnectionsNav) }
12061206
val viewModel = hiltViewModel<LightningConnectionsViewModel>(parentEntry)
1207+
val route = it.toRoute<Routes.ChannelDetail>()
12071208
ChannelDetailScreen(
12081209
navController = navController,
12091210
viewModel = viewModel,
1211+
channelId = route.channelId,
12101212
)
12111213
}
12121214
composableWithDefaultTransitions<Routes.CloseConnection> {
@@ -1836,7 +1838,7 @@ sealed interface Routes {
18361838
data object LightningConnections : Routes
18371839

18381840
@Serializable
1839-
data object ChannelDetail : Routes
1841+
data class ChannelDetail(val channelId: String) : Routes
18401842

18411843
@Serializable
18421844
data object CloseConnection : Routes

app/src/main/java/to/bitkit/ui/settings/lightning/ChannelDetailScreen.kt

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,42 @@ import java.util.Locale
8585
fun ChannelDetailScreen(
8686
navController: NavController,
8787
viewModel: LightningConnectionsViewModel,
88+
channelId: String,
8889
) {
8990
val context = LocalContext.current
9091
val app = appViewModel ?: return
9192
val wallet = walletViewModel ?: return
9293

94+
LaunchedEffect(channelId) {
95+
viewModel.findAndSelectChannel(channelId)
96+
}
97+
9398
val selectedChannel by viewModel.selectedChannel.collectAsStateWithLifecycle()
94-
val channel = selectedChannel ?: return
99+
val channel = selectedChannel
95100

96101
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
97102
val paidOrders by viewModel.blocktankRepo.blocktankState.collectAsStateWithLifecycle()
103+
val lightningState by wallet.lightningState.collectAsStateWithLifecycle()
104+
105+
if (channel == null) {
106+
Content(
107+
channel = null,
108+
blocktankOrders = emptyList(),
109+
cjitEntries = emptyList(),
110+
txTime = null,
111+
isRefreshing = false,
112+
isClosedChannel = false,
113+
onBack = { navController.popBackStack() },
114+
onRefresh = {},
115+
onCopyText = {},
116+
onOpenUrl = {},
117+
onSupport = {},
118+
onCloseConnection = {},
119+
)
120+
return
121+
}
98122

99123
val isClosedChannel = uiState.closedChannels.any { it.details.channelId == channel.details.channelId }
100-
val lightningState by wallet.lightningState.collectAsStateWithLifecycle()
101124

102125
// Fetch transaction details for funding transaction if available
103126
LaunchedEffect(channel.details.fundingTxo?.txid) {
@@ -108,8 +131,8 @@ fun ChannelDetailScreen(
108131

109132
// Fetch activity timestamp for transfer activity with matching channel ID
110133
LaunchedEffect(channel.details.channelId) {
111-
channel.details.channelId?.let { channelId ->
112-
viewModel.fetchActivityTimestamp(channelId)
134+
channel.details.channelId.let { id ->
135+
viewModel.fetchActivityTimestamp(id)
113136
}
114137
}
115138

@@ -148,7 +171,7 @@ fun ChannelDetailScreen(
148171
@Suppress("CyclomaticComplexMethod")
149172
@Composable
150173
private fun Content(
151-
channel: ChannelUi,
174+
channel: ChannelUi?,
152175
blocktankOrders: List<IBtOrder> = emptyList(),
153176
cjitEntries: List<IcJitEntry> = emptyList(),
154177
txTime: ULong? = null,
@@ -161,6 +184,24 @@ private fun Content(
161184
onSupport: (Any) -> Unit = {},
162185
onCloseConnection: () -> Unit = {},
163186
) {
187+
ScreenColumn {
188+
AppTopBar(
189+
titleText = channel?.name ?: "",
190+
onBackClick = onBack,
191+
actions = { DrawerNavIcon() },
192+
)
193+
194+
if (channel == null) {
195+
Box(
196+
modifier = Modifier
197+
.fillMaxSize()
198+
.padding(16.dp),
199+
contentAlignment = Alignment.Center
200+
) {
201+
CaptionB(text = stringResource(R.string.common__loading))
202+
}
203+
return@ScreenColumn
204+
}
164205
// Check if the channel was opened via CJIT
165206
val cjitEntry = cjitEntries.find { entry ->
166207
entry.channel?.fundingTx?.id == channel.details.fundingTxo?.txid
@@ -184,13 +225,6 @@ private fun Content(
184225
val remoteBalance = (channel.details.inboundCapacityMsat / 1000u).toLong()
185226
val reserveBalance = (channel.details.unspendablePunishmentReserve ?: 0u).toLong()
186227

187-
ScreenColumn {
188-
AppTopBar(
189-
titleText = channel.name,
190-
onBackClick = onBack,
191-
actions = { DrawerNavIcon() },
192-
)
193-
194228
PullToRefreshBox(
195229
isRefreshing = isRefreshing,
196230
onRefresh = onRefresh,

app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsScreen.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,13 @@ fun LightningConnectionsScreen(
8888
viewModel.refreshObservedState()
8989
viewModel.clearSelectedChannel()
9090
viewModel.clearTransactionDetails()
91-
}
9291

93-
LaunchedEffect(navController.currentBackStackEntry) {
9492
val selectedChannelId = navController.previousBackStackEntry?.savedStateHandle?.get<String>("selectedChannelId")
95-
if (selectedChannelId == null) return@LaunchedEffect
96-
97-
navController.previousBackStackEntry?.savedStateHandle?.remove<String>("selectedChannelId")
98-
delay(CHANNEL_SELECTION_DELAY_MS)
99-
if (viewModel.findAndSelectChannel(selectedChannelId)) {
100-
navController.navigate(Routes.ChannelDetail) {
93+
if (selectedChannelId != null) {
94+
navController.previousBackStackEntry?.savedStateHandle?.remove<String>("selectedChannelId")
95+
delay(CHANNEL_SELECTION_DELAY_MS)
96+
navController.navigate(Routes.ChannelDetail(selectedChannelId)) {
10197
launchSingleTop = true
102-
popUpTo(Routes.ConnectionsNav) { inclusive = false }
10398
}
10499
}
105100
}
@@ -112,8 +107,7 @@ fun LightningConnectionsScreen(
112107
viewModel.zipLogsForSharing { uri -> context.shareZipFile(uri) }
113108
},
114109
onClickChannel = { channelUi ->
115-
viewModel.setSelectedChannel(channelUi)
116-
navController.navigate(Routes.ChannelDetail)
110+
navController.navigate(Routes.ChannelDetail(channelUi.details.channelId))
117111
},
118112
onRefresh = {
119113
viewModel.onPullToRefresh()

0 commit comments

Comments
 (0)