diff --git a/app/src/main/java/com/rainy/token/ui/dashboard/DashboardScreen.kt b/app/src/main/java/com/rainy/token/ui/dashboard/DashboardScreen.kt index cbe559e..0cbe42e 100644 --- a/app/src/main/java/com/rainy/token/ui/dashboard/DashboardScreen.kt +++ b/app/src/main/java/com/rainy/token/ui/dashboard/DashboardScreen.kt @@ -783,7 +783,31 @@ private fun DashboardCard( Spacer(modifier = Modifier.height(16.dp)) // ─── 主体:服务特定的主信息 ─── - BalanceMainArea(card) + // Sub2API 把「面板管理」入口传入余额行,使其与余额数字齐平(见 Sub2ApiBalanceWithUsage) + val showPanelEntry = card.service == ServiceType.SUB2API && + card.credentialState != CredentialStatus.State.NOT_CONFIGURED && + onOpenPanelManagement != null + BalanceMainArea( + card = card, + balanceTrailing = if (showPanelEntry) { + { + TextButton(onClick = { onOpenPanelManagement!!.invoke() }) { + Text( + stringResource(R.string.sub2_panel_manage_title), + color = StrawberryPink, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Spacer(modifier = Modifier.width(2.dp)) + Icon( + imageVector = Icons.Filled.KeyboardArrowRight, + contentDescription = null, + tint = StrawberryPink + ) + } + } + } else null + ) // 用量服务卡片底部:用量详情入口 + Token 活动快捷入口(仅当有凭证时显示) if (onOpenUsageDetail != null && card.credentialState != com.rainy.token.domain.model.CredentialStatus.State.NOT_CONFIGURED) { @@ -827,29 +851,6 @@ private fun DashboardCard( } } - // Sub2API 面板管理快捷入口(仅已配置凭据时显示;按钮点击不会触发整卡点击) - if (card.service == ServiceType.SUB2API && - card.credentialState != CredentialStatus.State.NOT_CONFIGURED && - onOpenPanelManagement != null - ) { - Spacer(modifier = Modifier.height(2.dp)) - TextButton(onClick = onOpenPanelManagement) { - Text( - stringResource(R.string.sub2_panel_manage_title), - color = StrawberryPink, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Spacer(modifier = Modifier.width(2.dp)) - Icon( - imageVector = Icons.Filled.KeyboardArrowRight, - contentDescription = null, - tint = StrawberryPink, - modifier = Modifier.padding(top = 1.dp) - ) - } - } - // ─── 底部:更新时间 / 错误信息 ─── Spacer(modifier = Modifier.height(12.dp)) Text( diff --git a/app/src/main/java/com/rainy/token/ui/dashboard/ServiceBalanceCards.kt b/app/src/main/java/com/rainy/token/ui/dashboard/ServiceBalanceCards.kt index 6c2998a..887036c 100644 --- a/app/src/main/java/com/rainy/token/ui/dashboard/ServiceBalanceCards.kt +++ b/app/src/main/java/com/rainy/token/ui/dashboard/ServiceBalanceCards.kt @@ -51,7 +51,7 @@ import java.util.Locale // ── Service-specific balance Composables ── @Composable -internal fun BalanceMainArea(card: DashboardCardUi) { +internal fun BalanceMainArea(card: DashboardCardUi, balanceTrailing: (@Composable () -> Unit)? = null) { val balance = card.displayBalance when { card.credentialState == CredentialStatus.State.NOT_CONFIGURED -> { @@ -99,9 +99,7 @@ internal fun BalanceMainArea(card: DashboardCardUi) { OllamaUsageWindows(balance) } card.service == ServiceType.SUB2API -> { - // 余额与「今日 / 近7天」并排:右侧两列紧凑展示,避免早先竖排时把卡片撑得过高、 - // 也避免在窄屏上把周期行挤到换行。 - Sub2ApiBalanceWithUsage(balance) + Sub2ApiBalanceWithUsage(balance, balanceTrailing = balanceTrailing) } else -> { Row(verticalAlignment = Alignment.Bottom) { @@ -649,9 +647,16 @@ internal fun usageUpdatedAtText(updatedAt: Long): String { * 磁贴等宽 + 两行固定结构,保证 360dp 窄屏不换行、不同周期数值长度不一会错位。 */ @Composable -internal fun Sub2ApiBalanceWithUsage(balance: ServiceBalance) { +internal fun Sub2ApiBalanceWithUsage( + balance: ServiceBalance, + balanceTrailing: (@Composable () -> Unit)? = null +) { Column(modifier = Modifier.fillMaxWidth()) { - Sub2ApiBalanceHero(balance) + // 余额与右侧入口(面板管理)同处一行、垂直居中,使按钮与余额数字高度齐平 + Row(verticalAlignment = Alignment.CenterVertically) { + Sub2ApiBalanceHero(balance, modifier = Modifier.weight(1f)) + balanceTrailing?.invoke() + } Spacer(modifier = Modifier.height(10.dp)) Sub2ApiUsageTiles(balance) } @@ -717,12 +722,23 @@ private fun Sub2ApiUsageTiles(balance: ServiceBalance) { .padding(horizontal = 12.dp, vertical = 10.dp), verticalArrangement = Arrangement.Center ) { - Text( - text = w.label, - style = MaterialTheme.typography.labelSmall, - color = inkMuted(), - maxLines = 1 - ) + // 两行:第一行「周期 · 请求次数」,第二行 Token 数(避免占三行显得松散) + Row(verticalAlignment = Alignment.Bottom) { + Text( + text = w.label, + style = MaterialTheme.typography.labelSmall, + color = inkMuted(), + maxLines = 1 + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = stringResource(R.string.sub2_home_requests, w.requests), + style = MaterialTheme.typography.labelSmall, + color = inkMuted(), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } Spacer(modifier = Modifier.height(3.dp)) Text( text = w.tokens, @@ -732,14 +748,6 @@ private fun Sub2ApiUsageTiles(balance: ServiceBalance) { maxLines = 1, overflow = TextOverflow.Ellipsis ) - Spacer(modifier = Modifier.height(2.dp)) - Text( - text = stringResource(R.string.sub2_home_requests, w.requests), - style = MaterialTheme.typography.labelSmall, - color = inkMuted(), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) } } }