feat(scene): add scene editor, executor and fakes (phase 1) #5

Merged
KremeCN merged 10 commits from feat/scene-editor into main 2026-08-25 20:20:19 +08:00
5 changed files with 44 additions and 5 deletions
Showing only changes of commit 6b4ef585fb - Show all commits
@@ -17,6 +17,7 @@ import com.flagship.abox.manager.designsystem.ABoxTheme
import com.flagship.abox.manager.ui.login.LoginRoute
import com.flagship.abox.manager.ui.login.LoginViewModel
import com.flagship.abox.manager.ui.provider.ProviderSelectionRoute
import com.flagship.abox.manager.ui.scene.SceneNavHost
import com.flagship.abox.manager.ui.session.AppSessionUiState
import com.flagship.abox.manager.ui.session.AppSessionViewModel
import com.flagship.abox.manager.ui.session.SessionActionsViewModel
@@ -63,6 +64,9 @@ fun ABoxManagerApp(
onLogout = sessionActionsViewModel::logout,
actionInProgress = actionState.inProgress,
errorMessage = actionState.errorMessage,
scenesSlot = {
SceneNavHost()
},
)
}
}
@@ -13,7 +13,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Button
@@ -74,7 +74,7 @@ fun SceneEditorScreen(
},
navigationIcon = {
IconButton(onClick = onBack) {
Icon(Icons.Filled.ArrowBack, contentDescription = stringResource(R.string.scene_back))
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.scene_back))
}
},
)
@@ -12,7 +12,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Button
@@ -56,7 +56,7 @@ fun SceneExecutionScreen(
title = { Text(stringResource(R.string.scene_execution_title)) },
navigationIcon = {
IconButton(onClick = onBack) {
Icon(Icons.Filled.ArrowBack, contentDescription = stringResource(R.string.scene_back))
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.scene_back))
}
},
)
@@ -1,14 +1,18 @@
package com.flagship.abox.manager.ui.scene
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.flagship.abox.manager.domain.SceneId
/**
* Scene navigation routes. [SceneListRoute] is the entry point; the editor and execution routes
* Scene navigation routes. [SceneRoutes.LIST] is the entry point; the editor and execution routes
* carry the scene id as a path segment so deep linking works without manual argument parsing.
*/
object SceneRoutes {
@@ -21,6 +25,36 @@ object SceneRoutes {
fun executionFor(sceneId: SceneId): String = "scene/execution/${sceneId.value}"
}
/**
* Embedded navigation host for the scenes tab in [MainAppShell].
*/
@Composable
fun SceneNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
navController = navController,
startDestination = SceneRoutes.LIST,
modifier = modifier,
) {
sceneListDestination(
onAddScene = { navController.navigate(SceneRoutes.EDITOR) },
onEditScene = { sceneId -> navController.navigate(SceneRoutes.editorFor(sceneId)) },
onExecuteScene = { sceneId -> navController.navigate(SceneRoutes.executionFor(sceneId)) },
)
sceneEditorDestination(
onBack = { navController.popBackStack() },
onSaved = {
navController.popBackStack(SceneRoutes.LIST, inclusive = false)
},
)
sceneExecutionDestination(
onBack = { navController.popBackStack() },
)
}
}
fun NavGraphBuilder.sceneListDestination(
onAddScene: () -> Unit,
onEditScene: (SceneId) -> Unit,
+1
View File
@@ -11,3 +11,4 @@ dependencies {
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
}