refactor: extract duplicate format functions to FormatUtils
- New: ui/components/FormatUtils.kt — formatAmount/formatResetInSec/formatResetForWidget/normalizeWindowLabel - ServiceBalanceCards.kt: remove internal definitions, import from FormatUtils - ServiceDetailScreen.kt: remove private formatResetInSec/formatAmount, import from FormatUtils - OpenCodeGoWidgetProvider.kt: remove private normalizeWindowLabel, import from FormatUtils (formatReset kept — widget uses short d/h/m format, not Chinese)
This commit is contained in:
parent
ec5f2dcb5c
commit
f2e5eedaa4
@ -0,0 +1,47 @@
|
|||||||
|
package com.rainy.token.ui.components
|
||||||
|
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 共享格式化工具函数。
|
||||||
|
*
|
||||||
|
* 从 DashboardScreen / ServiceDetailScreen / WidgetProvider 提取,消除三处重复。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 格式化金额:整数无小数点,带小数保留 2 位 */
|
||||||
|
fun formatAmount(value: Double): String {
|
||||||
|
return if (value % 1.0 == 0.0) value.toInt().toString()
|
||||||
|
else String.format(Locale.US, "%.2f", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 格式化重置倒计时(秒 → "X 天 Y 小时" / "X 小时 Y 分" / "Y 分"),无效返回 "—" */
|
||||||
|
fun formatResetInSec(sec: Long): String {
|
||||||
|
if (sec <= 0) return "—"
|
||||||
|
val days = sec / 86400
|
||||||
|
val hours = (sec % 86400) / 3600
|
||||||
|
val minutes = (sec % 3600) / 60
|
||||||
|
return when {
|
||||||
|
days > 0 -> "$days 天 $hours 小时"
|
||||||
|
hours > 0 -> "$hours 小时 $minutes 分"
|
||||||
|
else -> "$minutes 分"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Widget 版本:逻辑相同但空值返回空串(非 "—"),适配 RemoteViews 布局 */
|
||||||
|
fun formatResetForWidget(sec: Long): String {
|
||||||
|
if (sec <= 0) return ""
|
||||||
|
val days = sec / 86400
|
||||||
|
val hours = (sec % 86400) / 3600
|
||||||
|
val minutes = (sec % 3600) / 60
|
||||||
|
return when {
|
||||||
|
days > 0 -> "$days 天 $hours 小时"
|
||||||
|
hours > 0 -> "$hours 小时 $minutes 分"
|
||||||
|
else -> "$minutes 分"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 标准化窗口标签:weekly → 每周,其他原样返回 */
|
||||||
|
fun normalizeWindowLabel(label: String): String = when (label.lowercase()) {
|
||||||
|
"weekly" -> "每周"
|
||||||
|
else -> label
|
||||||
|
}
|
||||||
@ -24,6 +24,9 @@ import com.rainy.token.domain.model.ServiceBalance
|
|||||||
import com.rainy.token.domain.service.ServiceType
|
import com.rainy.token.domain.service.ServiceType
|
||||||
import com.rainy.token.ui.components.StatusStyle
|
import com.rainy.token.ui.components.StatusStyle
|
||||||
import com.rainy.token.ui.components.StatusLevel
|
import com.rainy.token.ui.components.StatusLevel
|
||||||
|
import com.rainy.token.ui.components.formatAmount
|
||||||
|
import com.rainy.token.ui.components.formatResetInSec
|
||||||
|
import com.rainy.token.ui.components.normalizeWindowLabel
|
||||||
import com.rainy.token.ui.theme.StrawberryPink
|
import com.rainy.token.ui.theme.StrawberryPink
|
||||||
import com.rainy.token.ui.theme.StatusOrange
|
import com.rainy.token.ui.theme.StatusOrange
|
||||||
import com.rainy.token.ui.theme.inkMuted
|
import com.rainy.token.ui.theme.inkMuted
|
||||||
@ -353,11 +356,6 @@ internal fun OllamaUsageWindows(balance: ServiceBalance) {
|
|||||||
|
|
||||||
// ── Shared UI components ──
|
// ── Shared UI components ──
|
||||||
|
|
||||||
internal fun normalizeWindowLabel(label: String): String = when (label.lowercase()) {
|
|
||||||
"weekly" -> "每周"
|
|
||||||
else -> label
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun CompactUsageRowEmpty(label: String, resetInSec: Long?) {
|
internal fun CompactUsageRowEmpty(label: String, resetInSec: Long?) {
|
||||||
Column {
|
Column {
|
||||||
@ -452,18 +450,6 @@ internal fun CompactUsageRow(label: String, pct: Int, resetInSec: Long?) {
|
|||||||
|
|
||||||
// ── Dashboard utility functions ──
|
// ── Dashboard utility functions ──
|
||||||
|
|
||||||
internal fun formatResetInSec(sec: Long): String {
|
|
||||||
if (sec <= 0) return "—"
|
|
||||||
val days = sec / 86400
|
|
||||||
val hours = (sec % 86400) / 3600
|
|
||||||
val minutes = (sec % 3600) / 60
|
|
||||||
return when {
|
|
||||||
days > 0 -> "$days 天 $hours 小时"
|
|
||||||
hours > 0 -> "$hours 小时 $minutes 分"
|
|
||||||
else -> "$minutes 分"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun DashboardCardUi.statusBadgeStyle(): StatusStyle = when {
|
internal fun DashboardCardUi.statusBadgeStyle(): StatusStyle = when {
|
||||||
credentialState == CredentialStatus.State.NOT_CONFIGURED ->
|
credentialState == CredentialStatus.State.NOT_CONFIGURED ->
|
||||||
StatusStyle("未配置", StatusLevel.WARNING)
|
StatusStyle("未配置", StatusLevel.WARNING)
|
||||||
@ -504,8 +490,3 @@ internal fun footerText(card: DashboardCardUi): String {
|
|||||||
else -> "$timeStr 更新"
|
else -> "$timeStr 更新"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun formatAmount(value: Double): String {
|
|
||||||
return if (value % 1.0 == 0.0) value.toInt().toString()
|
|
||||||
else String.format(Locale.US, "%.2f", value)
|
|
||||||
}
|
|
||||||
@ -51,6 +51,8 @@ import com.rainy.token.ui.components.ServiceIcon
|
|||||||
import com.rainy.token.ui.components.StatusChip
|
import com.rainy.token.ui.components.StatusChip
|
||||||
import com.rainy.token.ui.components.StatusLevel
|
import com.rainy.token.ui.components.StatusLevel
|
||||||
import com.rainy.token.ui.components.StatusStyle
|
import com.rainy.token.ui.components.StatusStyle
|
||||||
|
import com.rainy.token.ui.components.formatAmount
|
||||||
|
import com.rainy.token.ui.components.formatResetInSec
|
||||||
import com.rainy.token.ui.theme.inkMuted
|
import com.rainy.token.ui.theme.inkMuted
|
||||||
import com.rainy.token.ui.theme.StrawberryPink
|
import com.rainy.token.ui.theme.StrawberryPink
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -388,18 +390,6 @@ private fun UsageWindowRow(label: String, pct: Int?, resetInSec: Long?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatResetInSec(sec: Long): String {
|
|
||||||
if (sec <= 0) return "—"
|
|
||||||
val days = sec / 86400
|
|
||||||
val hours = (sec % 86400) / 3600
|
|
||||||
val minutes = (sec % 3600) / 60
|
|
||||||
return when {
|
|
||||||
days > 0 -> "$days 天 $hours 小时"
|
|
||||||
hours > 0 -> "$hours 小时 $minutes 分"
|
|
||||||
else -> "$minutes 分"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ollama Pro 专属:5h + 每周用量窗口卡。
|
* Ollama Pro 专属:5h + 每周用量窗口卡。
|
||||||
*/
|
*/
|
||||||
@ -722,8 +712,3 @@ private fun formatTime(epochMillis: Long): String {
|
|||||||
val sdf = SimpleDateFormat("MM-dd HH:mm", Locale.getDefault())
|
val sdf = SimpleDateFormat("MM-dd HH:mm", Locale.getDefault())
|
||||||
return sdf.format(Date(epochMillis))
|
return sdf.format(Date(epochMillis))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatAmount(value: Double): String {
|
|
||||||
return if (value % 1.0 == 0.0) value.toInt().toString()
|
|
||||||
else String.format(Locale.US, "%.2f", value)
|
|
||||||
}
|
|
||||||
@ -14,6 +14,7 @@ import com.rainy.token.R
|
|||||||
import com.rainy.token.data.cache.BalanceCache
|
import com.rainy.token.data.cache.BalanceCache
|
||||||
import com.rainy.token.data.cache.balanceCacheDataStore
|
import com.rainy.token.data.cache.balanceCacheDataStore
|
||||||
import com.rainy.token.domain.service.ServiceType
|
import com.rainy.token.domain.service.ServiceType
|
||||||
|
import com.rainy.token.ui.components.normalizeWindowLabel
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@ -218,11 +219,6 @@ class OpenCodeGoWidgetProvider : AppWidgetProvider() {
|
|||||||
views.setTextViewText(R.id.row3_label, third)
|
views.setTextViewText(R.id.row3_label, third)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun normalizeWindowLabel(label: String): String = when (label.lowercase()) {
|
|
||||||
"weekly" -> "每周"
|
|
||||||
else -> label
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun populateRow(
|
private fun populateRow(
|
||||||
views: RemoteViews,
|
views: RemoteViews,
|
||||||
pctViewId: Int,
|
pctViewId: Int,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user