Skip to content
This repository was archived by the owner on Oct 10, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@t3tools/desktop",
"version": "0.0.2",
"version": "0.0.3",
"private": true,
"main": "dist-electron/main.js",
"scripts": {
Expand Down
7 changes: 7 additions & 0 deletions apps/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const UPDATE_STATE_CHANNEL = "desktop:update-state";
const UPDATE_GET_STATE_CHANNEL = "desktop:update-get-state";
const UPDATE_DOWNLOAD_CHANNEL = "desktop:update-download";
const UPDATE_INSTALL_CHANNEL = "desktop:update-install";
const UPDATE_CHECK_CHANNEL = "desktop:update-check";
const STATE_DIR =
process.env.T3CODE_STATE_DIR?.trim() || Path.join(OS.homedir(), ".t3", "userdata");
const DESKTOP_SCHEME = "t3";
Expand Down Expand Up @@ -1185,6 +1186,12 @@ function registerIpcHandlers(): void {
ipcMain.removeHandler(UPDATE_GET_STATE_CHANNEL);
ipcMain.handle(UPDATE_GET_STATE_CHANNEL, async () => updateState);

ipcMain.removeHandler(UPDATE_CHECK_CHANNEL);
ipcMain.handle(UPDATE_CHECK_CHANNEL, async () => {
await checkForUpdates("manual");
return updateState;
});

ipcMain.removeHandler(UPDATE_DOWNLOAD_CHANNEL);
ipcMain.handle(UPDATE_DOWNLOAD_CHANNEL, async () => {
const result = await downloadAvailableUpdate();
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const UPDATE_STATE_CHANNEL = "desktop:update-state";
const UPDATE_GET_STATE_CHANNEL = "desktop:update-get-state";
const UPDATE_DOWNLOAD_CHANNEL = "desktop:update-download";
const UPDATE_INSTALL_CHANNEL = "desktop:update-install";
const UPDATE_CHECK_CHANNEL = "desktop:update-check";
const wsUrl = process.env.T3CODE_DESKTOP_WS_URL ?? null;

contextBridge.exposeInMainWorld("desktopBridge", {
Expand All @@ -32,6 +33,7 @@ contextBridge.exposeInMainWorld("desktopBridge", {
};
},
getUpdateState: () => ipcRenderer.invoke(UPDATE_GET_STATE_CHANNEL),
checkForUpdate: () => ipcRenderer.invoke(UPDATE_CHECK_CHANNEL),
downloadUpdate: () => ipcRenderer.invoke(UPDATE_DOWNLOAD_CHANNEL),
installUpdate: () => ipcRenderer.invoke(UPDATE_INSTALL_CHANNEL),
onUpdateState: (listener) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@t3tools/web",
"version": "0.0.2",
"version": "0.0.3",
"private": true,
"type": "module",
"scripts": {
Expand Down
38 changes: 36 additions & 2 deletions apps/web/src/routes/_chat.settings.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createFileRoute } from "@tanstack/react-router";
import { useQuery } from "@tanstack/react-query";
import { useCallback, useState } from "react";
import { type ProviderKind } from "@t3tools/contracts";
import { useCallback, useEffect, useState } from "react";
import { type DesktopUpdateState, type ProviderKind } from "@t3tools/contracts";
import { getModelOptions, normalizeModelSlug } from "@t3tools/shared/model";

import {
Expand Down Expand Up @@ -211,6 +211,40 @@ function SettingsRouteView() {
Partial<Record<ProviderKind, string | null>>
>({});

const [updateState, setUpdateState] = useState<DesktopUpdateState | null>(null);
const [isCheckingUpdate, setIsCheckingUpdate] = useState(false);

useEffect(() => {
if (!isElectron || !window.desktopBridge) return;
const bridge = window.desktopBridge;
void bridge.getUpdateState().then(setUpdateState);
const unsubscribe = bridge.onUpdateState(setUpdateState);
return unsubscribe;
}, []);

const handleCheckForUpdate = useCallback(async () => {
if (!isElectron || !window.desktopBridge) return;
setIsCheckingUpdate(true);
try {
const state = await window.desktopBridge.checkForUpdate();
setUpdateState(state);
} finally {
setIsCheckingUpdate(false);
}
}, []);

const handleDownloadUpdate = useCallback(async () => {
if (!isElectron || !window.desktopBridge) return;
const result = await window.desktopBridge.downloadUpdate();
setUpdateState(result.state);
}, []);

const handleInstallUpdate = useCallback(async () => {
if (!isElectron || !window.desktopBridge) return;
const result = await window.desktopBridge.installUpdate();
setUpdateState(result.state);
}, []);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

const codexBinaryPath = settings.codexBinaryPath;
const codexHomePath = settings.codexHomePath;
const accentColor = settings.accentColor;
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export interface DesktopBridge {
openExternal: (url: string) => Promise<boolean>;
onMenuAction: (listener: (action: string) => void) => () => void;
getUpdateState: () => Promise<DesktopUpdateState>;
checkForUpdate: () => Promise<DesktopUpdateState>;
downloadUpdate: () => Promise<DesktopUpdateActionResult>;
installUpdate: () => Promise<DesktopUpdateActionResult>;
onUpdateState: (listener: (state: DesktopUpdateState) => void) => () => void;
Expand Down
Loading