From f62ba5eb865898d515270ab31a11cbcbbb8d5ff6 Mon Sep 17 00:00:00 2001
From: Luke Parker <10430890+Hona@users.noreply.github.com>
Date: Thu, 4 Jun 2026 09:51:40 +1000
Subject: [PATCH] fix(app): hide unavailable titlebar update (#30642)
---
packages/app/src/components/titlebar.tsx | 4 +++-
packages/app/src/pages/layout.tsx | 7 ++-----
packages/app/src/pages/layout/update.test.ts | 19 +++++++++++++++++++
packages/app/src/pages/layout/update.ts | 10 ++++++++++
4 files changed, 34 insertions(+), 6 deletions(-)
create mode 100644 packages/app/src/pages/layout/update.test.ts
create mode 100644 packages/app/src/pages/layout/update.ts
diff --git a/packages/app/src/components/titlebar.tsx b/packages/app/src/components/titlebar.tsx
index e38351873..c2af72738 100644
--- a/packages/app/src/components/titlebar.tsx
+++ b/packages/app/src/components/titlebar.tsx
@@ -707,7 +707,9 @@ type TitlebarV2RightState = {
function TitlebarV2Right(props: { state: TitlebarV2RightState }) {
return (
)
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index 3ac042360..c507ff4aa 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -89,6 +89,7 @@ import {
} from "./layout/sidebar-workspace"
import { ProjectDragOverlay, SortableProject, type ProjectSidebarContext } from "./layout/sidebar-project"
import { SidebarContent } from "./layout/sidebar-shell"
+import { runUpdateAndRestart } from "./layout/update"
export default function Layout(props: ParentProps) {
const [store, setStore, , ready] = persisted(
@@ -183,11 +184,7 @@ export default function Layout(props: ParentProps) {
return updateQuery.data.version ?? ""
}
const installUpdate = () => {
- if (!platform.updateAndRestart) return
- setUpdate("installing", true)
- void platform.updateAndRestart().catch(() => {
- setUpdate("installing", false)
- })
+ runUpdateAndRestart(platform.updateAndRestart, (installing) => setUpdate("installing", installing))
}
const titlebarUpdate: TitlebarUpdate = {
version: updateVersion,
diff --git a/packages/app/src/pages/layout/update.test.ts b/packages/app/src/pages/layout/update.test.ts
new file mode 100644
index 000000000..1fd86965c
--- /dev/null
+++ b/packages/app/src/pages/layout/update.test.ts
@@ -0,0 +1,19 @@
+import { describe, expect, test } from "bun:test"
+import { runUpdateAndRestart } from "./update"
+
+describe("runUpdateAndRestart", () => {
+ test("clears the installing state when restart resolves without exiting", async () => {
+ const states: boolean[] = []
+ await new Promise((resolve) => {
+ runUpdateAndRestart(
+ async () => {},
+ (installing) => {
+ states.push(installing)
+ if (states.length === 2) resolve()
+ },
+ )
+ })
+
+ expect(states).toEqual([true, false])
+ })
+})
diff --git a/packages/app/src/pages/layout/update.ts b/packages/app/src/pages/layout/update.ts
new file mode 100644
index 000000000..563e2c745
--- /dev/null
+++ b/packages/app/src/pages/layout/update.ts
@@ -0,0 +1,10 @@
+export function runUpdateAndRestart(
+ updateAndRestart: (() => Promise) | undefined,
+ setInstalling: (installing: boolean) => void,
+) {
+ if (!updateAndRestart) return
+ setInstalling(true)
+ void updateAndRestart()
+ .catch(() => undefined)
+ .finally(() => setInstalling(false))
+}