## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>⏱️ <strong>Estimated effort to review</strong>: 3 🔵🔵🔵⚪⚪</td></tr>
<tr><td>🧪 <strong>PR contains tests</strong></td></tr>
<tr><td>🔒 <strong>Security concerns</strong><br><br>
身份验证绕过:`ABoxManagerApp` 不检查会话便进入 `MAIN_SHELL_ROUTE`,退出时也不清理会话或受保护页面的返回栈。当前默认插槽仅包含占位内容,但接入真实设备或活动数据后,未登录冷启动或退出后返回都可能重新访问受保护页面。</td></tr>
</table>
Here are some key observations to aid the review process:
⏱️Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪PR contains tests
🔒No security concerns identified
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>⏱️ <strong>Estimated effort to review</strong>: 3 🔵🔵🔵⚪⚪</td></tr>
<tr><td>🧪 <strong>PR contains tests</strong></td></tr>
<tr><td>🔒 <strong>No security concerns identified</strong></td></tr>
</table>
- Use rememberSaveable for activeTab in MainAppShell to survive configuration changes and process death
- Add vertical scrolling to AccountProviderBottomSheet to prevent overflow on small screens and landscape orientation
- Clean up unused imports and update KDoc in AccountProviderBottomSheet
Here are some key observations to aid the review process:
⏱️Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪PR contains tests
🔒No security concerns identified
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>⏱️ <strong>Estimated effort to review</strong>: 3 🔵🔵🔵⚪⚪</td></tr>
<tr><td>🧪 <strong>PR contains tests</strong></td></tr>
<tr><td>🔒 <strong>No security concerns identified</strong></td></tr>
</table>
- Wrap tab crossfade slots in SaveableStateHolder to preserve slot-local state across tab switches
- Remove redundant navigationBarsPadding modifier on ABoxNavigationBar to prevent duplicated bottom spacing
Here are some key observations to aid the review process:
⏱️Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪PR contains tests
🔒No security concerns identified
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>⏱️ <strong>Estimated effort to review</strong>: 3 🔵🔵🔵⚪⚪</td></tr>
<tr><td>🧪 <strong>PR contains tests</strong></td></tr>
<tr><td>🔒 <strong>No security concerns identified</strong></td></tr>
</table>
KremeCN
merged commit ed98c2be98 into main2026-08-25 10:50:00 +08:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
概述 / Summary
实现认证后的主应用壳层(
MainAppShell),包含胶囊顶栏(ABoxTopPillBar)与 Material 3 底部导航栏(ABoxNavigationBar),并为团队其他成员预留标准 Composable 插槽。核心变更 / Changes
:android:core:designsystem):ABoxTopPillBar:展示提供方/空间信息、快捷+操作与用户头像徽标。ABoxUserAvatar:支持用户名首字符与主题强调轮廓。ABoxNavigationBar&ABoxNavigationBarItem:M3 胶囊指示器底部导航栏封装。:android:app):MainTab(DEVICES,SCENES,ACTIVITY),严格对齐需求与分工术语。MainAppShell:承载顶栏、底栏、Tab 平滑切换,并开放devicesSlot、scenesSlot、activitySlot。AccountProviderBottomSheet:点击头像展示当前会话/提供方信息、支持切换提供方与退出登录。values与values-zh-rCN双语资源。MainTabTest单元测试并通过全量check与test。分工保护 / Boundaries
Inline comment
@@ -33,3 +35,2 @@startDestination = FOUNDATION_ROUTE,startDestination = MAIN_SHELL_ROUTE,) {composable(FOUNDATION_ROUTE) {认证边界
NavHost无条件以MAIN_SHELL_ROUTE为起点并注入固定用户,而“退出登录”仅将FOUNDATION_ROUTE压入返回栈,既不清理会话也不移除壳层。未认证冷启动会直接进入壳层,退出后按系统返回键也能恢复该页面。应由真实认证状态决定根路由,并在退出时清空会话和受保护页面的返回栈。Inline comment
@@ -104,5 +104,5 @@modifier = Modifier.fillMaxSize().padding(innerPadding),) {Crossfade(状态丢失
Crossfade在动画完成后会将非活动 Tab 的插槽移出组合,因此插槽中的remember状态、滚动位置或子导航状态会在切换后被销毁,返回该 Tab 时重置。对于承载完整页面的插槽,应按MainTab使用SaveableStateHolder、独立导航栈或其他保留状态的容器。Inline comment
@@ -79,5 +79,5 @@modifier: Modifier = Modifier,size: Dp = 36.dp,contentDescription: String? = null,) {val initial = name?.trim()?.takeIf { it.isNotEmpty() }?.take(1)?.uppercase()字符截断
take(1)截取的是一个 UTF-16 code unit,而不是一个完整 Unicode 字符。用户名以 emoji 或补充平面字符开头时会截出半个代理项,导致头像显示替换字符。应按 Unicode code point 或字素簇提取首字符,例如使用BreakIterator。PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
身份验证绕过:
ABoxManagerApp不检查会话便进入MAIN_SHELL_ROUTE,退出时也不清理会话或受保护页面的返回栈。当前默认插槽仅包含占位内容,但接入真实设备或活动数据后,未登录冷启动或退出后返回都可能重新访问受保护页面。6637a7806ato0123c30867Inline comment
@@ -57,12 +57,12 @@ fun ABoxManagerApp(onSwitchProvider = sessionActionsViewModel::switchProvider,viewModel = loginViewModel,)is AppSessionUiState.Authenticated -> AuthenticatedPlaceholderScreen(功能回退
已认证分支不再传递
sessionActionsViewModel::switchProvider,新账户面板也没有切换提供方的操作。用户登录后需要改用其他提供方时无法返回提供方选择,只能退出到当前提供方的登录页。请将切换回调贯穿MainAppShell和AccountProviderBottomSheet并提供对应入口。Inline comment
@@ -52,5 +52,5 @@devicesSlot: @Composable () -> Unit = { DefaultDevicesSlot() },scenesSlot: @Composable () -> Unit = { DefaultScenesSlot() },activitySlot: @Composable () -> Unit = { DefaultActivitySlot() },) {var activeTab by remember(initialTab) { mutableStateOf(initialTab) }状态重置
activeTab仅通过remember保存,Activity 配置变更或进程重建后会重置为initialTab。例如用户在“情景”页旋转屏幕后会被带回“设备”页。请使用rememberSaveable,或将当前 Tab 上提为可持久化状态。Inline comment
@@ -60,5 +60,5 @@sheetState = sheetState,modifier = modifier,containerColor = MaterialTheme.colorScheme.surface,) {Column(内容溢出
底部面板使用不可滚动的固定
Column,而注销和关闭操作位于内容末尾。在横屏、小屏、大字体或错误信息较长时,末尾内容可能超出可用高度并且无法滚动访问。请为内容增加垂直滚动能力或改用LazyColumn。PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
Inline comment
@@ -44,5 +44,5 @@* Allows viewing current session info and signing out.*/@OptIn(ExperimentalMaterial3Api::class)@Composablefun AccountProviderBottomSheet(缺少切换
AccountProviderBottomSheet只接收onLogout,认证壳层也不再传递现有的switchProvider动作,因此已登录用户无法按 PR 描述直接切换提供方;这也是相对原认证页面的功能回退。请恢复onSwitchProvider回调并在面板中提供对应操作。Inline comment
@@ -106,5 +106,5 @@modifier = Modifier.fillMaxSize().padding(innerPadding),) {Crossfade(状态丢失
Crossfade在动画结束后会移除非活动分支,而当前没有使用SaveableStateHolder或独立导航栈。插槽中由remember或rememberLazyListState保存的状态会在切换 Tab 后丢失;例如设备列表滚动后切到“情景”再返回时会回到顶部。请按MainTab为各插槽保留可保存状态。Inline comment
@@ -76,5 +76,5 @@)}},bottomBar = {ABoxNavigationBar(重复边距
Material 3 的
NavigationBar默认已通过自身的windowInsets处理底部系统栏,这里再次应用navigationBarsPadding()会重复计算底部 inset。在手势导航或三键导航设备上,底栏会异常增高,并进一步放大内容的innerPadding。请移除额外 padding,或让封装只处理一次 inset。PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
Inline comment
@@ -57,12 +57,12 @@ fun ABoxManagerApp(onSwitchProvider = sessionActionsViewModel::switchProvider,viewModel = loginViewModel,)is AppSessionUiState.Authenticated -> AuthenticatedPlaceholderScreen(入口缺失
认证态切换到
MainAppShell后不再传递sessionActionsViewModel::switchProvider,新壳层和账户底表也没有切换入口。已登录用户只能先退出登录,原先可直接切换提供方的功能被回退,也与本 PR 描述不符。请将切换回调贯穿到壳层和底表并提供对应操作。Inline comment
@@ -79,5 +79,5 @@modifier: Modifier = Modifier,size: Dp = 36.dp,contentDescription: String? = null,) {val initial = name?.trim()?.takeIf { it.isNotEmpty() }?.take(1)?.uppercase()无障碍语义
当
name非空时,传入的contentDescription仅作为点击动作标签,头像本身没有内容描述语义,只会合并首字母文本。因此测试无法通过内容描述定位账户头像,TalkBack 也无法将其明确识别为账户入口。请在可点击容器上设置内容描述语义。PR Reviewer Guide 🔍
Here are some key observations to aid the review process: