feat: add temporary infrared navigation

This commit is contained in:
2026-08-24 11:37:13 +08:00
parent 26ff049601
commit 4043d9f0a6
4 changed files with 78 additions and 3 deletions
@@ -0,0 +1,26 @@
package com.flagship.abox.manager.ui
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.flagship.abox.manager.MainActivity
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ABoxManagerAppTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()
@Test
fun opensInfraredControlScreenFromFoundationScreen() {
composeTestRule.onNodeWithText("Infrared Control").performClick()
composeTestRule.onNodeWithTag("infrared_mode_label").assertIsDisplayed()
composeTestRule.onNodeWithTag("infrared_device_name_input").assertIsDisplayed()
}
}
@@ -7,33 +7,51 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
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.R
import com.flagship.abox.manager.designsystem.ABoxButton
import com.flagship.abox.manager.designsystem.ABoxSurface
import com.flagship.abox.manager.designsystem.ABoxTheme
import com.flagship.abox.manager.infrared.ui.InfraredControlRoute
private const val FOUNDATION_ROUTE = "foundation"
private const val PLACEHOLDER_ROUTE = "placeholder"
private const val INFRARED_ROUTE = "infrared/{profileId}"
private const val TEMPORARY_ABOX_PROFILE_ID = "abox"
@Composable
fun ABoxManagerApp() {
ABoxTheme {
ABoxSurface(modifier = Modifier.fillMaxSize()) {
val navController = rememberNavController()
var sessionMessage by remember { mutableStateOf<String?>(null) }
NavHost(
navController = navController,
startDestination = FOUNDATION_ROUTE,
) {
composable(FOUNDATION_ROUTE) {
FoundationScreen(onContinue = { navController.navigate(PLACEHOLDER_ROUTE) })
FoundationScreen(
sessionInvalidMessage = sessionMessage,
onContinue = { navController.navigate(PLACEHOLDER_ROUTE) },
onOpenInfrared = {
sessionMessage = null
navController.navigate("infrared/$TEMPORARY_ABOX_PROFILE_ID")
},
)
}
composable(PLACEHOLDER_ROUTE) {
MessageScreen(
@@ -41,13 +59,32 @@ fun ABoxManagerApp() {
description = stringResource(R.string.placeholder_description),
)
}
composable(
route = INFRARED_ROUTE,
arguments = listOf(
navArgument("profileId") { type = NavType.StringType },
),
) {
val sessionInvalidText = stringResource(R.string.infrared_session_invalid_message)
InfraredControlRoute(
onBack = { navController.popBackStack() },
onSessionInvalid = {
sessionMessage = sessionInvalidText
navController.popBackStack(FOUNDATION_ROUTE, inclusive = false)
},
)
}
}
}
}
}
@Composable
private fun FoundationScreen(onContinue: () -> Unit) {
private fun FoundationScreen(
sessionInvalidMessage: String?,
onContinue: () -> Unit,
onOpenInfrared: () -> Unit,
) {
Column(
modifier = Modifier
.fillMaxSize()
@@ -57,7 +94,7 @@ private fun FoundationScreen(onContinue: () -> Unit) {
) {
MessageScreen(
title = stringResource(R.string.foundation_title),
description = stringResource(R.string.foundation_description),
description = sessionInvalidMessage ?: stringResource(R.string.foundation_description),
)
ABoxButton(
onClick = onContinue,
@@ -67,6 +104,14 @@ private fun FoundationScreen(onContinue: () -> Unit) {
) {
Text(stringResource(R.string.continue_action))
}
ABoxButton(
onClick = onOpenInfrared,
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp),
) {
Text(stringResource(R.string.infrared_control_action))
}
}
}
@@ -5,4 +5,6 @@
<string name="continue_action">继续</string>
<string name="placeholder_title">功能模块可以开始开发</string>
<string name="placeholder_description">设备、红外和情景页面将由对应模块负责人实现。</string>
<string name="infrared_control_action">红外控制</string>
<string name="infrared_session_invalid_message">ABox 会话未认证,请先登录。</string>
</resources>
@@ -5,4 +5,6 @@
<string name="continue_action">Continue</string>
<string name="placeholder_title">Feature development can start</string>
<string name="placeholder_description">Device, infrared and scene screens will be added by their module owners.</string>
<string name="infrared_control_action">Infrared Control</string>
<string name="infrared_session_invalid_message">ABox session is not authenticated. Please log in first.</string>
</resources>