From e37a75a411c584d3e463662a0219fd342d4247ab Mon Sep 17 00:00:00 2001
From: Adam <2363879+adamdotdevin@users.noreply.github.com>
Date: Thu, 18 Dec 2025 04:26:17 -0600
Subject: feat(desktop): custom update toast
---
packages/desktop/src/app.tsx | 91 ++++++++++++++++---------------
packages/desktop/src/context/platform.tsx | 6 ++
packages/desktop/src/pages/layout.tsx | 55 +++++++++++++++----
3 files changed, 98 insertions(+), 54 deletions(-)
(limited to 'packages/desktop')
diff --git a/packages/desktop/src/app.tsx b/packages/desktop/src/app.tsx
index 10bde2202..91952fc9d 100644
--- a/packages/desktop/src/app.tsx
+++ b/packages/desktop/src/app.tsx
@@ -1,5 +1,5 @@
import "@/index.css"
-import { Show } from "solid-js"
+import { ErrorBoundary, Show } from "solid-js"
import { Router, Route, Navigate } from "@solidjs/router"
import { MetaProvider } from "@solidjs/meta"
import { Font } from "@opencode-ai/ui/font"
@@ -20,6 +20,7 @@ import Layout from "@/pages/layout"
import Home from "@/pages/home"
import DirectoryLayout from "@/pages/directory-layout"
import Session from "@/pages/session"
+import { ErrorPage } from "./pages/error"
declare global {
interface Window {
@@ -38,48 +39,50 @@ const url =
export function App() {
return (
-
-
-
-
-
-
-
-
-
-
- (
-
- {props.children}
-
- )}
- >
-
-
- } />
- (
-
-
-
-
-
-
-
- )}
- />
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ (
+
+ {props.children}
+
+ )}
+ >
+
+
+ } />
+ (
+
+
+
+
+
+
+
+ )}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
)
}
diff --git a/packages/desktop/src/context/platform.tsx b/packages/desktop/src/context/platform.tsx
index 92bb2ba15..2ac9f64d4 100644
--- a/packages/desktop/src/context/platform.tsx
+++ b/packages/desktop/src/context/platform.tsx
@@ -19,6 +19,12 @@ export type Platform = {
/** Storage mechanism, defaults to localStorage */
storage?: (name?: string) => SyncStorage | AsyncStorage
+
+ /** Check for updates (Tauri only) */
+ checkUpdate?(): Promise<{ updateAvailable: boolean; version?: string }>
+
+ /** Install updates (Tauri only) */
+ update?(): Promise
}
export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({
diff --git a/packages/desktop/src/pages/layout.tsx b/packages/desktop/src/pages/layout.tsx
index 540c5d778..fccb6d595 100644
--- a/packages/desktop/src/pages/layout.tsx
+++ b/packages/desktop/src/pages/layout.tsx
@@ -1,4 +1,15 @@
-import { createEffect, createMemo, createSignal, For, Match, ParentProps, Show, Switch, type JSX } from "solid-js"
+import {
+ createEffect,
+ createMemo,
+ createSignal,
+ For,
+ Match,
+ onMount,
+ ParentProps,
+ Show,
+ Switch,
+ type JSX,
+} from "solid-js"
import { DateTime } from "luxon"
import { A, useNavigate, useParams } from "@solidjs/router"
import { useLayout, getAvatarColors } from "@/context/layout"
@@ -28,7 +39,7 @@ import {
} from "@thisbeyond/solid-dnd"
import type { DragEvent } from "@thisbeyond/solid-dnd"
import { useProviders } from "@/hooks/use-providers"
-import { Toast } from "@opencode-ai/ui/toast"
+import { showToast, Toast } from "@opencode-ai/ui/toast"
import { useGlobalSDK } from "@/context/global-sdk"
import { useNotification } from "@/context/notification"
import { Binary } from "@opencode-ai/util/binary"
@@ -46,14 +57,6 @@ export default function Layout(props: ParentProps) {
let scrollContainerRef: HTMLDivElement | undefined
- function scrollToSession(sessionId: string) {
- if (!scrollContainerRef) return
- const element = scrollContainerRef.querySelector(`[data-session-id="${sessionId}"]`)
- if (element) {
- element.scrollIntoView({ block: "center", behavior: "smooth" })
- }
- }
-
const params = useParams()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
@@ -65,6 +68,30 @@ export default function Layout(props: ParentProps) {
const dialog = useDialog()
const command = useCommand()
+ onMount(async () => {
+ if (platform.checkUpdate && platform.update) {
+ const { updateAvailable, version } = await platform.checkUpdate()
+ if (updateAvailable) {
+ showToast({
+ persistent: true,
+ icon: "download",
+ title: "Update available",
+ description: `A new version of OpenCode (${version}) is now available to install.`,
+ actions: [
+ {
+ label: "Install and restart",
+ onClick: () => platform!.update!(),
+ },
+ {
+ label: "Not yet",
+ onClick: "dismiss",
+ },
+ ],
+ })
+ }
+ }
+ })
+
function flattenSessions(sessions: Session[]): Session[] {
const childrenMap = new Map()
for (const session of sessions) {
@@ -87,6 +114,14 @@ export default function Layout(props: ParentProps) {
return result
}
+ function scrollToSession(sessionId: string) {
+ if (!scrollContainerRef) return
+ const element = scrollContainerRef.querySelector(`[data-session-id="${sessionId}"]`)
+ if (element) {
+ element.scrollIntoView({ block: "center", behavior: "smooth" })
+ }
+ }
+
const currentSessions = createMemo(() => {
if (!params.dir) return []
const directory = base64Decode(params.dir)
--
cgit v1.2.3