1package com.parseable.android.ui.navigation
3import androidx.compose.runtime.Composable
4import androidx.navigation.NavHostController
5import androidx.navigation.NavType
6import androidx.navigation.compose.NavHost
7import androidx.navigation.compose.composable
8import androidx.navigation.navArgument
9import androidx.navigation.navDeepLink
10import androidx.compose.runtime.LaunchedEffect
11import com.parseable.android.data.repository.ParseableRepository
12import com.parseable.android.ui.screens.alerts.AlertsScreen
13import com.parseable.android.ui.screens.login.LoginScreen
14import com.parseable.android.ui.screens.logviewer.LogViewerScreen
15import com.parseable.android.ui.screens.logviewer.StreamInfoScreen
16import com.parseable.android.ui.screens.about.AboutScreen
17import com.parseable.android.ui.screens.settings.SettingsScreen
18import com.parseable.android.ui.screens.streams.StreamsScreen
19import java.net.URLDecoder
20import java.net.URLEncoder
23 const val LOGIN = "login"
24 const val STREAMS = "streams"
25 const val LOG_VIEWER = "log_viewer/{streamName}"
26 const val STREAM_INFO = "stream_info/{streamName}"
27 const val ALERTS = "alerts"
28 const val SETTINGS = "settings"
29 const val ABOUT = "about"
31 fun login(sessionExpired: Boolean = false) =
32 if (sessionExpired) "login?sessionExpired=true" else LOGIN
33 fun logViewer(streamName: String) =
34 "log_viewer/${URLEncoder.encode(streamName, "UTF-8")}"
35 fun streamInfo(streamName: String) =
36 "stream_info/${URLEncoder.encode(streamName, "UTF-8")}"
41 navController: NavHostController,
42 startDestination: String,
43 repository: ParseableRepository,
46 navController = navController,
47 startDestination = startDestination,
50 route = "${Routes.LOGIN}?sessionExpired={sessionExpired}",
51 arguments = listOf(navArgument("sessionExpired") {
52 type = NavType.BoolType
56 val sessionExpired = backStackEntry.arguments?.getBoolean("sessionExpired") ?: false
59 navController.navigate(Routes.STREAMS) {
60 popUpTo(Routes.LOGIN) { inclusive = true }
63 sessionExpired = sessionExpired,
68 route = Routes.STREAMS,
69 deepLinks = listOf(navDeepLink { uriPattern = "parseable://streams" }),
71 if (!repository.isConfigured) {
72 LaunchedEffect(Unit) {
73 navController.navigate(Routes.LOGIN) {
74 popUpTo(0) { inclusive = true }
80 onStreamClick = { streamName ->
81 navController.navigate(Routes.logViewer(streamName)) {
82 launchSingleTop = true
86 navController.navigate(Routes.ALERTS) {
87 launchSingleTop = true
91 navController.navigate(Routes.SETTINGS) {
92 launchSingleTop = true
96 navController.navigate(Routes.LOGIN) {
97 popUpTo(0) { inclusive = true }
104 route = Routes.LOG_VIEWER,
105 arguments = listOf(navArgument("streamName") { type = NavType.StringType }),
106 deepLinks = listOf(navDeepLink { uriPattern = "parseable://stream/{streamName}" }),
107 ) { backStackEntry ->
108 // Guard: redirect to login if the API client isn't configured
109 if (!repository.isConfigured) {
110 LaunchedEffect(Unit) {
111 navController.navigate(Routes.LOGIN) {
112 popUpTo(0) { inclusive = true }
117 val streamName = URLDecoder.decode(
118 backStackEntry.arguments?.getString("streamName") ?: "", "UTF-8"
121 streamName = streamName,
122 onBack = { navController.popBackStack() },
123 onStreamInfo = { name ->
124 navController.navigate(Routes.streamInfo(name)) {
125 launchSingleTop = true
132 route = Routes.STREAM_INFO,
133 arguments = listOf(navArgument("streamName") { type = NavType.StringType }),
134 ) { backStackEntry ->
135 val streamName = URLDecoder.decode(
136 backStackEntry.arguments?.getString("streamName") ?: "", "UTF-8"
139 streamName = streamName,
140 onBack = { navController.popBackStack() },
142 navController.popBackStack(Routes.STREAMS, inclusive = false)
148 route = Routes.ALERTS,
149 deepLinks = listOf(navDeepLink { uriPattern = "parseable://alerts" }),
151 if (!repository.isConfigured) {
152 LaunchedEffect(Unit) {
153 navController.navigate(Routes.LOGIN) {
154 popUpTo(0) { inclusive = true }
160 onBack = { navController.popBackStack() },
164 composable(Routes.SETTINGS) {
165 if (!repository.isConfigured) {
166 LaunchedEffect(Unit) {
167 navController.navigate(Routes.LOGIN) {
168 popUpTo(0) { inclusive = true }
174 onBack = { navController.popBackStack() },
176 navController.navigate(Routes.ABOUT) {
177 launchSingleTop = true
183 composable(Routes.ABOUT) {
184 if (!repository.isConfigured) {
185 LaunchedEffect(Unit) {
186 navController.navigate(Routes.LOGIN) {
187 popUpTo(0) { inclusive = true }
193 onBack = { navController.popBackStack() },
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list