fix: nav crash bug on scratch config
This commit is contained in:
parent
57d096ebb1
commit
791b532d85
|
@ -44,6 +44,7 @@ import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelService
|
|||
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavBar
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavItem
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.isCurrentRoute
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.prompt.CustomSnackBar
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarControllerProvider
|
||||
import com.zaneschepke.wireguardautotunnel.ui.screens.config.ConfigScreen
|
||||
|
@ -115,9 +116,10 @@ class MainActivity : AppCompatActivity() {
|
|||
Modifier
|
||||
.focusable()
|
||||
.focusProperties {
|
||||
when (navBackStackEntry?.toRoute<Screens>()) {
|
||||
is Screens.Lock -> Unit
|
||||
else -> up = focusRequester
|
||||
if (navBackStackEntry?.isCurrentRoute(Route.Lock) == true) {
|
||||
Unit
|
||||
} else {
|
||||
up = focusRequester
|
||||
}
|
||||
},
|
||||
bottomBar = {
|
||||
|
@ -126,17 +128,17 @@ class MainActivity : AppCompatActivity() {
|
|||
listOf(
|
||||
BottomNavItem(
|
||||
name = stringResource(R.string.tunnels),
|
||||
route = Screens.Main,
|
||||
route = Route.Main,
|
||||
icon = Icons.Rounded.Home,
|
||||
),
|
||||
BottomNavItem(
|
||||
name = stringResource(R.string.settings),
|
||||
route = Screens.Settings,
|
||||
route = Route.Settings,
|
||||
icon = Icons.Rounded.Settings,
|
||||
),
|
||||
BottomNavItem(
|
||||
name = stringResource(R.string.support),
|
||||
route = Screens.Support,
|
||||
route = Route.Support,
|
||||
icon = Icons.Rounded.QuestionMark,
|
||||
),
|
||||
),
|
||||
|
@ -148,16 +150,16 @@ class MainActivity : AppCompatActivity() {
|
|||
navController,
|
||||
enterTransition = { fadeIn(tween(Constants.TRANSITION_ANIMATION_TIME)) },
|
||||
exitTransition = { fadeOut(tween(Constants.TRANSITION_ANIMATION_TIME)) },
|
||||
startDestination = (if (isPinLockEnabled == true) Screens.Lock else Screens.Main),
|
||||
startDestination = (if (isPinLockEnabled == true) Route.Lock else Route.Main),
|
||||
) {
|
||||
composable<Screens.Main> {
|
||||
composable<Route.Main> {
|
||||
MainScreen(
|
||||
focusRequester = focusRequester,
|
||||
uiState = appUiState,
|
||||
navController = navController,
|
||||
)
|
||||
}
|
||||
composable<Screens.Settings> {
|
||||
composable<Route.Settings> {
|
||||
SettingsScreen(
|
||||
appViewModel = appViewModel,
|
||||
uiState = appUiState,
|
||||
|
@ -165,25 +167,25 @@ class MainActivity : AppCompatActivity() {
|
|||
focusRequester = focusRequester,
|
||||
)
|
||||
}
|
||||
composable<Screens.Support> {
|
||||
composable<Route.Support> {
|
||||
SupportScreen(
|
||||
focusRequester = focusRequester,
|
||||
navController = navController,
|
||||
appUiState = appUiState,
|
||||
)
|
||||
}
|
||||
composable<Screens.Logs> {
|
||||
composable<Route.Logs> {
|
||||
LogsScreen()
|
||||
}
|
||||
composable<Screens.Config> {
|
||||
val args = it.toRoute<Screens.Config>()
|
||||
composable<Route.Config> {
|
||||
val args = it.toRoute<Route.Config>()
|
||||
ConfigScreen(
|
||||
focusRequester = focusRequester,
|
||||
tunnelId = args.id,
|
||||
)
|
||||
}
|
||||
composable<Screens.Option> {
|
||||
val args = it.toRoute<Screens.Option>()
|
||||
composable<Route.Option> {
|
||||
val args = it.toRoute<Route.Option>()
|
||||
OptionsScreen(
|
||||
navController = navController,
|
||||
tunnelId = args.id,
|
||||
|
@ -191,7 +193,7 @@ class MainActivity : AppCompatActivity() {
|
|||
appUiState = appUiState,
|
||||
)
|
||||
}
|
||||
composable<Screens.Lock> {
|
||||
composable<Route.Lock> {
|
||||
PinLockScreen(
|
||||
navController = navController,
|
||||
appViewModel = appViewModel,
|
||||
|
|
|
@ -2,29 +2,29 @@ package com.zaneschepke.wireguardautotunnel.ui
|
|||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
sealed class Screens {
|
||||
sealed class Route {
|
||||
@Serializable
|
||||
data object Support : Screens()
|
||||
data object Support : Route()
|
||||
|
||||
@Serializable
|
||||
data object Settings : Screens()
|
||||
data object Settings : Route()
|
||||
|
||||
@Serializable
|
||||
data object Main : Screens()
|
||||
data object Main : Route()
|
||||
|
||||
@Serializable
|
||||
data class Option(
|
||||
val id: Int,
|
||||
) : Screens()
|
||||
) : Route()
|
||||
|
||||
@Serializable
|
||||
data object Lock : Screens()
|
||||
data object Lock : Route()
|
||||
|
||||
@Serializable
|
||||
data class Config(
|
||||
val id: Int,
|
||||
) : Screens()
|
||||
) : Route()
|
||||
|
||||
@Serializable
|
||||
data object Logs : Screens()
|
||||
data object Logs : Route()
|
||||
}
|
|
@ -33,9 +33,7 @@ fun BottomNavBar(navController: NavController, bottomNavItems: List<BottomNavIte
|
|||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
) {
|
||||
bottomNavItems.forEach { item ->
|
||||
val selected = navBackStackEntry?.destination?.hierarchy?.any {
|
||||
it.hasRoute(route = item.route::class)
|
||||
} == true
|
||||
val selected = navBackStackEntry.isCurrentRoute(item.route)
|
||||
NavigationBarItem(
|
||||
selected = selected,
|
||||
onClick = {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.zaneschepke.wireguardautotunnel.ui.common.navigation
|
||||
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
|
||||
data class BottomNavItem(
|
||||
val name: String,
|
||||
val route: Screens,
|
||||
val route: Route,
|
||||
val icon: ImageVector,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.zaneschepke.wireguardautotunnel.ui.common.navigation
|
||||
|
||||
import androidx.navigation.NavBackStackEntry
|
||||
import androidx.navigation.NavDestination.Companion.hasRoute
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
|
||||
fun NavBackStackEntry?.isCurrentRoute(route: Route): Boolean {
|
||||
return this?.destination?.hierarchy?.any {
|
||||
it.hasRoute(route = route::class)
|
||||
} == true
|
||||
}
|
|
@ -17,7 +17,7 @@ import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
|||
import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
import com.zaneschepke.wireguardautotunnel.module.IoDispatcher
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController
|
||||
import com.zaneschepke.wireguardautotunnel.ui.screens.config.model.PeerProxy
|
||||
import com.zaneschepke.wireguardautotunnel.util.Constants
|
||||
|
@ -335,14 +335,15 @@ constructor(
|
|||
SnackbarController.showMessage(
|
||||
StringValue.StringResource(R.string.config_changes_saved),
|
||||
)
|
||||
navController.navigate(Screens.Main)
|
||||
navController.navigate(Route.Main)
|
||||
}.onFailure {
|
||||
Timber.e(it)
|
||||
val message = it.message?.substringAfter(":", missingDelimiterValue = "")
|
||||
val stringValue =
|
||||
message?.let {
|
||||
StringValue.DynamicString(message)
|
||||
} ?: StringValue.StringResource(R.string.unknown_error)
|
||||
val stringValue = if (message.isNullOrBlank()) {
|
||||
StringValue.StringResource(R.string.unknown_error)
|
||||
} else {
|
||||
StringValue.DynamicString(message)
|
||||
}
|
||||
SnackbarController.showMessage(stringValue)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig
|
|||
import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus
|
||||
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppUiState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.RowListItem
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.dialog.InfoDialog
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.functions.rememberFileImportLauncherForResult
|
||||
|
@ -235,7 +235,7 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel(), uiState: AppUiState,
|
|||
onQrClick = { launchQrScanner() },
|
||||
onManualImportClick = {
|
||||
navController.navigate(
|
||||
Screens.Config(Constants.MANUAL_TUNNEL_CONFIG_ID),
|
||||
Route.Config(Constants.MANUAL_TUNNEL_CONFIG_ID),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -409,7 +409,7 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel(), uiState: AppUiState,
|
|||
onClick = {
|
||||
selectedTunnel?.let {
|
||||
navController.navigate(
|
||||
Screens.Option(it.id),
|
||||
Route.Option(it.id),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
@ -456,7 +456,7 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel(), uiState: AppUiState,
|
|||
selectedTunnel = tunnel
|
||||
selectedTunnel?.let {
|
||||
navController.navigate(
|
||||
Screens.Option(it.id),
|
||||
Route.Option(it.id),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -50,7 +50,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import androidx.navigation.NavController
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppUiState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.config.SubmitConfigurationTextBox
|
||||
|
@ -114,7 +114,7 @@ fun OptionsScreen(
|
|||
)
|
||||
}, focusRequester, isVisible = true, onClick = {
|
||||
navController.navigate(
|
||||
Screens.Config(config.id),
|
||||
Route.Config(config.id),
|
||||
)
|
||||
})
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.navigation.NavController
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppViewModel
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController
|
||||
import com.zaneschepke.wireguardautotunnel.util.StringValue
|
||||
import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv
|
||||
|
@ -36,11 +36,11 @@ fun PinLockScreen(navController: NavController, appViewModel: AppViewModel) {
|
|||
onPinCorrect = {
|
||||
// pin is correct, navigate or hide pin lock
|
||||
if (context.isRunningOnTv()) {
|
||||
navController.navigate(Screens.Main)
|
||||
navController.navigate(Route.Main)
|
||||
} else {
|
||||
val isPopped = navController.popBackStack()
|
||||
if (!isPopped) {
|
||||
navController.navigate(Screens.Main)
|
||||
navController.navigate(Route.Main)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -69,7 +69,7 @@ import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
|||
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppUiState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppViewModel
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.prompt.AuthorizationPrompt
|
||||
|
@ -581,7 +581,7 @@ fun SettingsScreen(
|
|||
} else {
|
||||
// TODO may want to show a dialog before proceeding in the future
|
||||
PinManager.initialize(WireGuardAutoTunnel.instance)
|
||||
navController.navigate(Screens.Lock)
|
||||
navController.navigate(Route.Lock)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
@ -46,7 +46,7 @@ import androidx.navigation.NavController
|
|||
import com.zaneschepke.wireguardautotunnel.BuildConfig
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppUiState
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Screens
|
||||
import com.zaneschepke.wireguardautotunnel.ui.Route
|
||||
import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv
|
||||
import com.zaneschepke.wireguardautotunnel.util.extensions.launchSupportEmail
|
||||
import com.zaneschepke.wireguardautotunnel.util.extensions.openWebUrl
|
||||
|
@ -244,7 +244,7 @@ fun SupportScreen(navController: NavController, focusRequester: FocusRequester,
|
|||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
TextButton(
|
||||
onClick = { navController.navigate(Screens.Logs) },
|
||||
onClick = { navController.navigate(Route.Logs) },
|
||||
modifier = Modifier.padding(vertical = 5.dp),
|
||||
) {
|
||||
Row(
|
||||
|
|
Loading…
Reference in New Issue