Skip to content

Commit 2266872

Browse files
authored
fix: fix navigation stack (#471)
* feat: Wire up back navigation * feat: Add sealed class for destinations * chore: Tidy * chore: Update visibility to internal
1 parent acbab2f commit 2266872

File tree

8 files changed

+56
-56
lines changed

8 files changed

+56
-56
lines changed

mockzilla-management-ui/mockzilla-desktop/src/commonMain/kotlin/com/apadmi/mockzilla/desktop/di/KoinHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import com.apadmi.mockzilla.desktop.ui.devicetabs.DeviceTabsViewModel
1111
import com.apadmi.mockzilla.lib.config.ZeroConfConfig
1212
import com.apadmi.mockzilla.ui.di.utils.MockzillaUiKoinContext
1313
import com.apadmi.mockzilla.ui.di.utils.viewModel
14-
import kotlinx.coroutines.DelicateCoroutinesApi
1514

1615
import org.koin.dsl.module
1716

1817
import java.net.NetworkInterface
1918

19+
import kotlinx.coroutines.DelicateCoroutinesApi
2020
import kotlinx.coroutines.GlobalScope
2121

2222
@OptIn(DelicateCoroutinesApi::class)

mockzilla-management-ui/mockzilla-management-ui-common/src/commonMain/kotlin/com/apadmi/mockzilla/ui/ui/common/widgets/endpoints/details/EndpointDetailsWidget.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
99
import androidx.compose.foundation.layout.FlowRow
1010
import androidx.compose.foundation.layout.Row
1111
import androidx.compose.foundation.layout.Spacer
12+
import androidx.compose.foundation.layout.fillMaxSize
1213
import androidx.compose.foundation.layout.fillMaxWidth
1314
import androidx.compose.foundation.layout.height
1415
import androidx.compose.foundation.layout.heightIn
@@ -17,6 +18,8 @@ import androidx.compose.foundation.layout.size
1718
import androidx.compose.foundation.layout.width
1819
import androidx.compose.foundation.pager.HorizontalPager
1920
import androidx.compose.foundation.pager.rememberPagerState
21+
import androidx.compose.foundation.rememberScrollState
22+
import androidx.compose.foundation.verticalScroll
2023
import androidx.compose.material.icons.Icons
2124
import androidx.compose.material.icons.filled.Delete
2225
import androidx.compose.material3.Button
@@ -122,7 +125,11 @@ fun EndpointDetailsWidgetContent(
122125
onErrorPresetSelected: (DashboardOverridePreset) -> Unit,
123126
onResetAll: () -> Unit,
124127
strings: Strings = LocalStrings.current,
125-
) = Column {
128+
) = Column(
129+
modifier = Modifier
130+
.fillMaxSize()
131+
.verticalScroll(rememberScrollState())
132+
) {
126133
val pagerState = rememberPagerState(initialPage = 0) { Tab.entries.size }
127134
val coroutineScope = rememberCoroutineScope()
128135

mockzilla-management-ui/mockzilla-mobile-ui/src/androidMain/kotlin/MockzillaManagementSdkActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import androidx.activity.compose.setContent
66
import androidx.compose.runtime.CompositionLocalProvider
77
import com.apadmi.mockzilla.lib.internal.utils.FileIo
88
import com.apadmi.mockzilla.mobile.ui.MobileAppRoot
9-
import com.apadmi.mockzilla.mobile.ui.startMockzillaMobileUiKoin
9+
import com.apadmi.mockzilla.mobile.ui.utils.startMockzillaMobileUiKoin
1010
import org.koin.core.context.stopKoin
1111
import org.koin.dsl.module
1212

mockzilla-management-ui/mockzilla-mobile-ui/src/commonMain/kotlin/com/apadmi/mockzilla/mobile/ui/MobileAppRoot.kt

Lines changed: 28 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
package com.apadmi.mockzilla.mobile.ui
44

55
import androidx.compose.foundation.layout.Column
6-
import androidx.compose.foundation.layout.fillMaxSize
7-
import androidx.compose.foundation.rememberScrollState
8-
import androidx.compose.foundation.verticalScroll
96
import androidx.compose.material.icons.Icons
107
import androidx.compose.material.icons.automirrored.filled.ArrowBack
118
import androidx.compose.material.icons.filled.Close
@@ -15,13 +12,8 @@ import androidx.compose.material3.IconButton
1512
import androidx.compose.material3.Surface
1613
import androidx.compose.material3.TopAppBar
1714
import androidx.compose.runtime.Composable
18-
import androidx.compose.runtime.LaunchedEffect
19-
import androidx.compose.runtime.MutableState
2015
import androidx.compose.runtime.collectAsState
2116
import androidx.compose.runtime.getValue
22-
import androidx.compose.runtime.mutableStateOf
23-
import androidx.compose.runtime.remember
24-
import androidx.compose.ui.Modifier
2517
import androidx.navigation.NavHostController
2618
import androidx.navigation.compose.NavHost
2719
import androidx.navigation.compose.composable
@@ -30,6 +22,7 @@ import androidx.navigation.toRoute
3022

3123
import com.apadmi.mockzilla.lib.models.EndpointConfiguration
3224
import com.apadmi.mockzilla.mobile.ui.deviceconnection.MobileDeviceConnectionWidget
25+
import com.apadmi.mockzilla.mobile.ui.utils.Destination
3326
import com.apadmi.mockzilla.ui.di.utils.getViewModel
3427
import com.apadmi.mockzilla.ui.i18n.LocalStrings
3528
import com.apadmi.mockzilla.ui.i18n.Strings
@@ -40,18 +33,6 @@ import com.apadmi.mockzilla.ui.ui.common.widgets.deviceconnection.UnsupportedDev
4033
import com.apadmi.mockzilla.ui.ui.common.widgets.endpoints.details.EndpointDetailsWidget
4134
import com.apadmi.mockzilla.ui.ui.common.widgets.endpoints.endpoints.EndpointsWidget
4235

43-
import kotlinx.serialization.Serializable
44-
45-
/**
46-
* @property key
47-
*/
48-
// TODO: Replace these with a sealed class so their usages are exhaustive
49-
@Serializable
50-
internal data class EndpointDetails(val key: String)
51-
52-
@Serializable
53-
internal data object EndpointList
54-
5536
@OptIn(ExperimentalMaterial3Api::class)
5637
@Composable
5738
internal fun MobileAppRoot(
@@ -60,14 +41,17 @@ internal fun MobileAppRoot(
6041
) = AppTheme {
6142
val viewModel = getViewModel<AppRootViewModel>()
6243
val state by viewModel.state.collectAsState()
63-
var showBackButton = remember { mutableStateOf(false) }
44+
val navController = rememberNavController()
45+
val showBackButton = navController.currentBackStack.collectAsState()
46+
.value
47+
.size > 2
48+
6449
Column {
6550
TopAppBar(
66-
title = { },
51+
title = { /* No title */ },
6752
navigationIcon = {
68-
// TODO: Wire up back nav
69-
if (showBackButton.value) {
70-
IconButton(onClick = onClose) {
53+
if (showBackButton) {
54+
IconButton(onClick = navController::navigateUp) {
7155
Icon(
7256
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
7357
contentDescription = strings.common.backDescription
@@ -82,13 +66,13 @@ internal fun MobileAppRoot(
8266
contentDescription = strings.common.closeDescription
8367
)
8468
}
85-
},
69+
}
8670
)
8771

8872
when (val currentState = state) {
8973
is State.Connected -> ConnectedState(
90-
currentState = currentState,
91-
showBackButton = showBackButton
74+
navController = navController,
75+
currentState = currentState
9276
)
9377

9478
State.NewDeviceConnection -> MobileDeviceConnectionWidget()
@@ -99,36 +83,29 @@ internal fun MobileAppRoot(
9983

10084
@Composable
10185
private fun ConnectedState(
102-
navController: NavHostController = rememberNavController(),
103-
currentState: State.Connected,
104-
showBackButton: MutableState<Boolean>
105-
) {
106-
val backStack by navController.currentBackStack.collectAsState()
107-
LaunchedEffect(backStack) {
108-
showBackButton.value = backStack.size > 1
109-
}
110-
86+
navController: NavHostController,
87+
currentState: State.Connected
88+
) = Surface {
11189
NavHost(
11290
navController = navController,
113-
startDestination = EndpointList
91+
startDestination = Destination.EndpointList
11492
) {
115-
composable<EndpointDetails>() { backStackEntry ->
116-
Surface(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
117-
EndpointDetailsWidget(
118-
currentState.activeDevice.device,
119-
activeEndpoint = EndpointConfiguration.Key(backStackEntry.toRoute<EndpointDetails>().key)
93+
composable<Destination.EndpointDetails> { backStackEntry ->
94+
EndpointDetailsWidget(
95+
device = currentState.activeDevice.device,
96+
activeEndpoint = EndpointConfiguration.Key(
97+
backStackEntry.toRoute<Destination.EndpointDetails>().key
12098
)
121-
}
99+
)
122100
}
123101

124-
composable<EndpointList> {
125-
Surface {
126-
EndpointsWidget(
127-
currentState.activeDevice.device
128-
) {
129-
navController.navigate(EndpointDetails(it.raw))
102+
composable<Destination.EndpointList> {
103+
EndpointsWidget(
104+
device = currentState.activeDevice.device,
105+
onEndpointClicked = {
106+
navController.navigate(Destination.EndpointDetails(it.raw))
130107
}
131-
}
108+
)
132109
}
133110
}
134111
}

mockzilla-management-ui/mockzilla-mobile-ui/src/commonMain/kotlin/com/apadmi/mockzilla/mobile/ui/deviceconnection/MobileDeviceConnectionWidget.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal fun MobileDeviceConnectionWidget(
3636
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.CenterVertically),
3737
horizontalAlignment = Alignment.CenterHorizontally
3838
) {
39-
when (val currentState = state) {
39+
when (state) {
4040
State.Connecting -> CircularProgressIndicator(
4141
modifier = Modifier.padding(end = 8.dp).size(20.dp)
4242
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.apadmi.mockzilla.mobile.ui.utils
2+
3+
import kotlinx.serialization.Serializable
4+
5+
@Serializable
6+
internal sealed class Destination {
7+
@Serializable
8+
internal data object EndpointList : Destination()
9+
10+
/**
11+
* @property key
12+
*/
13+
@Serializable
14+
internal data class EndpointDetails(val key: String) : Destination()
15+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.apadmi.mockzilla.mobile.ui
1+
package com.apadmi.mockzilla.mobile.ui.utils
22

33
import com.apadmi.mockzilla.lib.sharedstate.MockzillaSharedProcessStateHandler
44
import com.apadmi.mockzilla.mobile.ui.deviceconnection.MobileDeviceConnectionViewModel

mockzilla-management-ui/mockzilla-mobile-ui/src/iosMain/kotlin/com/apadmi/mockzilla/mobile/ui/Launcher.ios.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.apadmi.mockzilla.mobile.ui
22

33
import androidx.compose.ui.window.ComposeUIViewController
44
import com.apadmi.mockzilla.lib.internal.utils.FileIo
5+
import com.apadmi.mockzilla.mobile.ui.utils.startMockzillaMobileUiKoin
56
import org.koin.dsl.module
67

78
import platform.UIKit.*

0 commit comments

Comments
 (0)