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.LoginRoute
import com.flagship.abox.manager.ui.login.LoginViewModel import com.flagship.abox.manager.ui.login.LoginViewModel
import com.flagship.abox.manager.ui.provider.ProviderSelectionRoute 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.AppSessionUiState
import com.flagship.abox.manager.ui.session.AppSessionViewModel import com.flagship.abox.manager.ui.session.AppSessionViewModel
import com.flagship.abox.manager.ui.session.SessionActionsViewModel import com.flagship.abox.manager.ui.session.SessionActionsViewModel
@@ -63,6 +64,9 @@ fun ABoxManagerApp(
onLogout = sessionActionsViewModel::logout, onLogout = sessionActionsViewModel::logout,
actionInProgress = actionState.inProgress, actionInProgress = actionState.inProgress,
errorMessage = actionState.errorMessage, 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.lazy.items
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons 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.material.icons.filled.Delete
import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChip
import androidx.compose.material3.Button import androidx.compose.material3.Button
@@ -74,7 +74,7 @@ fun SceneEditorScreen(
}, },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { 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.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons 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.Check
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Button import androidx.compose.material3.Button
@@ -56,7 +56,7 @@ fun SceneExecutionScreen(
title = { Text(stringResource(R.string.scene_execution_title)) }, title = { Text(stringResource(R.string.scene_execution_title)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { 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 package com.flagship.abox.manager.ui.scene
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavGraphBuilder import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument import androidx.navigation.navArgument
import com.flagship.abox.manager.domain.SceneId 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. * carry the scene id as a path segment so deep linking works without manual argument parsing.
*/ */
object SceneRoutes { object SceneRoutes {
@@ -21,6 +25,36 @@ object SceneRoutes {
fun executionFor(sceneId: SceneId): String = "scene/execution/${sceneId.value}" 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( fun NavGraphBuilder.sceneListDestination(
onAddScene: () -> Unit, onAddScene: () -> Unit,
onEditScene: (SceneId) -> Unit, onEditScene: (SceneId) -> Unit,
+1
View File
@@ -11,3 +11,4 @@ dependencies {
testImplementation(libs.junit) testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test) testImplementation(libs.kotlinx.coroutines.test)
} }