migrate to typed navigation

This commit is contained in:
Zane Schepke 2024-09-22 03:07:02 -04:00
parent d330fa4c28
commit cfb4f85ded
13 changed files with 118 additions and 128 deletions

View File

@ -11,6 +11,10 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.focusable import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Home
import androidx.compose.material.icons.rounded.QuestionMark
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarData import androidx.compose.material3.SnackbarData
@ -25,24 +29,24 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.navArgument import androidx.navigation.toRoute
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.data.repository.AppStateRepository import com.zaneschepke.wireguardautotunnel.data.repository.AppStateRepository
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelService import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelService
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavBar import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavBar
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavItem
import com.zaneschepke.wireguardautotunnel.ui.common.prompt.CustomSnackBar import com.zaneschepke.wireguardautotunnel.ui.common.prompt.CustomSnackBar
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarControllerProvider import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarControllerProvider
import com.zaneschepke.wireguardautotunnel.ui.screens.config.ConfigScreen import com.zaneschepke.wireguardautotunnel.ui.screens.config.ConfigScreen
import com.zaneschepke.wireguardautotunnel.ui.screens.config.ConfigViewModel
import com.zaneschepke.wireguardautotunnel.ui.screens.main.ConfigType
import com.zaneschepke.wireguardautotunnel.ui.screens.main.MainScreen import com.zaneschepke.wireguardautotunnel.ui.screens.main.MainScreen
import com.zaneschepke.wireguardautotunnel.ui.screens.options.OptionsScreen import com.zaneschepke.wireguardautotunnel.ui.screens.options.OptionsScreen
import com.zaneschepke.wireguardautotunnel.ui.screens.pinlock.PinLockScreen import com.zaneschepke.wireguardautotunnel.ui.screens.pinlock.PinLockScreen
@ -111,8 +115,8 @@ class MainActivity : AppCompatActivity() {
Modifier Modifier
.focusable() .focusable()
.focusProperties { .focusProperties {
when (navBackStackEntry?.destination?.route) { when (navBackStackEntry?.toRoute<Screens>()) {
Screen.Lock.route -> Unit is Screens.Lock -> Unit
else -> up = focusRequester else -> up = focusRequester
} }
}, },
@ -120,9 +124,21 @@ class MainActivity : AppCompatActivity() {
BottomNavBar( BottomNavBar(
navController, navController,
listOf( listOf(
Screen.Main.navItem, BottomNavItem(
Screen.Settings.navItem, name = stringResource(R.string.tunnels),
Screen.Support.navItem, route = Screens.Main,
icon = Icons.Rounded.Home,
),
BottomNavItem(
name = stringResource(R.string.settings),
route = Screens.Settings,
icon = Icons.Rounded.Settings,
),
BottomNavItem(
name = stringResource(R.string.support),
route = Screens.Support,
icon = Icons.Rounded.QuestionMark,
),
), ),
) )
}, },
@ -132,20 +148,16 @@ class MainActivity : AppCompatActivity() {
navController, navController,
enterTransition = { fadeIn(tween(Constants.TRANSITION_ANIMATION_TIME)) }, enterTransition = { fadeIn(tween(Constants.TRANSITION_ANIMATION_TIME)) },
exitTransition = { fadeOut(tween(Constants.TRANSITION_ANIMATION_TIME)) }, exitTransition = { fadeOut(tween(Constants.TRANSITION_ANIMATION_TIME)) },
startDestination = (if (isPinLockEnabled == true) Screen.Lock.route else Screen.Main.route), startDestination = (if (isPinLockEnabled == true) Screens.Lock else Screens.Main),
) { ) {
composable( composable<Screens.Main> {
Screen.Main.route,
) {
MainScreen( MainScreen(
focusRequester = focusRequester, focusRequester = focusRequester,
uiState = appUiState, uiState = appUiState,
navController = navController, navController = navController,
) )
} }
composable( composable<Screens.Settings> {
Screen.Settings.route,
) {
SettingsScreen( SettingsScreen(
appViewModel = appViewModel, appViewModel = appViewModel,
uiState = appUiState, uiState = appUiState,
@ -153,56 +165,33 @@ class MainActivity : AppCompatActivity() {
focusRequester = focusRequester, focusRequester = focusRequester,
) )
} }
composable( composable<Screens.Support> {
Screen.Support.route,
) {
SupportScreen( SupportScreen(
focusRequester = focusRequester, focusRequester = focusRequester,
navController = navController, navController = navController,
appUiState = appUiState, appUiState = appUiState,
) )
} }
composable(Screen.Support.Logs.route) { composable<Screens.Logs> {
LogsScreen() LogsScreen()
} }
composable( composable<Screens.Config> {
"${Screen.Config.route}/{id}?configType={configType}", val args = it.toRoute<Screens.Config>()
arguments = ConfigScreen(
listOf( focusRequester = focusRequester,
navArgument("id") { tunnelId = args.id,
type = NavType.StringType )
defaultValue = "0"
},
navArgument("configType") {
type = NavType.StringType
defaultValue = ConfigType.WIREGUARD.name
},
),
) {
val id = it.arguments?.getString("id")
if (!id.isNullOrBlank()) {
val viewModel = hiltViewModel<ConfigViewModel, ConfigViewModel.ConfigViewModelFactory> { factory ->
factory.create(id.toInt())
}
ConfigScreen(
viewModel = viewModel,
focusRequester = focusRequester,
tunnelId = id.toInt(),
)
}
} }
composable("${Screen.Option.route}/{id}") { composable<Screens.Option> {
val id = it.arguments?.getString("id") val args = it.toRoute<Screens.Option>()
if (!id.isNullOrBlank()) { OptionsScreen(
OptionsScreen( navController = navController,
navController = navController, tunnelId = args.id,
tunnelId = id.toInt(), focusRequester = focusRequester,
focusRequester = focusRequester, appUiState = appUiState,
appUiState = appUiState, )
)
}
} }
composable(Screen.Lock.route) { composable<Screens.Lock> {
PinLockScreen( PinLockScreen(
navController = navController, navController = navController,
appViewModel = appViewModel, appViewModel = appViewModel,

View File

@ -1,46 +0,0 @@
package com.zaneschepke.wireguardautotunnel.ui
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Home
import androidx.compose.material.icons.rounded.QuestionMark
import androidx.compose.material.icons.rounded.Settings
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavItem
sealed class Screen(val route: String) {
data object Main : Screen("main") {
val navItem =
BottomNavItem(
name = WireGuardAutoTunnel.instance.getString(R.string.tunnels),
route = route,
icon = Icons.Rounded.Home,
)
}
data object Settings : Screen("settings") {
val navItem =
BottomNavItem(
name = WireGuardAutoTunnel.instance.getString(R.string.settings),
route = route,
icon = Icons.Rounded.Settings,
)
}
data object Support : Screen("support") {
val navItem =
BottomNavItem(
name = WireGuardAutoTunnel.instance.getString(R.string.support),
route = route,
icon = Icons.Rounded.QuestionMark,
)
data object Logs : Screen("support/logs")
}
data object Config : Screen("config")
data object Lock : Screen("lock")
data object Option : Screen("option")
}

View File

@ -0,0 +1,30 @@
package com.zaneschepke.wireguardautotunnel.ui
import kotlinx.serialization.Serializable
sealed class Screens {
@Serializable
data object Support : Screens()
@Serializable
data object Settings : Screens()
@Serializable
data object Main : Screens()
@Serializable
data class Option(
val id: Int,
) : Screens()
@Serializable
data object Lock : Screens()
@Serializable
data class Config(
val id: Int,
) : Screens()
@Serializable
data object Logs : Screens()
}

View File

@ -12,6 +12,8 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
@ -20,19 +22,24 @@ fun BottomNavBar(navController: NavController, bottomNavItems: List<BottomNavIte
var showBottomBar by rememberSaveable { mutableStateOf(true) } var showBottomBar by rememberSaveable { mutableStateOf(true) }
val navBackStackEntry by navController.currentBackStackEntryAsState() val navBackStackEntry by navController.currentBackStackEntryAsState()
showBottomBar = bottomNavItems.firstOrNull { navBackStackEntry?.destination?.route?.contains(it.route) == true } != null showBottomBar = bottomNavItems.firstOrNull {
navBackStackEntry?.destination?.hierarchy?.any { dest ->
bottomNavItems.map { dest.hasRoute(route = it.route::class) }.contains(true)
} == true
} != null
if (showBottomBar) { if (showBottomBar) {
NavigationBar( NavigationBar(
containerColor = MaterialTheme.colorScheme.surface, containerColor = MaterialTheme.colorScheme.surface,
) { ) {
bottomNavItems.forEach { item -> bottomNavItems.forEach { item ->
val selected = navBackStackEntry?.destination?.route?.contains(item.route) == true val selected = navBackStackEntry?.destination?.hierarchy?.any {
it.hasRoute(route = item.route::class)
} == true
NavigationBarItem( NavigationBarItem(
selected = selected, selected = selected,
onClick = { onClick = {
if (navBackStackEntry?.destination?.route == item.route) return@NavigationBarItem if (selected) return@NavigationBarItem
navController.navigate(item.route) { navController.navigate(item.route) {
// Pop up to the start destination of the graph to // Pop up to the start destination of the graph to
// avoid building up a large stack of destinations // avoid building up a large stack of destinations

View File

@ -1,9 +1,10 @@
package com.zaneschepke.wireguardautotunnel.ui.common.navigation package com.zaneschepke.wireguardautotunnel.ui.common.navigation
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import com.zaneschepke.wireguardautotunnel.ui.Screens
data class BottomNavItem( data class BottomNavItem(
val name: String, val name: String,
val route: String, val route: Screens,
val icon: ImageVector, val icon: ImageVector,
) )

View File

@ -53,6 +53,7 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationTextBox import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationTextBox
@ -68,7 +69,11 @@ import kotlinx.coroutines.delay
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable @Composable
fun ConfigScreen(tunnelId: Int, viewModel: ConfigViewModel, focusRequester: FocusRequester) { fun ConfigScreen(tunnelId: Int, focusRequester: FocusRequester) {
val viewModel = hiltViewModel<ConfigViewModel, ConfigViewModel.ConfigViewModelFactory> { factory ->
factory.create(tunnelId)
}
val context = LocalContext.current val context = LocalContext.current
val snackbar = SnackbarController.current val snackbar = SnackbarController.current
val clipboardManager: ClipboardManager = LocalClipboardManager.current val clipboardManager: ClipboardManager = LocalClipboardManager.current

View File

@ -17,7 +17,7 @@ import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
import com.zaneschepke.wireguardautotunnel.module.IoDispatcher import com.zaneschepke.wireguardautotunnel.module.IoDispatcher
import com.zaneschepke.wireguardautotunnel.ui.Screen import com.zaneschepke.wireguardautotunnel.ui.Screens
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController
import com.zaneschepke.wireguardautotunnel.ui.screens.config.model.PeerProxy import com.zaneschepke.wireguardautotunnel.ui.screens.config.model.PeerProxy
import com.zaneschepke.wireguardautotunnel.util.Constants import com.zaneschepke.wireguardautotunnel.util.Constants
@ -335,7 +335,7 @@ constructor(
SnackbarController.showMessage( SnackbarController.showMessage(
StringValue.StringResource(R.string.config_changes_saved), StringValue.StringResource(R.string.config_changes_saved),
) )
navController.navigate(Screen.Main.route) navController.navigate(Screens.Main)
}.onFailure { }.onFailure {
Timber.e(it) Timber.e(it)
val message = it.message?.substringAfter(":", missingDelimiterValue = "") val message = it.message?.substringAfter(":", missingDelimiterValue = "")

View File

@ -68,7 +68,7 @@ import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig
import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
import com.zaneschepke.wireguardautotunnel.ui.AppUiState import com.zaneschepke.wireguardautotunnel.ui.AppUiState
import com.zaneschepke.wireguardautotunnel.ui.Screen import com.zaneschepke.wireguardautotunnel.ui.Screens
import com.zaneschepke.wireguardautotunnel.ui.common.RowListItem import com.zaneschepke.wireguardautotunnel.ui.common.RowListItem
import com.zaneschepke.wireguardautotunnel.ui.common.dialog.InfoDialog import com.zaneschepke.wireguardautotunnel.ui.common.dialog.InfoDialog
import com.zaneschepke.wireguardautotunnel.ui.common.functions.rememberFileImportLauncherForResult import com.zaneschepke.wireguardautotunnel.ui.common.functions.rememberFileImportLauncherForResult
@ -235,7 +235,7 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel(), uiState: AppUiState,
onQrClick = { launchQrScanner() }, onQrClick = { launchQrScanner() },
onManualImportClick = { onManualImportClick = {
navController.navigate( navController.navigate(
"${Screen.Config.route}/${Constants.MANUAL_TUNNEL_CONFIG_ID}", Screens.Config(Constants.MANUAL_TUNNEL_CONFIG_ID),
) )
}, },
) )
@ -407,9 +407,11 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel(), uiState: AppUiState,
Row { Row {
IconButton( IconButton(
onClick = { onClick = {
navController.navigate( selectedTunnel?.let {
"${Screen.Option.route}/${selectedTunnel?.id}", navController.navigate(
) Screens.Option(it.id),
)
}
}, },
) { ) {
val icon = Icons.Rounded.Settings val icon = Icons.Rounded.Settings
@ -452,9 +454,11 @@ fun MainScreen(viewModel: MainViewModel = hiltViewModel(), uiState: AppUiState,
IconButton( IconButton(
onClick = { onClick = {
selectedTunnel = tunnel selectedTunnel = tunnel
navController.navigate( selectedTunnel?.let {
"${Screen.Option.route}/${selectedTunnel?.id}", navController.navigate(
) Screens.Option(it.id),
)
}
}, },
) { ) {
val icon = Icons.Rounded.Settings val icon = Icons.Rounded.Settings

View File

@ -50,7 +50,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.ui.AppUiState import com.zaneschepke.wireguardautotunnel.ui.AppUiState
import com.zaneschepke.wireguardautotunnel.ui.Screen import com.zaneschepke.wireguardautotunnel.ui.Screens
import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton
import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle
import com.zaneschepke.wireguardautotunnel.ui.common.config.SubmitConfigurationTextBox import com.zaneschepke.wireguardautotunnel.ui.common.config.SubmitConfigurationTextBox
@ -114,7 +114,7 @@ fun OptionsScreen(
) )
}, focusRequester, isVisible = true, onClick = { }, focusRequester, isVisible = true, onClick = {
navController.navigate( navController.navigate(
"${Screen.Config.route}/${config.id}", Screens.Config(config.id),
) )
}) })
}, },

View File

@ -8,7 +8,7 @@ import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController import androidx.navigation.NavController
import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.ui.AppViewModel import com.zaneschepke.wireguardautotunnel.ui.AppViewModel
import com.zaneschepke.wireguardautotunnel.ui.Screen import com.zaneschepke.wireguardautotunnel.ui.Screens
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController
import com.zaneschepke.wireguardautotunnel.util.StringValue import com.zaneschepke.wireguardautotunnel.util.StringValue
import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv
@ -36,11 +36,11 @@ fun PinLockScreen(navController: NavController, appViewModel: AppViewModel) {
onPinCorrect = { onPinCorrect = {
// pin is correct, navigate or hide pin lock // pin is correct, navigate or hide pin lock
if (context.isRunningOnTv()) { if (context.isRunningOnTv()) {
navController.navigate(Screen.Main.route) navController.navigate(Screens.Main)
} else { } else {
val isPopped = navController.popBackStack() val isPopped = navController.popBackStack()
if (!isPopped) { if (!isPopped) {
navController.navigate(Screen.Main.route) navController.navigate(Screens.Main)
} }
} }
}, },

View File

@ -69,7 +69,7 @@ import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
import com.zaneschepke.wireguardautotunnel.ui.AppUiState import com.zaneschepke.wireguardautotunnel.ui.AppUiState
import com.zaneschepke.wireguardautotunnel.ui.AppViewModel import com.zaneschepke.wireguardautotunnel.ui.AppViewModel
import com.zaneschepke.wireguardautotunnel.ui.Screen import com.zaneschepke.wireguardautotunnel.ui.Screens
import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton
import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle
import com.zaneschepke.wireguardautotunnel.ui.common.prompt.AuthorizationPrompt import com.zaneschepke.wireguardautotunnel.ui.common.prompt.AuthorizationPrompt
@ -581,7 +581,7 @@ fun SettingsScreen(
} else { } else {
// TODO may want to show a dialog before proceeding in the future // TODO may want to show a dialog before proceeding in the future
PinManager.initialize(WireGuardAutoTunnel.instance) PinManager.initialize(WireGuardAutoTunnel.instance)
navController.navigate(Screen.Lock.route) navController.navigate(Screens.Lock)
} }
}, },
) )

View File

@ -46,7 +46,7 @@ import androidx.navigation.NavController
import com.zaneschepke.wireguardautotunnel.BuildConfig import com.zaneschepke.wireguardautotunnel.BuildConfig
import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.ui.AppUiState import com.zaneschepke.wireguardautotunnel.ui.AppUiState
import com.zaneschepke.wireguardautotunnel.ui.Screen import com.zaneschepke.wireguardautotunnel.ui.Screens
import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv
import com.zaneschepke.wireguardautotunnel.util.extensions.launchSupportEmail import com.zaneschepke.wireguardautotunnel.util.extensions.launchSupportEmail
import com.zaneschepke.wireguardautotunnel.util.extensions.openWebUrl import com.zaneschepke.wireguardautotunnel.util.extensions.openWebUrl
@ -244,7 +244,7 @@ fun SupportScreen(navController: NavController, focusRequester: FocusRequester,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
) )
TextButton( TextButton(
onClick = { navController.navigate(Screen.Support.Logs.route) }, onClick = { navController.navigate(Screens.Logs) },
modifier = Modifier.padding(vertical = 5.dp), modifier = Modifier.padding(vertical = 5.dp),
) { ) {
Row( Row(

View File

@ -4,7 +4,7 @@ object Constants {
const val BASE_LOG_FILE_NAME = "wg_tunnel_logs" const val BASE_LOG_FILE_NAME = "wg_tunnel_logs"
const val LOG_BUFFER_SIZE = 3_000L const val LOG_BUFFER_SIZE = 3_000L
const val MANUAL_TUNNEL_CONFIG_ID = "0" const val MANUAL_TUNNEL_CONFIG_ID = 0
const val BATTERY_SAVER_WATCHER_WAKE_LOCK_TIMEOUT = 10 * 60 * 1_000L // 10 minutes const val BATTERY_SAVER_WATCHER_WAKE_LOCK_TIMEOUT = 10 * 60 * 1_000L // 10 minutes
const val WATCHER_COLLECTION_DELAY = 3_000L const val WATCHER_COLLECTION_DELAY = 3_000L