Feat/moler infrared control (#9)

Co-authored-by: KremeCN <3265494849@qq.com>
Reviewed-on: #9
Co-authored-by: mxhsnd <2049295946@qq.com>
This commit was merged in pull request #9.
This commit is contained in:
2026-08-25 14:51:34 +08:00
committed by KremeCN
co-authored by KremeCN
parent 249721be33
commit 09c352457d
78 changed files with 12785 additions and 15 deletions
+1
View File
@@ -64,6 +64,7 @@ dependencies {
implementation(project(":domain"))
implementation(project(":android:core:designsystem"))
implementation(project(":android:core:session"))
implementation(project(":android:feature:infrared"))
implementation(project(":absdk-bridge"))
implementation(project(":runtime:simulation"))
debugImplementation(project(":testing:fakes"))
@@ -11,9 +11,20 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.designsystem.ABoxLoadingIndicator
import com.flagship.abox.manager.designsystem.ABoxSurface
import com.flagship.abox.manager.designsystem.ABoxTheme
import com.flagship.abox.manager.domain.ProviderProfile
import com.flagship.abox.manager.domain.Username
import com.flagship.abox.manager.infrared.hub.InfraredHubRoute
import com.flagship.abox.manager.infrared.panel.RemotePanelRoute
import com.flagship.abox.manager.infrared.ui.InfraredControlRoute
import com.flagship.abox.manager.ui.devicecontrollist.DeviceListScreen
import com.flagship.abox.manager.ui.login.LoginRoute
import com.flagship.abox.manager.ui.login.LoginViewModel
import com.flagship.abox.manager.ui.provider.ProviderSelectionRoute
@@ -57,18 +68,93 @@ fun ABoxManagerApp(
onSwitchProvider = sessionActionsViewModel::switchProvider,
viewModel = loginViewModel,
)
is AppSessionUiState.Authenticated -> MainAppShell(
userName = state.username.value,
providerName = state.profile.displayName,
onLogout = sessionActionsViewModel::logout,
is AppSessionUiState.Authenticated -> AuthenticatedNavHost(
username = state.username,
profile = state.profile,
actionInProgress = actionState.inProgress,
errorMessage = actionState.errorMessage,
onLogout = sessionActionsViewModel::logout,
)
}
}
}
}
@Composable
private fun AuthenticatedNavHost(
username: Username,
profile: ProviderProfile,
actionInProgress: Boolean,
errorMessage: String?,
onLogout: () -> Unit,
) {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "home",
) {
composable("home") {
MainAppShell(
userName = username.value,
providerName = profile.displayName,
onLogout = onLogout,
actionInProgress = actionInProgress,
errorMessage = errorMessage,
devicesSlot = {
val encodedProfileId = android.net.Uri.encode(profile.id.value)
DeviceListScreen(
onInfraredClick = {
navController.navigate("infrared_hub/$encodedProfileId")
},
)
},
)
}
composable(
route = "infrared_hub/{profileId}",
arguments = listOf(
navArgument("profileId") { type = NavType.StringType },
),
) {
val encodedProfileId = android.net.Uri.encode(profile.id.value)
InfraredHubRoute(
onBack = { navController.popBackStack() },
onOpenRemote = { remoteId ->
val encodedRemoteId = android.net.Uri.encode(remoteId)
navController.navigate("infrared_panel/$encodedProfileId/$encodedRemoteId")
},
onOpenSettings = {
navController.navigate("infrared_settings/$encodedProfileId")
},
onSessionInvalid = onLogout,
)
}
composable(
route = "infrared_panel/{profileId}/{remoteId}",
arguments = listOf(
navArgument("profileId") { type = NavType.StringType },
navArgument("remoteId") { type = NavType.StringType },
),
) {
RemotePanelRoute(
onBack = { navController.popBackStack() },
onSessionInvalid = onLogout,
)
}
composable(
route = "infrared_settings/{profileId}",
arguments = listOf(
navArgument("profileId") { type = NavType.StringType },
),
) {
InfraredControlRoute(
onBack = { navController.popBackStack() },
onSessionInvalid = onLogout,
)
}
}
}
private fun AppSessionUiState.screenKey(): String = when (this) {
AppSessionUiState.Loading -> "loading"
AppSessionUiState.ProviderSelection -> "providers"
@@ -23,7 +23,6 @@
<string name="action_switch_provider">切换提供方</string>
<string name="authenticated_title">已连接到 %1$s</string>
<string name="authenticated_description">登录后入口已经就绪,设备导航将由对应模块负责人接入。</string>
<!-- 认证后壳层 -->
<string name="tab_devices">设备</string>
<string name="tab_scenes">情景</string>
@@ -52,4 +51,6 @@
<string name="device_temperature_humidity_description">进入温湿度状态相关功能。</string>
<string name="device_infrared_title">红外控制器</string>
<string name="device_infrared_description">进入红外控制器相关功能。</string>
<string name="infrared_control_action">红外控制</string>
<string name="infrared_session_invalid_message">ABox 会话未认证,请先登录。</string>
</resources>
+2 -1
View File
@@ -23,7 +23,6 @@
<string name="action_switch_provider">Switch provider</string>
<string name="authenticated_title">Connected to %1$s</string>
<string name="authenticated_description">The authenticated route is ready. Device navigation will be added by its module owner.</string>
<!-- Authenticated shell -->
<string name="tab_devices">Devices</string>
<string name="tab_scenes">Scenes</string>
@@ -52,4 +51,6 @@
<string name="device_temperature_humidity_description">View temperature and humidity status.</string>
<string name="device_infrared_title">Infrared Controller</string>
<string name="device_infrared_description">Access infrared controller features.</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>