From f6f7accfa5488b3b88d84f4f6f67a54d8f441d8d Mon Sep 17 00:00:00 2001 From: Amir Khodak Date: Fri, 22 May 2026 16:00:17 +0000 Subject: [PATCH] =?UTF-8?q?v1.3:=20smooth=2030fps=20rotation=20(6=C2=B0=20?= =?UTF-8?q?steps),=20guaranteed=20minimum=20one=20full=20spin=20per=20tap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 4 +-- .../khodak/claudeusage/UsageUpdateWorker.kt | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 422ba6f..c6a0270 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 = 3 - versionName = "1.2" + versionCode = 4 + versionName = "1.3" } signingConfigs { diff --git a/app/src/main/java/me/khodak/claudeusage/UsageUpdateWorker.kt b/app/src/main/java/me/khodak/claudeusage/UsageUpdateWorker.kt index cddc688..cfe67ce 100644 --- a/app/src/main/java/me/khodak/claudeusage/UsageUpdateWorker.kt +++ b/app/src/main/java/me/khodak/claudeusage/UsageUpdateWorker.kt @@ -8,9 +8,11 @@ import android.content.Context import android.content.Intent import android.os.SystemClock import androidx.work.* +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import me.khodak.claudeusage.data.PreferencesManager class UsageUpdateWorker( @@ -31,6 +33,7 @@ class UsageUpdateWorker( prefs.saveUsageData(data) } catch (_: Exception) {} animJob.cancel() + animJob.join() // wait for the minimum-rotation finally block to finish } pushWidgetUpdate() @@ -40,10 +43,25 @@ class UsageUpdateWorker( private suspend fun rotateRefreshIcon() { val manager = AppWidgetManager.getInstance(context) val ids = manager.getAppWidgetIds(ComponentName(context, ClaudeUsageWidget::class.java)) - while (true) { - ClaudeUsageWidget.currentRotation = (ClaudeUsageWidget.currentRotation + 30f) % 360f - ids.forEach { id -> ClaudeUsageWidget.updateWidget(context, manager, id) } - delay(83) // ~12 fps — one full rotation per second + var totalDegrees = 0f + + try { + while (true) { + ClaudeUsageWidget.currentRotation = (ClaudeUsageWidget.currentRotation + 6f) % 360f + totalDegrees += 6f + ids.forEach { id -> ClaudeUsageWidget.updateWidget(context, manager, id) } + delay(33) // 30 fps, one full rotation per second + } + } finally { + // Even if the fetch finishes early, complete at least one full 360° + withContext(NonCancellable) { + while (totalDegrees < 360f) { + ClaudeUsageWidget.currentRotation = (ClaudeUsageWidget.currentRotation + 6f) % 360f + totalDegrees += 6f + ids.forEach { id -> ClaudeUsageWidget.updateWidget(context, manager, id) } + delay(33) + } + } } }