diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8b67400..a054e59 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "me.khodak.claudeusage" minSdk = 26 targetSdk = 34 - versionCode = 12 - versionName = "1.11" + versionCode = 13 + versionName = "1.12" } signingConfigs { diff --git a/app/src/main/java/me/khodak/claudeusage/BarRenderer.kt b/app/src/main/java/me/khodak/claudeusage/BarRenderer.kt index 080a1b7..5ff6378 100644 --- a/app/src/main/java/me/khodak/claudeusage/BarRenderer.kt +++ b/app/src/main/java/me/khodak/claudeusage/BarRenderer.kt @@ -42,14 +42,20 @@ object BarRenderer { canvas.drawRoundRect(fill, cornerPx, cornerPx, paint) } - // Pace tick — "where you should be right now" + // Pace tick — "where you should be right now". + // Wider than before and wrapped in a white halo so it stands out on any fill color. if (markerPct != null && tierColor != null) { val m = markerPct.coerceIn(0, 100) - val tickW = (wPx * 0.012f).coerceIn(3f, 7f) + val coreW = (wPx * 0.022f).coerceIn(9f, 14f) // tier-colored core + val halo = coreW * 0.6f // white outline on each side var x = wPx * m / 100f - x = x.coerceIn(tickW / 2f, wPx - tickW / 2f) + x = x.coerceIn(coreW / 2f + halo, wPx - coreW / 2f - halo) + // white halo + paint.color = 0xFFFFFFFF.toInt() + canvas.drawRect(x - coreW / 2f - halo, 0f, x + coreW / 2f + halo, hPx.toFloat(), paint) + // tier-colored core paint.color = tierColor - canvas.drawRect(x - tickW / 2f, 0f, x + tickW / 2f, hPx.toFloat(), paint) + canvas.drawRect(x - coreW / 2f, 0f, x + coreW / 2f, hPx.toFloat(), paint) } return bmp diff --git a/app/src/main/java/me/khodak/claudeusage/ClaudeUsageWidget.kt b/app/src/main/java/me/khodak/claudeusage/ClaudeUsageWidget.kt index b3e1c20..e9d2630 100644 --- a/app/src/main/java/me/khodak/claudeusage/ClaudeUsageWidget.kt +++ b/app/src/main/java/me/khodak/claudeusage/ClaudeUsageWidget.kt @@ -107,8 +107,7 @@ class ClaudeUsageWidget : AppWidgetProvider() { val pace = PaceCalc.compute(apiData.fiveHourUtilization, apiData.utilizationResetAtEpoch, PaceCalc.SESSION_WINDOW_MS) v.setTextViewText(R.id.tv_session_value, "$pct%") v.setImageViewBitmap(R.id.bar_session, BarRenderer.render(pct, pace?.markerPct, SESSION_FILL, pace?.tierColor)) - v.setTextViewText(R.id.tv_session_label, - if (pace != null) PaceCalc.shortTag(apiData.fiveHourUtilization, pace) else formatReset(apiData.utilizationResetAtEpoch)) + v.setTextViewText(R.id.tv_session_label, formatReset(apiData.utilizationResetAtEpoch)) } hasApiMessages -> { val rem = apiData!!.effectiveRemaining @@ -137,8 +136,7 @@ class ClaudeUsageWidget : AppWidgetProvider() { val pace = PaceCalc.compute(apiData.weeklyUtilization, apiData.weeklyResetAtEpoch, PaceCalc.WEEKLY_WINDOW_MS) v.setTextViewText(R.id.tv_weekly_value, "$wPct%") v.setImageViewBitmap(R.id.bar_weekly, BarRenderer.render(wPct, pace?.markerPct, WEEKLY_FILL, pace?.tierColor)) - v.setTextViewText(R.id.tv_weekly_label, - if (pace != null) PaceCalc.shortTag(apiData.weeklyUtilization, pace) else formatReset(apiData.weeklyResetAtEpoch)) + v.setTextViewText(R.id.tv_weekly_label, formatReset(apiData.weeklyResetAtEpoch)) } else { val weeklyDays = Integer.bitCount(prefs.getWeeklyMask()) v.setTextViewText(R.id.tv_weekly_value, "${weeklyDays}d") @@ -187,7 +185,7 @@ class ClaudeUsageWidget : AppWidgetProvider() { val pace = PaceCalc.compute(apiData.fiveHourUtilization, apiData.utilizationResetAtEpoch, PaceCalc.SESSION_WINDOW_MS) v.setTextViewText(R.id.tv_session_value, "$pct%") v.setImageViewBitmap(R.id.bar_session, BarRenderer.render(pct, pace?.markerPct, SESSION_FILL, pace?.tierColor)) - v.setTextViewText(R.id.tv_session_label, resetWithPace(apiData.utilizationResetAtEpoch, apiData.fiveHourUtilization, pace)) + v.setTextViewText(R.id.tv_session_label, formatReset(apiData.utilizationResetAtEpoch)) } hasApiMessages -> { val rem = apiData!!.effectiveRemaining @@ -219,7 +217,7 @@ class ClaudeUsageWidget : AppWidgetProvider() { val pace = PaceCalc.compute(apiData.weeklyUtilization, apiData.weeklyResetAtEpoch, PaceCalc.WEEKLY_WINDOW_MS) v.setTextViewText(R.id.tv_weekly_value, "$wPct%") v.setImageViewBitmap(R.id.bar_weekly, BarRenderer.render(wPct, pace?.markerPct, WEEKLY_FILL, pace?.tierColor)) - v.setTextViewText(R.id.tv_weekly_label, resetWithPace(apiData.weeklyResetAtEpoch, apiData.weeklyUtilization, pace)) + v.setTextViewText(R.id.tv_weekly_label, formatReset(apiData.weeklyResetAtEpoch)) } else { val weeklyDays = Integer.bitCount(prefs.getWeeklyMask()) v.setTextViewText(R.id.tv_weekly_value, "$weeklyDays d") @@ -260,14 +258,6 @@ class ClaudeUsageWidget : AppWidgetProvider() { } } - /** "Resets at 3:00 PM · 8% under pace" — reset line with the pace tag appended. */ - private fun resetWithPace(resetEpoch: Long, usedPct: Float, pace: PaceCalc.Pace?): CharSequence { - val reset = formatReset(resetEpoch) - if (pace == null) return reset - val tag = PaceCalc.shortTag(usedPct, pace) - return if (reset.isBlank()) tag else "$reset · $tag" - } - private fun formatReset(epochMs: Long): String { if (epochMs <= 0) return "" val now = System.currentTimeMillis() diff --git a/releases/latest/claude-usage-widget.apk b/releases/latest/claude-usage-widget.apk index 7f0a2b8..803cc7f 100644 Binary files a/releases/latest/claude-usage-widget.apk and b/releases/latest/claude-usage-widget.apk differ