diff --git a/app/src/main/java/com/rainy/token/ui/components/ServiceIcon.kt b/app/src/main/java/com/rainy/token/ui/components/ServiceIcon.kt index 9b6de6f..0675c10 100644 --- a/app/src/main/java/com/rainy/token/ui/components/ServiceIcon.kt +++ b/app/src/main/java/com/rainy/token/ui/components/ServiceIcon.kt @@ -102,18 +102,17 @@ fun ServiceIcon( } } ServiceType.OLLAMA -> { - // Ollama 暂用 emoji 占位 Box( modifier = modifier .size(size.dp) - .clip(RoundedCornerShape(12.dp)) - .background(Color(0xFF000000), - ), + .clip(RoundedCornerShape(8.dp)) + .background(if (isSystemInDarkTheme()) Color(0xFF1A1A1A) else Color.White), contentAlignment = Alignment.Center ) { - androidx.compose.material3.Text( - text = "🦙", - fontSize = (size * 0.5).sp + Image( + painter = painterResource(id = R.drawable.ic_ollama_logo), + contentDescription = "Ollama Pro", + modifier = Modifier.size((size * 0.85).dp) ) } } 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 8265166..02834e8 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 @@ -892,7 +892,7 @@ private fun OllamaMainBalance(balance: com.rainy.token.domain.model.ServiceBalan ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "Session 已用", + text = "5h 已用", style = MaterialTheme.typography.titleMedium, color = inkMuted(), modifier = Modifier.padding(bottom = 6.dp) @@ -918,12 +918,12 @@ private fun OllamaUsageWindows(balance: com.rainy.token.domain.model.ServiceBala Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { if (sessionPct != null) { CompactUsageRow( - label = "Session", + label = "5h", pct = sessionPct.toInt().coerceIn(0, 100), resetInSec = sessionResetAt?.let { (it - System.currentTimeMillis()) / 1000 }?.takeIf { it > 0 } ) } else { - CompactUsageRowEmpty(label = "Session", resetInSec = null) + CompactUsageRowEmpty(label = "5h", resetInSec = null) } if (weeklyPct != null) { CompactUsageRow( diff --git a/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt b/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt index 5916323..1b1b149 100644 --- a/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt +++ b/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt @@ -138,7 +138,7 @@ fun ServiceDetailScreen( // Codex 详情:暂无专用详情卡片,用通用余额展示即可 } ServiceType.OLLAMA -> { - // Ollama 详情:暂无专用详情卡片,用通用余额展示即可 + item { OllamaUsageCard(uiState.state) } } } @@ -400,6 +400,59 @@ private fun formatResetInSec(sec: Long): String { } } +/** + * Ollama Pro 专属:5h + 每周用量窗口卡。 + */ +@Composable +private fun OllamaUsageCard(state: State) { + val balance = when (state) { + is State.Fresh -> state.data + is State.Stale -> state.data + is State.Error -> state.cached + else -> null + } + val extras = balance?.extras ?: return + val plan = extras["plan"] ?: "—" + + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(20.dp), + colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) + ) { + Column(modifier = Modifier.padding(20.dp)) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + text = "用量窗口", + style = MaterialTheme.typography.labelLarge, + color = inkMuted() + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = plan, + style = MaterialTheme.typography.labelLarge, + color = StrawberryPink, + fontWeight = FontWeight.Bold + ) + } + Spacer(modifier = Modifier.height(12.dp)) + UsageWindowRow( + label = "5 小时", + pct = extras["session.pct"]?.toIntOrNull(), + resetInSec = extras["session.resetAt"]?.toLongOrNull()?.let { (it - System.currentTimeMillis()) / 1000 }?.takeIf { it > 0 } + ) + Spacer(modifier = Modifier.height(14.dp)) + HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant) + Spacer(modifier = Modifier.height(14.dp)) + UsageWindowRow( + label = "每周", + pct = extras["weekly.pct"]?.toIntOrNull(), + resetInSec = extras["weekly.resetAt"]?.toLongOrNull()?.let { (it - System.currentTimeMillis()) / 1000 }?.takeIf { it > 0 } + ) + } + } +} + @Composable private fun MainBalanceCard(state: State, service: ServiceType) { Card( diff --git a/app/src/main/java/com/rainy/token/ui/widget/OpenCodeGoWidgetProvider.kt b/app/src/main/java/com/rainy/token/ui/widget/OpenCodeGoWidgetProvider.kt index ccd429c..0e354f9 100644 --- a/app/src/main/java/com/rainy/token/ui/widget/OpenCodeGoWidgetProvider.kt +++ b/app/src/main/java/com/rainy/token/ui/widget/OpenCodeGoWidgetProvider.kt @@ -182,7 +182,7 @@ class OpenCodeGoWidgetProvider : AppWidgetProvider() { } ServiceType.DEEPSEEK -> setEmptyState(views) ServiceType.OLLAMA -> { - setRowLabel(views, "Session", "每周", "Plan") + setRowLabel(views, "5h", "每周", "Plan") populateRow(views, R.id.row1_pct, R.id.row1_bar, R.id.row1_reset, pct = extras["session.pct"]?.toIntOrNull(), resetSec = extras["session.resetAt"]?.toLongOrNull()?.let { (it - System.currentTimeMillis()) / 1000 }?.takeIf { it > 0 }) @@ -303,7 +303,7 @@ class OpenCodeGoWidgetProvider : AppWidgetProvider() { ServiceType.OPENCODE_GO, ServiceType.COMMANDCODE_GO -> R.drawable.ic_opencode_go_logo ServiceType.CODEX -> R.drawable.ic_codex_logo ServiceType.DEEPSEEK -> R.drawable.ic_deepseek_logo - ServiceType.OLLAMA -> R.drawable.ic_opencode_go_logo // 复用,后续可换 Ollama logo + ServiceType.OLLAMA -> R.drawable.ic_ollama_logo } /** diff --git a/app/src/main/res/drawable-nodpi/ic_ollama_logo.png b/app/src/main/res/drawable-nodpi/ic_ollama_logo.png new file mode 100644 index 0000000..e1130b2 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/ic_ollama_logo.png differ