diff --git a/src/features/updates/UpdateSettings.test.tsx b/src/features/updates/UpdateSettings.test.tsx index ec27fcb7c..8eeea76fb 100644 --- a/src/features/updates/UpdateSettings.test.tsx +++ b/src/features/updates/UpdateSettings.test.tsx @@ -13,6 +13,13 @@ import { afterEach, expect, it, vi } from "vitest"; import { UpdateSettings } from "./UpdateSettings"; import { createUpdates, type UpdatePlatform, type Updates } from "./updates"; +const native = vi.hoisted(() => ({ + getVersion: vi.fn(async () => "1.2.3"), + isTauri: vi.fn(() => false), +})); +vi.mock("@tauri-apps/api/app", () => ({ getVersion: native.getVersion })); +vi.mock("@tauri-apps/api/core", () => ({ isTauri: native.isTauri })); + let updates: Updates | undefined; afterEach(() => { cleanup(); @@ -110,6 +117,27 @@ it("explains builds without automatic updates", async () => { expect(screen.getByRole("button", { name: "Check Again" })).toBeVisible(); }); +it("shows the installed version in the header", async () => { + native.isTauri.mockReturnValue(true); + try { + renderSettings({}); + const subtitle = await screen.findByText( + "Keep Buzz up to date with the latest features and fixes.", + ); + // The subtitle renders the version on its own line above the tagline. + const lineBreaks = subtitle.querySelectorAll("br"); + const text = subtitle.textContent ?? ""; + expect(lineBreaks).toHaveLength(1); + expect(text.startsWith("Version 1.2.3")).toBe(true); + expect( + text.endsWith("Keep Buzz up to date with the latest features and fixes."), + ).toBe(true); + expect(native.getVersion).toHaveBeenCalledOnce(); + } finally { + native.isTauri.mockReturnValue(false); + } +}); + function deferred() { let resolve!: (value: T) => void; let reject!: (reason: unknown) => void; diff --git a/src/features/updates/UpdateSettings.tsx b/src/features/updates/UpdateSettings.tsx index 0887901bb..7e9c497ea 100644 --- a/src/features/updates/UpdateSettings.tsx +++ b/src/features/updates/UpdateSettings.tsx @@ -1,4 +1,6 @@ -import { useEffect, useSyncExternalStore } from "react"; +import { useEffect, useState, useSyncExternalStore } from "react"; +import { getVersion } from "@tauri-apps/api/app"; +import { isTauri } from "@tauri-apps/api/core"; import { Button } from "../../shared/design-system/ui/Button"; import { Header } from "../../shared/design-system/ui/Header"; import type { Updates } from "./updates"; @@ -19,6 +21,20 @@ export function UpdateSettings({ () => (active ? updates.showInline() : undefined), [active, updates], ); + // Browser builds have no native version; leave it unset there. + const [version, setVersion] = useState(null); + useEffect(() => { + if (!isTauri()) return; + let cancelled = false; + getVersion() + .then((found) => { + if (!cancelled) setVersion(found); + }) + .catch(() => {}); + return () => { + cancelled = true; + }; + }, []); const pending = [ "checking", "available", @@ -50,7 +66,17 @@ export function UpdateSettings({
+ Version {version} +
+ Keep Buzz up to date with the latest features and fixes. + + ) : ( + "Keep Buzz up to date with the latest features and fixes." + ) + } />