diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml index efde6168..e7b6dcbd 100644 --- a/app/detekt-baseline.xml +++ b/app/detekt-baseline.xml @@ -2,7 +2,6 @@ - LongMethod:AslNavHost.kt$@Composable fun AslNavHost( startDestination: String, openProjectId: String? = null, onOpenProjectConsumed: () -> Unit = {}, navController: NavHostController = rememberNavController(), ) MatchingDeclarationName:BlockingErrorScreen.kt$BlockingErrorType ParameterNaming:AslNavHost.kt$onOpenProjectConsumed diff --git a/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/AslNavHost.kt b/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/AslNavHost.kt index 72c9e5f6..15d932e1 100644 --- a/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/AslNavHost.kt +++ b/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/AslNavHost.kt @@ -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, @@ -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("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("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("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() } } diff --git a/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/NavGraphs.kt b/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/NavGraphs.kt new file mode 100644 index 00000000..f772c262 --- /dev/null +++ b/app/src/main/java/com/ahmadkharfan/androidstudiolite/navigation/NavGraphs.kt @@ -0,0 +1,297 @@ +package com.ahmadkharfan.androidstudiolite.navigation + +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.compose.composable +import androidx.navigation.navArgument +import com.ahmadkharfan.androidstudiolite.domain.model.GitDiffTarget +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.crashreport.CrashReportRoute +import com.ahmadkharfan.androidstudiolite.feature.createproject.CreateProjectRoute +import com.ahmadkharfan.androidstudiolite.feature.editor.EditorNavigation +import com.ahmadkharfan.androidstudiolite.feature.editor.EditorRoute +import com.ahmadkharfan.androidstudiolite.feature.editor.git.conflict.GitConflictRoute +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.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.gitauth.GitAuthSettingsRoute +import com.ahmadkharfan.androidstudiolite.feature.settings.root.SettingsRootRoute +import com.ahmadkharfan.androidstudiolite.feature.terminal.TerminalRoute + +internal fun NavGraphBuilder.onboardingGraph(navController: NavHostController) { + 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 } } + }, + ) + } +} + +internal fun NavGraphBuilder.projectsGraph(navController: NavHostController) { + composable(Routes.HUB) { backStackEntry -> + val pickedFolder by backStackEntry.savedStateHandle + .getStateFlow("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("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() + }, + ) + } +} + +internal fun NavGraphBuilder.utilityGraph(navController: NavHostController) { + composable(Routes.TERMINAL) { + TerminalRoute(onBack = { navController.popBackStack() }) + } + + composable(Routes.CRASH_REPORT) { + CrashReportRoute( + onRestart = { navController.popBackStack() }, + onClose = { navController.popBackStack() }, + ) + } +} + +internal fun NavGraphBuilder.editorGraph(navController: NavHostController) { + editorDestination(navController) + gitDiffDestination(navController) + gitHistoryDestination(navController) + gitBlameDestination(navController) + gitRefsDestination(navController) + gitConflictsDestination(navController) +} + +private fun NavGraphBuilder.editorDestination(navController: NavHostController) { + composable( + route = Routes.EDITOR_PATTERN, + arguments = listOf(navArgument("projectId") { }), + ) { backStackEntry -> + val projectId = backStackEntry.arguments?.getString("projectId").orEmpty() + val conflictPath by backStackEntry.savedStateHandle + .getStateFlow("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 }, + ) + } +} + +private fun NavGraphBuilder.gitDiffDestination(navController: NavHostController) { + 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, + ) + } +} + +private fun NavGraphBuilder.gitHistoryDestination(navController: NavHostController) { + 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), + ) + }, + ) + } +} + +private fun NavGraphBuilder.gitBlameDestination(navController: NavHostController) { + 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() }, + ) + } +} + +private fun NavGraphBuilder.gitRefsDestination(navController: NavHostController) { + 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() }, + ) + } +} + +private fun NavGraphBuilder.gitConflictsDestination(navController: NavHostController) { + 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() + }, + ) + } +} + +internal fun NavGraphBuilder.settingsGraph(navController: NavHostController) { + 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() }) + } +} + +internal fun NavGraphBuilder.deviceSupportGraph() { + 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) + } +}