From de7ac8d0964bb7634192af1125b5f7f877b5976b Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sat, 16 May 2026 18:38:59 +0200 Subject: [PATCH] fix(freshness): hold checking state for 400ms minimum Cached GitHub responses resolved so fast that the spinner state was overwritten before Vue could render it, so clicking the badge from "Not checked" looked like nothing happened. --- src/hooks/useNoteFreshness.hook.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/hooks/useNoteFreshness.hook.ts b/src/hooks/useNoteFreshness.hook.ts index 617ca8b..92f4d86 100644 --- a/src/hooks/useNoteFreshness.hook.ts +++ b/src/hooks/useNoteFreshness.hook.ts @@ -13,6 +13,8 @@ export type FreshnessStatus = | "outdated" | "offline" +const MIN_SPINNER_MS = 400 + export const useNoteFreshness = ({ user, repo, @@ -38,15 +40,24 @@ export const useNoteFreshness = ({ const check = async () => { if (!path.value) return status.value = "checking" + const startedAt = performance.now() + + let next: FreshnessStatus const remoteSha = await fetchLatestSha(path.value) if (remoteSha === null) { - status.value = "offline" - return + next = "offline" + } else { + latestSha.value = remoteSha + lastCheckedAt.value = new Date() + const local = await expectedSha() + next = remoteSha === local ? "verified" : "outdated" } - latestSha.value = remoteSha - lastCheckedAt.value = new Date() - const local = await expectedSha() - status.value = remoteSha === local ? "verified" : "outdated" + + const elapsed = performance.now() - startedAt + if (elapsed < MIN_SPINNER_MS) { + await new Promise((r) => setTimeout(r, MIN_SPINNER_MS - elapsed)) + } + status.value = next } const pullLatest = async (): Promise => {