Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>LongMethod:AslNavHost.kt$@Composable fun AslNavHost( startDestination: String, openProjectId: String? = null, onOpenProjectConsumed: () -&gt; Unit = {}, navController: NavHostController = rememberNavController(), )</ID>
<ID>MatchingDeclarationName:BlockingErrorScreen.kt$BlockingErrorType</ID>
<ID>ParameterNaming:AslNavHost.kt$onOpenProjectConsumed</ID>
</CurrentIssues>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,12 @@ package com.ahmadkharfan.androidstudiolite.navigation

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.ahmadkharfan.androidstudiolite.feature.acsmissing.AcsMissingRoute
import com.ahmadkharfan.androidstudiolite.feature.blockingerror.BlockingErrorRoute
import com.ahmadkharfan.androidstudiolite.feature.blockingerror.BlockingErrorType
import com.ahmadkharfan.androidstudiolite.feature.createproject.CreateProjectRoute
import com.ahmadkharfan.androidstudiolite.feature.crashreport.CrashReportRoute
import com.ahmadkharfan.androidstudiolite.feature.editor.EditorNavigation
import com.ahmadkharfan.androidstudiolite.feature.editor.EditorRoute
import com.ahmadkharfan.androidstudiolite.feature.editor.git.diff.GitDiffRoute
import com.ahmadkharfan.androidstudiolite.feature.editor.git.history.GitBlameRoute
import com.ahmadkharfan.androidstudiolite.feature.editor.git.history.GitHistoryRoute
import com.ahmadkharfan.androidstudiolite.feature.editor.git.refs.GitRefsMode
import com.ahmadkharfan.androidstudiolite.feature.editor.git.refs.GitRefsRoute
import com.ahmadkharfan.androidstudiolite.feature.editor.git.conflict.GitConflictRoute
import com.ahmadkharfan.androidstudiolite.domain.model.GitDiffTarget
import com.ahmadkharfan.androidstudiolite.feature.folderpicker.FolderPickerRoute
import com.ahmadkharfan.androidstudiolite.feature.hub.HubRoute
import com.ahmadkharfan.androidstudiolite.feature.onboarding.complete.CompleteRoute
import com.ahmadkharfan.androidstudiolite.feature.onboarding.howitworks.HowItWorksRoute
import com.ahmadkharfan.androidstudiolite.feature.onboarding.permissions.PermissionsRoute
import com.ahmadkharfan.androidstudiolite.feature.onboarding.welcome.WelcomeRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.about.AboutRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.aiagent.AiAgentSettingsRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.buildrun.BuildRunSettingsRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.editor.EditorSettingsRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.general.GeneralRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.root.SettingsRootRoute
import com.ahmadkharfan.androidstudiolite.feature.settings.gitauth.GitAuthSettingsRoute
import com.ahmadkharfan.androidstudiolite.feature.terminal.TerminalRoute

