Limit feature to device list component
This commit is contained in:
@@ -19,8 +19,6 @@ import com.flagship.abox.manager.R
|
|||||||
import com.flagship.abox.manager.designsystem.ABoxButton
|
import com.flagship.abox.manager.designsystem.ABoxButton
|
||||||
import com.flagship.abox.manager.designsystem.ABoxSurface
|
import com.flagship.abox.manager.designsystem.ABoxSurface
|
||||||
import com.flagship.abox.manager.designsystem.ABoxTheme
|
import com.flagship.abox.manager.designsystem.ABoxTheme
|
||||||
import com.flagship.abox.manager.ui.devicecontrol.DEVICE_LIST_ROUTE
|
|
||||||
import com.flagship.abox.manager.ui.devicecontrol.deviceControlGraph
|
|
||||||
|
|
||||||
private const val FOUNDATION_ROUTE = "foundation"
|
private const val FOUNDATION_ROUTE = "foundation"
|
||||||
private const val PLACEHOLDER_ROUTE = "placeholder"
|
private const val PLACEHOLDER_ROUTE = "placeholder"
|
||||||
@@ -35,10 +33,7 @@ fun ABoxManagerApp() {
|
|||||||
startDestination = FOUNDATION_ROUTE,
|
startDestination = FOUNDATION_ROUTE,
|
||||||
) {
|
) {
|
||||||
composable(FOUNDATION_ROUTE) {
|
composable(FOUNDATION_ROUTE) {
|
||||||
FoundationScreen(
|
FoundationScreen(onContinue = { navController.navigate(PLACEHOLDER_ROUTE) })
|
||||||
onContinue = { navController.navigate(PLACEHOLDER_ROUTE) },
|
|
||||||
onOpenDeviceControl = { navController.navigate(DEVICE_LIST_ROUTE) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
composable(PLACEHOLDER_ROUTE) {
|
composable(PLACEHOLDER_ROUTE) {
|
||||||
MessageScreen(
|
MessageScreen(
|
||||||
@@ -46,17 +41,13 @@ fun ABoxManagerApp() {
|
|||||||
description = stringResource(R.string.placeholder_description),
|
description = stringResource(R.string.placeholder_description),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
deviceControlGraph(navController)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FoundationScreen(
|
private fun FoundationScreen(onContinue: () -> Unit) {
|
||||||
onContinue: () -> Unit,
|
|
||||||
onOpenDeviceControl: () -> Unit,
|
|
||||||
) {
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
@@ -76,14 +67,6 @@ private fun FoundationScreen(
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.continue_action))
|
Text(stringResource(R.string.continue_action))
|
||||||
}
|
}
|
||||||
ABoxButton(
|
|
||||||
onClick = onOpenDeviceControl,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 12.dp),
|
|
||||||
) {
|
|
||||||
Text("打开设备控制 Kotlin 版")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-92
@@ -1,92 +0,0 @@
|
|||||||
package com.flagship.abox.manager.ui.devicecontrol
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedButton
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.flagship.abox.manager.designsystem.ABoxButton
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun DevicePageScaffold(
|
|
||||||
title: String,
|
|
||||||
description: String,
|
|
||||||
onBackClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
content: @Composable ColumnScope.() -> Unit,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier.padding(32.dp),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = title,
|
|
||||||
style = MaterialTheme.typography.headlineLarge,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = description,
|
|
||||||
modifier = Modifier.padding(top = 12.dp, bottom = 24.dp),
|
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
content()
|
|
||||||
OutlinedButton(
|
|
||||||
onClick = onBackClick,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 24.dp),
|
|
||||||
) {
|
|
||||||
Text("返回设备列表")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun PrimaryActionButton(
|
|
||||||
text: String,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
ABoxButton(
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
) {
|
|
||||||
Text(text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TwoColumnActions(
|
|
||||||
leftText: String,
|
|
||||||
rightText: String,
|
|
||||||
onLeftClick: () -> Unit,
|
|
||||||
onRightClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
|
||||||
) {
|
|
||||||
PrimaryActionButton(
|
|
||||||
text = leftText,
|
|
||||||
onClick = onLeftClick,
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
)
|
|
||||||
PrimaryActionButton(
|
|
||||||
text = rightText,
|
|
||||||
onClick = onRightClick,
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
package com.flagship.abox.manager.ui.devicecontrol
|
|
||||||
|
|
||||||
import androidx.navigation.NavGraphBuilder
|
|
||||||
import androidx.navigation.NavHostController
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
|
|
||||||
const val DEVICE_LIST_ROUTE = "device_list"
|
|
||||||
private const val SOCKET_ROUTE = "device_socket"
|
|
||||||
private const val TH_ROUTE = "device_temperature_humidity"
|
|
||||||
private const val INFRARED_ROUTE = "device_infrared"
|
|
||||||
|
|
||||||
fun NavGraphBuilder.deviceControlGraph(navController: NavHostController) {
|
|
||||||
composable(DEVICE_LIST_ROUTE) {
|
|
||||||
DeviceListScreen(
|
|
||||||
onSocketClick = { navController.navigate(SOCKET_ROUTE) },
|
|
||||||
onTemperatureHumidityClick = { navController.navigate(TH_ROUTE) },
|
|
||||||
onInfraredClick = { navController.navigate(INFRARED_ROUTE) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
composable(SOCKET_ROUTE) {
|
|
||||||
SocketControlScreen(onBackClick = navController::popBackStack)
|
|
||||||
}
|
|
||||||
composable(TH_ROUTE) {
|
|
||||||
TemperatureHumidityScreen(onBackClick = navController::popBackStack)
|
|
||||||
}
|
|
||||||
composable(INFRARED_ROUTE) {
|
|
||||||
InfraredControlScreen(onBackClick = navController::popBackStack)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
package com.flagship.abox.manager.ui.devicecontrol
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
|
||||||
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.Modifier
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun InfraredControlScreen(
|
|
||||||
onBackClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
var deviceName by remember { mutableStateOf("红外遥控器") }
|
|
||||||
var key by remember { mutableStateOf("") }
|
|
||||||
var statusText by remember { mutableStateOf("输入设备名称和按键 KEY 后执行红外操作") }
|
|
||||||
|
|
||||||
DevicePageScaffold(
|
|
||||||
title = "红外遥控器",
|
|
||||||
description = "发送红外按键或学习新按键。后续可接入 InfraredGateway。",
|
|
||||||
onBackClick = onBackClick,
|
|
||||||
modifier = modifier.fillMaxSize(),
|
|
||||||
) {
|
|
||||||
OutlinedTextField(
|
|
||||||
value = deviceName,
|
|
||||||
onValueChange = { deviceName = it },
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
label = { Text("红外设备名称") },
|
|
||||||
singleLine = true,
|
|
||||||
)
|
|
||||||
OutlinedTextField(
|
|
||||||
value = key,
|
|
||||||
onValueChange = { key = it },
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 16.dp),
|
|
||||||
label = { Text("按键 KEY,例如 POWER") },
|
|
||||||
singleLine = true,
|
|
||||||
)
|
|
||||||
TwoColumnActions(
|
|
||||||
leftText = "发送",
|
|
||||||
rightText = "学习",
|
|
||||||
onLeftClick = {
|
|
||||||
statusText = if (key.isBlank()) {
|
|
||||||
"请先输入按键 KEY。"
|
|
||||||
} else {
|
|
||||||
"已请求发送 $key(待接入真实红外发送)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onRightClick = {
|
|
||||||
statusText = if (key.isBlank()) {
|
|
||||||
"请先输入按键 KEY。"
|
|
||||||
} else {
|
|
||||||
"已请求学习 $key(待接入真实红外学习)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modifier = Modifier.padding(top = 24.dp),
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = statusText,
|
|
||||||
modifier = Modifier.padding(top = 20.dp),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
package com.flagship.abox.manager.ui.devicecontrol
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
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.Modifier
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SocketControlScreen(
|
|
||||||
onBackClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
var statusText by remember { mutableStateOf("当前状态:未知") }
|
|
||||||
|
|
||||||
DevicePageScaffold(
|
|
||||||
title = "智能插座",
|
|
||||||
description = "Kotlin Compose 版插座控制页面。后续可接入 SocketGateway。",
|
|
||||||
onBackClick = onBackClick,
|
|
||||||
modifier = modifier.fillMaxSize(),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = statusText,
|
|
||||||
modifier = Modifier.padding(bottom = 24.dp),
|
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
PrimaryActionButton(
|
|
||||||
text = "刷新状态",
|
|
||||||
onClick = {
|
|
||||||
statusText = "当前状态:等待接入真实状态查询"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
TwoColumnActions(
|
|
||||||
leftText = "打开",
|
|
||||||
rightText = "关闭",
|
|
||||||
onLeftClick = {
|
|
||||||
statusText = "当前状态:已请求打开(待接入真实控制)"
|
|
||||||
},
|
|
||||||
onRightClick = {
|
|
||||||
statusText = "当前状态:已请求关闭(待接入真实控制)"
|
|
||||||
},
|
|
||||||
modifier = Modifier.padding(top = 16.dp),
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = "建议后续调用 SocketGateway.getStatus / setPower,而不是直接调用 ABSDK。",
|
|
||||||
modifier = Modifier.padding(top = 20.dp),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
package com.flagship.abox.manager.ui.devicecontrol
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
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.Modifier
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun TemperatureHumidityScreen(
|
|
||||||
onBackClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
var temperature by remember { mutableStateOf("-- ℃") }
|
|
||||||
var humidity by remember { mutableStateOf("-- %") }
|
|
||||||
var statusText by remember { mutableStateOf("点击按钮查询当前温湿度") }
|
|
||||||
|
|
||||||
DevicePageScaffold(
|
|
||||||
title = "温湿度状态",
|
|
||||||
description = "显示温度与湿度读数。后续可接入 TemperatureHumidityGateway。",
|
|
||||||
onBackClick = onBackClick,
|
|
||||||
modifier = modifier.fillMaxSize(),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "温度:$temperature",
|
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = "湿度:$humidity",
|
|
||||||
modifier = Modifier.padding(top = 12.dp, bottom = 24.dp),
|
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
PrimaryActionButton(
|
|
||||||
text = "刷新温湿度",
|
|
||||||
onClick = {
|
|
||||||
temperature = "待接入"
|
|
||||||
humidity = "待接入"
|
|
||||||
statusText = "已触发刷新动作,等待接入真实 ABSDK bridge。"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = statusText,
|
|
||||||
modifier = Modifier.padding(top = 20.dp),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-5
@@ -1,4 +1,4 @@
|
|||||||
package com.flagship.abox.manager.ui.devicecontrol
|
package com.flagship.abox.manager.ui.devicecontrollist
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -41,17 +41,17 @@ fun DeviceListScreen(
|
|||||||
)
|
)
|
||||||
DeviceEntryButton(
|
DeviceEntryButton(
|
||||||
text = "智能插座",
|
text = "智能插座",
|
||||||
description = "查看插座状态,执行打开或关闭操作。",
|
description = "进入智能插座相关功能。",
|
||||||
onClick = onSocketClick,
|
onClick = onSocketClick,
|
||||||
)
|
)
|
||||||
DeviceEntryButton(
|
DeviceEntryButton(
|
||||||
text = "温湿度传感器",
|
text = "温湿度传感器",
|
||||||
description = "查询当前温度与湿度读数。",
|
description = "进入温湿度状态相关功能。",
|
||||||
onClick = onTemperatureHumidityClick,
|
onClick = onTemperatureHumidityClick,
|
||||||
)
|
)
|
||||||
DeviceEntryButton(
|
DeviceEntryButton(
|
||||||
text = "红外遥控器",
|
text = "红外控制器",
|
||||||
description = "发送红外按键,或进入红外学习流程。",
|
description = "进入红外控制器相关功能。",
|
||||||
onClick = onInfraredClick,
|
onClick = onInfraredClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,114 +1,51 @@
|
|||||||
# Device Control Compose UI Change Log
|
# Device List Compose UI Change Log
|
||||||
|
|
||||||
Branch: `feature/device-control-compose-ui`
|
Branch: `feature/device-control-compose-ui`
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
This branch adds a Kotlin Jetpack Compose implementation for the device-control UI owned by this feature area.
|
This branch adds only the Kotlin Jetpack Compose device list page owned by this feature area.
|
||||||
|
|
||||||
The implementation introduces a new device-control entry point and a group of Compose screens for the three device types required by the current project scope:
|
The implementation provides a reusable Compose screen that displays the ABox terminal device categories:
|
||||||
|
|
||||||
- Socket device control
|
|
||||||
- Temperature/humidity status display
|
|
||||||
- Infrared remote control actions
|
|
||||||
|
|
||||||
The existing placeholder/foundation app flow is preserved. The new device-control flow is added as an additional navigation path instead of replacing the existing screens.
|
|
||||||
|
|
||||||
## Modified Files
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/ABoxManagerApp.kt`
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
|
|
||||||
- Added an entry button on the foundation screen for the Kotlin device-control UI.
|
|
||||||
- Registered the new device-control navigation graph in the existing `NavHost`.
|
|
||||||
- Preserved the existing foundation and placeholder routes.
|
|
||||||
|
|
||||||
Purpose:
|
|
||||||
|
|
||||||
- Allows teammates to open the newly added device-control screens from the current Compose app shell.
|
|
||||||
|
|
||||||
## Added Files
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/DeviceControlRoutes.kt`
|
|
||||||
|
|
||||||
Adds navigation routes and a small navigation graph for the device-control feature.
|
|
||||||
|
|
||||||
Routes included:
|
|
||||||
|
|
||||||
- Device list
|
|
||||||
- Socket control
|
|
||||||
- Temperature/humidity status
|
|
||||||
- Infrared control
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/DeviceListScreen.kt`
|
|
||||||
|
|
||||||
Adds the top-level device list screen.
|
|
||||||
|
|
||||||
The screen contains entries for:
|
|
||||||
|
|
||||||
- Smart socket
|
- Smart socket
|
||||||
- Temperature/humidity sensor
|
- Temperature/humidity sensor
|
||||||
- Infrared remote controller
|
- Infrared controller
|
||||||
|
|
||||||
Each entry navigates to its corresponding Compose screen.
|
This branch intentionally does not modify the app entry point or app shell routing. The app shell, login flow, and detail-feature routing are owned by other feature branches.
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/DeviceControlComponents.kt`
|
## Added Files
|
||||||
|
|
||||||
Adds shared UI components used by the device-control screens.
|
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt`
|
||||||
|
|
||||||
Included components:
|
Adds the device list page.
|
||||||
|
|
||||||
- Shared device page scaffold
|
The page displays entries for:
|
||||||
- Primary action button wrapper
|
|
||||||
- Two-column action button row
|
|
||||||
|
|
||||||
Purpose:
|
- Smart socket
|
||||||
|
- Temperature/humidity sensor
|
||||||
- Keeps repeated screen layout and action button patterns consistent across device screens.
|
- Infrared controller
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/SocketControlScreen.kt`
|
|
||||||
|
|
||||||
Adds a Compose screen for socket control.
|
|
||||||
|
|
||||||
Current scope:
|
Current scope:
|
||||||
|
|
||||||
- Displays socket status text.
|
- Display the device categories as list entry UI.
|
||||||
- Provides actions for refreshing status, turning on, and turning off.
|
- Keep the UI in Kotlin Compose.
|
||||||
- Uses local Compose state as a placeholder.
|
- Expose click callbacks for each device category.
|
||||||
|
- Avoid adding app-shell routing, detail routes, or detail control pages in this branch.
|
||||||
|
|
||||||
|
Integration API:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
DeviceListScreen(
|
||||||
|
onSocketClick = { /* route to socket module later */ },
|
||||||
|
onTemperatureHumidityClick = { /* route to temperature/humidity module later */ },
|
||||||
|
onInfraredClick = { /* route to infrared controller module later */ },
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
Future integration point:
|
Future integration point:
|
||||||
|
|
||||||
- Replace placeholder state handling with `SocketGateway.getStatus(...)` and `SocketGateway.setPower(...)` through a ViewModel.
|
- The app shell or feature owner responsible for routing can host this screen and connect these callbacks to their own routes/modules later.
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/TemperatureHumidityScreen.kt`
|
|
||||||
|
|
||||||
Adds a Compose screen for temperature/humidity display.
|
|
||||||
|
|
||||||
Current scope:
|
|
||||||
|
|
||||||
- Displays temperature and humidity values.
|
|
||||||
- Provides a refresh action.
|
|
||||||
- Uses local Compose state as a placeholder.
|
|
||||||
|
|
||||||
Future integration point:
|
|
||||||
|
|
||||||
- Replace placeholder state handling with `TemperatureHumidityGateway.getReading(...)` through a ViewModel.
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/InfraredControlScreen.kt`
|
|
||||||
|
|
||||||
Adds a Compose screen for infrared remote operations.
|
|
||||||
|
|
||||||
Current scope:
|
|
||||||
|
|
||||||
- Allows entering an infrared device name.
|
|
||||||
- Allows entering an infrared key name.
|
|
||||||
- Provides send and learn actions.
|
|
||||||
- Uses local Compose state as a placeholder.
|
|
||||||
|
|
||||||
Future integration point:
|
|
||||||
|
|
||||||
- Replace placeholder state handling with `InfraredGateway.sendKey(...)` and `InfraredGateway.learnKey(...)` through a ViewModel.
|
|
||||||
|
|
||||||
## Architecture Notes
|
## Architecture Notes
|
||||||
|
|
||||||
@@ -117,33 +54,22 @@ This branch follows the current repository direction:
|
|||||||
- Kotlin instead of Java
|
- Kotlin instead of Java
|
||||||
- Jetpack Compose instead of XML layouts
|
- Jetpack Compose instead of XML layouts
|
||||||
- Single-Activity UI instead of multiple Activities
|
- Single-Activity UI instead of multiple Activities
|
||||||
- Navigation Compose instead of `Intent`-based Activity navigation
|
- Navigation Compose compatibility through external callbacks
|
||||||
- Existing design-system wrappers where practical
|
- Existing design-system wrappers where practical
|
||||||
|
|
||||||
This branch intentionally does not copy the previous Java/XML experiment module into the team repository.
|
This branch intentionally does not copy the previous Java/XML experiment module into the team repository.
|
||||||
|
|
||||||
## ABSDK Integration Notes
|
|
||||||
|
|
||||||
The UI screens added in this branch do not call ABSDK directly.
|
|
||||||
|
|
||||||
The repository already contains domain abstractions and an ABSDK bridge:
|
|
||||||
|
|
||||||
- `SocketGateway`
|
|
||||||
- `TemperatureHumidityGateway`
|
|
||||||
- `InfraredGateway`
|
|
||||||
- `AbsdkBridge`
|
|
||||||
- `VendorAbsdkClient`
|
|
||||||
|
|
||||||
Recommended next step:
|
|
||||||
|
|
||||||
- Add ViewModels for the device-control screens.
|
|
||||||
- Inject/use the gateway interfaces from the domain layer.
|
|
||||||
- Expose screen UI state from ViewModels to the Compose screens.
|
|
||||||
|
|
||||||
## Scope Intentionally Not Included
|
## Scope Intentionally Not Included
|
||||||
|
|
||||||
This branch does not include:
|
This branch does not include:
|
||||||
|
|
||||||
|
- App entry point changes
|
||||||
|
- App shell or login routing changes
|
||||||
|
- A device-control navigation graph file
|
||||||
|
- Socket control screen implementation
|
||||||
|
- Temperature/humidity status screen implementation
|
||||||
|
- Infrared controller screen implementation
|
||||||
|
- Shared detail-control component scaffolding
|
||||||
- Direct ABSDK calls from Compose UI
|
- Direct ABSDK calls from Compose UI
|
||||||
- New Java Activity classes
|
- New Java Activity classes
|
||||||
- XML layout files
|
- XML layout files
|
||||||
@@ -151,138 +77,74 @@ This branch does not include:
|
|||||||
- Full session/login integration for device gateway calls
|
- Full session/login integration for device gateway calls
|
||||||
- Persistent infrared key storage
|
- Persistent infrared key storage
|
||||||
|
|
||||||
These should be added in later branches or follow-up commits after team architecture review.
|
These should be added by the corresponding feature owners in later branches or follow-up commits after team architecture review.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- Built and ran `android.app` from Android Studio successfully during local validation.
|
||||||
|
- `:android:app:assembleDebug` completed successfully after trimming the feature scope.
|
||||||
|
|
||||||
## Files Intended for Commit
|
## Files Intended for Commit
|
||||||
|
|
||||||
The intended commit scope is limited to:
|
The intended commit scope is limited to:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
android/app/src/main/kotlin/com/flagship/abox/manager/ui/ABoxManagerApp.kt
|
android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt
|
||||||
android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/
|
|
||||||
docs/device-control-compose-ui-change-log.md
|
docs/device-control-compose-ui-change-log.md
|
||||||
```
|
```
|
||||||
|
|
||||||
`settings.gradle.kts` is intentionally not part of this feature commit unless the team decides the local toolchain resolver change is required.
|
`settings.gradle.kts` is intentionally excluded from this feature commit. Local Gradle/JDK/toolchain setup should be handled on the developer machine and should not modify the team-provided project configuration in this branch.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 设备控制 Compose UI 修改说明(中文)
|
# 设备列表 Compose UI 修改说明(中文)
|
||||||
|
|
||||||
分支:`feature/device-control-compose-ui`
|
分支:`feature/device-control-compose-ui`
|
||||||
|
|
||||||
## 概要
|
## 概要
|
||||||
|
|
||||||
本分支新增了一套 Kotlin Jetpack Compose 版本的设备控制 UI,用于承载当前负责的设备列表与三类终端设备页面。
|
本分支只新增当前分工负责的 Kotlin Jetpack Compose 设备列表页面。
|
||||||
|
|
||||||
本次新增的设备范围包括:
|
设备列表展示的设备类别包括:
|
||||||
|
|
||||||
- 智能插座控制
|
|
||||||
- 温湿度状态显示
|
|
||||||
- 红外遥控器操作
|
|
||||||
|
|
||||||
本分支没有替换原有的 foundation / placeholder 页面,而是在现有 Compose 应用壳中新增了一个设备控制入口。因此,原有占位流程仍然保留,设备控制流程是额外新增的导航路径。
|
|
||||||
|
|
||||||
## 修改文件
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/ABoxManagerApp.kt`
|
|
||||||
|
|
||||||
修改内容:
|
|
||||||
|
|
||||||
- 在 foundation 页面增加了一个进入 Kotlin 版设备控制 UI 的按钮。
|
|
||||||
- 在现有 `NavHost` 中注册了设备控制导航图。
|
|
||||||
- 保留了原有 foundation route 和 placeholder route。
|
|
||||||
|
|
||||||
作用:
|
|
||||||
|
|
||||||
- 方便团队成员从当前 Compose 应用入口进入新增加的设备控制页面。
|
|
||||||
|
|
||||||
## 新增文件
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/DeviceControlRoutes.kt`
|
|
||||||
|
|
||||||
新增设备控制相关的 Compose Navigation 路由与导航图。
|
|
||||||
|
|
||||||
包含的页面路由:
|
|
||||||
|
|
||||||
- 设备列表
|
|
||||||
- 智能插座控制
|
|
||||||
- 温湿度状态
|
|
||||||
- 红外遥控器控制
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/DeviceListScreen.kt`
|
|
||||||
|
|
||||||
新增设备列表页面。
|
|
||||||
|
|
||||||
页面包含三个设备入口:
|
|
||||||
|
|
||||||
- 智能插座
|
- 智能插座
|
||||||
- 温湿度传感器
|
- 温湿度传感器
|
||||||
- 红外遥控器
|
- 红外控制器
|
||||||
|
|
||||||
每个入口会跳转到对应的 Compose 设备页面。
|
本分支故意不修改 App 入口或应用壳路由。程序入口、登录流程和各设备详情模块路由由其他功能分支负责。
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/DeviceControlComponents.kt`
|
## 新增文件
|
||||||
|
|
||||||
新增设备控制页面共用 UI 组件。
|
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt`
|
||||||
|
|
||||||
包含:
|
新增设备列表页面。
|
||||||
|
|
||||||
- 通用设备页面脚手架
|
页面展示三个设备入口:
|
||||||
- 主要操作按钮封装
|
|
||||||
- 双按钮横向操作区
|
|
||||||
|
|
||||||
作用:
|
- 智能插座
|
||||||
|
- 温湿度传感器
|
||||||
- 减少各设备页面中的重复布局代码。
|
- 红外控制器
|
||||||
- 让插座、温湿度、红外页面保持相似的视觉结构。
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/SocketControlScreen.kt`
|
|
||||||
|
|
||||||
新增智能插座控制页面。
|
|
||||||
|
|
||||||
当前实现范围:
|
当前实现范围:
|
||||||
|
|
||||||
- 显示插座状态文本。
|
- 展示设备类别入口 UI。
|
||||||
- 提供刷新状态、打开、关闭三个操作入口。
|
- 保持 Kotlin Compose 实现。
|
||||||
- 当前使用本地 Compose state 作为占位状态。
|
- 为每个设备类别暴露点击回调。
|
||||||
|
- 不在本分支实现 App 入口接入、设备详情 route 或设备控制页面。
|
||||||
|
|
||||||
|
对接 API:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
DeviceListScreen(
|
||||||
|
onSocketClick = { /* 后续跳转到智能插座模块 */ },
|
||||||
|
onTemperatureHumidityClick = { /* 后续跳转到温湿度模块 */ },
|
||||||
|
onInfraredClick = { /* 后续跳转到红外控制器模块 */ },
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
后续接入点:
|
后续接入点:
|
||||||
|
|
||||||
- 通过 ViewModel 接入 `SocketGateway.getStatus(...)`。
|
- 由负责 App shell 或对应设备模块的同学,在各自分支中挂载这个页面,并把这些回调连接到他们自己的详情路由或功能模块。
|
||||||
- 通过 ViewModel 接入 `SocketGateway.setPower(...)`。
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/TemperatureHumidityScreen.kt`
|
|
||||||
|
|
||||||
新增温湿度状态页面。
|
|
||||||
|
|
||||||
当前实现范围:
|
|
||||||
|
|
||||||
- 显示温度值。
|
|
||||||
- 显示湿度值。
|
|
||||||
- 提供刷新温湿度按钮。
|
|
||||||
- 当前使用本地 Compose state 作为占位状态。
|
|
||||||
|
|
||||||
后续接入点:
|
|
||||||
|
|
||||||
- 通过 ViewModel 接入 `TemperatureHumidityGateway.getReading(...)`。
|
|
||||||
|
|
||||||
### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/InfraredControlScreen.kt`
|
|
||||||
|
|
||||||
新增红外遥控器页面。
|
|
||||||
|
|
||||||
当前实现范围:
|
|
||||||
|
|
||||||
- 输入红外设备名称。
|
|
||||||
- 输入红外按键 KEY。
|
|
||||||
- 提供发送红外按键操作。
|
|
||||||
- 提供学习红外按键操作。
|
|
||||||
- 当前使用本地 Compose state 作为占位状态。
|
|
||||||
|
|
||||||
后续接入点:
|
|
||||||
|
|
||||||
- 通过 ViewModel 接入 `InfraredGateway.sendKey(...)`。
|
|
||||||
- 通过 ViewModel 接入 `InfraredGateway.learnKey(...)`。
|
|
||||||
|
|
||||||
## 架构说明
|
## 架构说明
|
||||||
|
|
||||||
@@ -291,37 +153,22 @@ docs/device-control-compose-ui-change-log.md
|
|||||||
- 使用 Kotlin,而不是 Java。
|
- 使用 Kotlin,而不是 Java。
|
||||||
- 使用 Jetpack Compose,而不是 XML layout。
|
- 使用 Jetpack Compose,而不是 XML layout。
|
||||||
- 使用单 Activity 架构,而不是多个 Activity 跳转。
|
- 使用单 Activity 架构,而不是多个 Activity 跳转。
|
||||||
- 使用 Navigation Compose,而不是 `Intent` 页面跳转。
|
- 通过外部回调保持与 Navigation Compose 的兼容性。
|
||||||
- 尽量复用已有 design system 中的组件封装。
|
- 尽量复用已有 design system 中的组件封装。
|
||||||
|
|
||||||
本分支没有把之前个人实验项目中的 Java/XML 模块直接复制进团队仓库。
|
本分支没有把之前个人实验项目中的 Java/XML 模块直接复制进团队仓库。
|
||||||
|
|
||||||
## ABSDK 接入说明
|
|
||||||
|
|
||||||
本次新增的 Compose UI 页面没有直接调用 ABSDK。
|
|
||||||
|
|
||||||
当前仓库中已经存在较正式的 domain 抽象和 ABSDK bridge:
|
|
||||||
|
|
||||||
- `SocketGateway`
|
|
||||||
- `TemperatureHumidityGateway`
|
|
||||||
- `InfraredGateway`
|
|
||||||
- `AbsdkBridge`
|
|
||||||
- `VendorAbsdkClient`
|
|
||||||
|
|
||||||
因此后续真实设备控制逻辑建议通过 ViewModel 调用 domain gateway,而不是在 Compose UI 中直接调用 ABSDK。
|
|
||||||
|
|
||||||
推荐后续工作:
|
|
||||||
|
|
||||||
- 为插座页面新增 ViewModel。
|
|
||||||
- 为温湿度页面新增 ViewModel。
|
|
||||||
- 为红外页面新增 ViewModel。
|
|
||||||
- 在 ViewModel 中调用对应 gateway。
|
|
||||||
- 将调用结果转换为 Compose UI state。
|
|
||||||
|
|
||||||
## 本分支未包含的内容
|
## 本分支未包含的内容
|
||||||
|
|
||||||
本分支暂不包含:
|
本分支暂不包含:
|
||||||
|
|
||||||
|
- App 入口修改。
|
||||||
|
- App shell 或登录路由修改。
|
||||||
|
- 设备控制 navigation graph 文件。
|
||||||
|
- 智能插座控制页面。
|
||||||
|
- 温湿度状态页面。
|
||||||
|
- 红外控制器操作页面。
|
||||||
|
- 设备详情控制页面共用组件。
|
||||||
- Compose UI 中直接调用 ABSDK。
|
- Compose UI 中直接调用 ABSDK。
|
||||||
- 新增 Java Activity。
|
- 新增 Java Activity。
|
||||||
- 新增 XML layout。
|
- 新增 XML layout。
|
||||||
@@ -329,16 +176,20 @@ docs/device-control-compose-ui-change-log.md
|
|||||||
- 完整登录/session 与设备 gateway 的联动。
|
- 完整登录/session 与设备 gateway 的联动。
|
||||||
- 红外学习按键的持久化存储。
|
- 红外学习按键的持久化存储。
|
||||||
|
|
||||||
这些内容建议在团队确认架构之后,作为后续 branch 或后续 commit 继续实现。
|
这些内容建议由对应模块负责人在后续 branch 或后续 commit 中继续实现。
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
- 本地验证过程中已从 Android Studio 成功 build/run `android.app`。
|
||||||
|
- 修剪职责范围后,`:android:app:assembleDebug` 构建成功。
|
||||||
|
|
||||||
## 预期提交范围
|
## 预期提交范围
|
||||||
|
|
||||||
本次提交范围应限制在:
|
本次提交范围应限制在:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
android/app/src/main/kotlin/com/flagship/abox/manager/ui/ABoxManagerApp.kt
|
android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt
|
||||||
android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrol/
|
|
||||||
docs/device-control-compose-ui-change-log.md
|
docs/device-control-compose-ui-change-log.md
|
||||||
```
|
```
|
||||||
|
|
||||||
`settings.gradle.kts` 当前不属于本次设备控制 UI 功能提交范围,除非团队明确认为本地 toolchain resolver 配置也需要进入 PR。
|
`settings.gradle.kts` 当前不属于本次设备列表 UI 功能提交范围。本地 Gradle/JDK/toolchain 配置应在开发者本机处理,不应修改团队提供的项目配置文件。
|
||||||
|
|||||||
Reference in New Issue
Block a user