From e425be5c9655fdfe5f5227f712420139e3d14c60 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Mon, 4 May 2026 23:53:48 +0200 Subject: [PATCH] refactor(freshness): drop time-based stale-known status The 2-minute timer + tick ref decayed verified to stale-known and rendered a clock icon, but the user can always click the badge to re-check. Removing the timer simplifies the hook and the badge has one fewer visual state. --- src/components/NoteFreshnessBadge.vue | 39 +++++++-------------------- src/hooks/useNoteFreshness.hook.ts | 38 ++++++-------------------- 2 files changed, 17 insertions(+), 60 deletions(-) diff --git a/src/components/NoteFreshnessBadge.vue b/src/components/NoteFreshnessBadge.vue index be01e36..40d582b 100644 --- a/src/components/NoteFreshnessBadge.vue +++ b/src/components/NoteFreshnessBadge.vue @@ -13,9 +13,6 @@ defineEmits<{ (e: "click"): void }>() const formatTime = (d: Date) => d.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" }) -const minutesAgo = (d: Date) => - Math.max(1, Math.round((Date.now() - d.getTime()) / 60000)) - const label = computed(() => { switch (props.status) { case "verified": @@ -24,10 +21,6 @@ const label = computed(() => { return "Checking…" case "outdated": return "Outdated" - case "stale-known": - return props.lastCheckedAt - ? `Checked ${minutesAgo(props.lastCheckedAt)}m ago` - : "Not checked" case "offline": return "Can’t reach GitHub" case "unknown": @@ -44,8 +37,6 @@ const tooltip = computed(() => { : "Click to re-check." case "outdated": return "GitHub has a newer version. Click to pull latest." - case "stale-known": - return "Click to verify against GitHub." case "offline": return "Could not reach GitHub. Click to retry." case "checking": @@ -88,14 +79,9 @@ const isBusy = computed(() => props.status === "checking") props.status === "checking") stroke-linecap="round" stroke-linejoin="round" > - - + + + props.status === "checking") } .state-unknown, -.state-stale-known, .state-checking { color: var(--color-base-content); opacity: 0.6; diff --git a/src/hooks/useNoteFreshness.hook.ts b/src/hooks/useNoteFreshness.hook.ts index c1968c4..b0ce322 100644 --- a/src/hooks/useNoteFreshness.hook.ts +++ b/src/hooks/useNoteFreshness.hook.ts @@ -1,4 +1,4 @@ -import { computed, Ref, ref } from "vue" +import { Ref, ref } from "vue" import { useGitHubContent } from "@/hooks/useGitHubContent.hook" import { markdownBuilder } from "@/hooks/useMarkdown.hook" @@ -10,12 +10,9 @@ export type FreshnessStatus = | "unknown" | "checking" | "verified" - | "stale-known" | "outdated" | "offline" -const STALE_AFTER_MS = 2 * 60 * 1000 - export const useNoteFreshness = ({ user, repo, @@ -32,54 +29,36 @@ export const useNoteFreshness = ({ const store = useUserRepoStore() const { fetchLatestSha } = useGitHubContent({ user, repo }) - const rawStatus = ref("unknown") + const status = ref("unknown") const lastCheckedAt = ref(null) const latestSha = ref(null) - const tick = ref(0) - let staleTimer: ReturnType | null = null - - const status = computed(() => { - void tick.value - if (rawStatus.value !== "verified") return rawStatus.value - if (!lastCheckedAt.value) return rawStatus.value - const age = Date.now() - lastCheckedAt.value.getTime() - return age > STALE_AFTER_MS ? "stale-known" : "verified" - }) - - const armStaleTimer = () => { - if (staleTimer) clearTimeout(staleTimer) - staleTimer = setTimeout(() => { - tick.value++ - }, STALE_AFTER_MS + 100) - } const expectedSha = async () => (await getEditedSha()) ?? sha.value const check = async () => { if (!path.value) return - rawStatus.value = "checking" + status.value = "checking" const remoteSha = await fetchLatestSha(path.value) if (remoteSha === null) { - rawStatus.value = "offline" + status.value = "offline" return } latestSha.value = remoteSha lastCheckedAt.value = new Date() const local = await expectedSha() - rawStatus.value = remoteSha === local ? "verified" : "outdated" - armStaleTimer() + status.value = remoteSha === local ? "verified" : "outdated" } const pullLatest = async (): Promise => { if (!path.value) return null const remoteSha = latestSha.value ?? (await fetchLatestSha(path.value)) if (!remoteSha) { - rawStatus.value = "offline" + status.value = "offline" return null } const fileContent = await queryFileContent(user, repo, remoteSha) if (!fileContent) { - rawStatus.value = "offline" + status.value = "offline" return null } const { saveCacheNote } = prepareNoteCache(sha.value, path.value) @@ -90,8 +69,7 @@ export const useNoteFreshness = ({ store.addFile({ path: path.value, sha: remoteSha }) latestSha.value = remoteSha lastCheckedAt.value = new Date() - rawStatus.value = "verified" - armStaleTimer() + status.value = "verified" const { getRawContent } = markdownBuilder(sha.value) return getRawContent(fileContent) }