@Composable
fun AslNavHost(
startDestination: String,
Expand All @@ -64,233 +34,11 @@ fun AslNavHost(
popEnterTransition = { aslPopEnter() },
popExitTransition = { aslPopExit() },
) {
composable(Routes.ONBOARDING_WELCOME) {
WelcomeRoute(onGetStarted = { navController.navigate(Routes.ONBOARDING_HOW_IT_WORKS) })
}

composable(Routes.ONBOARDING_HOW_IT_WORKS) {
HowItWorksRoute(onContinue = { navController.navigate(Routes.ONBOARDING_PERMISSIONS) })
}

composable(Routes.ONBOARDING_PERMISSIONS) {
PermissionsRoute(onContinue = { navController.navigate(Routes.ONBOARDING_COMPLETE) })
}
composable(Routes.ONBOARDING_COMPLETE) {
CompleteRoute(
onOpenHub = {
navController.navigate(Routes.HUB) { popUpTo(Routes.ONBOARDING_WELCOME) { inclusive = true } }
},
)
}

composable(Routes.HUB) { backStackEntry ->
val pickedFolder by backStackEntry.savedStateHandle
.getStateFlow<String?>("picked_folder", null)
.collectAsState()
HubRoute(
onOpenProject = { id -> navController.navigate(Routes.editor(id)) },
onCreateProject = { navController.navigate(Routes.CREATE_PROJECT) },
onOpenPreferences = { navController.navigate(Routes.SETTINGS_ROOT) },
onBrowseFolder = { navController.navigate(Routes.FOLDER_PICKER) },
pickedFolder = pickedFolder,
onPickedFolderConsumed = { backStackEntry.savedStateHandle["picked_folder"] = null },
)
}

composable(Routes.CREATE_PROJECT) { backStackEntry ->
val pickedFolder by backStackEntry.savedStateHandle
.getStateFlow<String?>("picked_folder", null)
.collectAsState()
CreateProjectRoute(
onBack = { navController.popBackStack(Routes.CREATE_PROJECT, inclusive = true) },
onCreated = { id ->
navController.navigate(Routes.editor(id)) { popUpTo(Routes.HUB) }
},
onBrowseLocation = { navController.navigate(Routes.FOLDER_PICKER) },
pickedFolder = pickedFolder,
onPickedFolderConsumed = { backStackEntry.savedStateHandle["picked_folder"] = null },
)
}

composable(Routes.FOLDER_PICKER) {
FolderPickerRoute(
onCancel = { navController.popBackStack() },
onFolderSelected = { path ->
navController.previousBackStackEntry?.savedStateHandle?.set("picked_folder", path)
navController.popBackStack()
},
)
}

composable(Routes.TERMINAL) {
TerminalRoute(onBack = { navController.popBackStack() })
}

composable(Routes.CRASH_REPORT) {
CrashReportRoute(
onRestart = { navController.popBackStack() },
onClose = { navController.popBackStack() },
)
}

composable(
route = Routes.EDITOR_PATTERN,
arguments = listOf(navArgument("projectId") { }),
) { backStackEntry ->
val projectId = backStackEntry.arguments?.getString("projectId").orEmpty()
val conflictPath by backStackEntry.savedStateHandle
.getStateFlow<String?>("git_conflict_path", null).collectAsState()
EditorRoute(
projectId = projectId,
navigation = EditorNavigation(
onCloseProject = {
if (!navController.popBackStack(Routes.HUB, inclusive = false)) {
navController.navigate(Routes.HUB) {
popUpTo(navController.graph.id) { inclusive = true }
launchSingleTop = true
}
}
},
onOpenSettings = { navController.navigate(Routes.SETTINGS_ROOT) },
onOpenAiAgentSettings = { navController.navigate(Routes.SETTINGS_AI_AGENT) },
onOpenGitDiff = { path, target -> navController.navigate(Routes.gitDiff(projectId, path, target)) },
onOpenGitHistory = { path -> navController.navigate(Routes.gitHistory(projectId, path)) },
onOpenGitBlame = { path -> navController.navigate(Routes.gitBlame(projectId, path)) },
onOpenBranches = { navController.navigate(Routes.gitRefs(projectId, GitRefsMode.BRANCHES.name)) },
onOpenTags = { navController.navigate(Routes.gitRefs(projectId, GitRefsMode.TAGS.name)) },
onOpenStashes = { navController.navigate(Routes.gitRefs(projectId, GitRefsMode.STASHES.name)) },
onOpenHistory = { navController.navigate(Routes.gitHistory(projectId)) },
onOpenConflicts = { navController.navigate(Routes.gitConflicts(projectId)) },
),
openConflictPath = conflictPath,
onConflictPathOpened = { backStackEntry.savedStateHandle["git_conflict_path"] = null },
)
}

composable(
route = Routes.GIT_DIFF_PATTERN,
arguments = listOf(
navArgument("projectId") { },
navArgument("target") { },
navArgument("path") { },
navArgument("commitId") { },
),
) { backStackEntry ->
val projectId = backStackEntry.arguments?.getString("projectId").orEmpty()
val path = backStackEntry.arguments?.getString("path").orEmpty()
val commitId = backStackEntry.arguments?.getString("commitId")?.takeIf { it.isNotBlank() }
val target = runCatching {
GitDiffTarget.valueOf(backStackEntry.arguments?.getString("target").orEmpty())
}.getOrDefault(GitDiffTarget.INDEX_TO_WORKTREE)
GitDiffRoute(
projectId = projectId,
path = path,
target = target,
onBack = { navController.popBackStack() },
commitId = commitId,
)
}

composable(
route = Routes.GIT_HISTORY_PATTERN,
arguments = listOf(navArgument("projectId") { }, navArgument("path") { }),
) { backStackEntry ->
val projectId = backStackEntry.arguments?.getString("projectId").orEmpty()
val path = backStackEntry.arguments?.getString("path")?.takeIf { it.isNotBlank() }
GitHistoryRoute(
projectId = projectId,
path = path,
onBack = { navController.popBackStack() },
onOpenDiff = { file, commit ->
navController.navigate(
Routes.gitDiff(projectId, file, GitDiffTarget.COMMIT_TO_PARENT, commit),
)
},
)
}

composable(
route = Routes.GIT_BLAME_PATTERN,
arguments = listOf(navArgument("projectId") { }, navArgument("path") { }),
) { backStackEntry ->
GitBlameRoute(
projectId = backStackEntry.arguments?.getString("projectId").orEmpty(),
path = backStackEntry.arguments?.getString("path").orEmpty(),
onBack = { navController.popBackStack() },
)
}

composable(
route = Routes.GIT_REFS_PATTERN,
arguments = listOf(navArgument("projectId") { }, navArgument("mode") { }),
) { backStackEntry ->
val mode = runCatching {
GitRefsMode.valueOf(backStackEntry.arguments?.getString("mode").orEmpty())
}.getOrDefault(GitRefsMode.BRANCHES)
GitRefsRoute(
projectId = backStackEntry.arguments?.getString("projectId").orEmpty(),
mode = mode,
onBack = { navController.popBackStack() },
)
}

composable(
route = Routes.GIT_CONFLICTS_PATTERN,
arguments = listOf(navArgument("projectId") { }),
) { backStackEntry ->
val projectId = backStackEntry.arguments?.getString("projectId").orEmpty()
GitConflictRoute(
projectId = projectId,
onBack = { navController.popBackStack() },
onOpenEditor = { path ->
navController.previousBackStackEntry?.savedStateHandle?.set("git_conflict_path", path)
navController.popBackStack()
},
)
}

composable(Routes.SETTINGS_ROOT) {
SettingsRootRoute(
onBack = { navController.popBackStack() },
onOpenGeneral = { navController.navigate(Routes.SETTINGS_GENERAL) },
onOpenEditor = { navController.navigate(Routes.SETTINGS_EDITOR) },
onOpenAiAgent = { navController.navigate(Routes.SETTINGS_AI_AGENT) },
onOpenBuildRun = { navController.navigate(Routes.SETTINGS_BUILD_RUN) },
onOpenGitAuth = { navController.navigate(Routes.SETTINGS_GIT_AUTH) },
onOpenAbout = { navController.navigate(Routes.SETTINGS_ABOUT) },
)
}
composable(Routes.SETTINGS_GENERAL) {
GeneralRoute(onBack = { navController.popBackStack() })
}
composable(Routes.SETTINGS_EDITOR) {
EditorSettingsRoute(onBack = { navController.popBackStack() })
}
composable(Routes.SETTINGS_AI_AGENT) {
AiAgentSettingsRoute(onBack = { navController.popBackStack() })
}
composable(Routes.SETTINGS_BUILD_RUN) {
BuildRunSettingsRoute(onBack = { navController.popBackStack() })
}
composable(Routes.SETTINGS_GIT_AUTH) {
GitAuthSettingsRoute(onBack = { navController.popBackStack() })
}
composable(Routes.SETTINGS_ABOUT) {
AboutRoute(onBack = { navController.popBackStack() })
}
composable(Routes.ACS_MISSING) {
AcsMissingRoute()
}
composable(
route = Routes.BLOCKING_ERROR_PATTERN,
arguments = listOf(navArgument("type") { }),
) { backStackEntry ->
val type = when (backStackEntry.arguments?.getString("type")) {
"sdcard" -> BlockingErrorType.SdCardInstall
"user" -> BlockingErrorType.SecondaryUser
else -> BlockingErrorType.UnsupportedDevice
}
BlockingErrorRoute(type = type)
}
onboardingGraph(navController)
projectsGraph(navController)
utilityGraph(navController)
editorGraph(navController)
settingsGraph(navController)
deviceSupportGraph()
}
}
Loading
Loading