feat(scene): add scene editor, executor and fakes (phase 1) #5
@@ -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))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -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,
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ dependencies {
|
|||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
testImplementation(libs.kotlinx.coroutines.test)
|
testImplementation(libs.kotlinx.coroutines.test)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user