diff --git a/app/components/settings.tsx b/app/components/settings.tsx
index e2464481341..82ce70e5a18 100644
--- a/app/components/settings.tsx
+++ b/app/components/settings.tsx
@@ -49,7 +49,7 @@ import Locale, {
changeLang,
getLang,
} from "../locales";
-import { copyToClipboard } from "../utils";
+import { copyToClipboard, clientUpdate, semverCompare } from "../utils";
import Link from "next/link";
import {
Anthropic,
@@ -585,7 +585,7 @@ export function Settings() {
const [checkingUpdate, setCheckingUpdate] = useState(false);
const currentVersion = updateStore.formatVersion(updateStore.version);
const remoteId = updateStore.formatVersion(updateStore.remoteVersion);
- const hasNewVersion = currentVersion !== remoteId;
+ const hasNewVersion = semverCompare(currentVersion, remoteId) === -1;
const updateUrl = getClientConfig()?.isApp ? RELEASE_URL : UPDATE_URL;
function checkUpdate(force = false) {
@@ -1357,9 +1357,17 @@ export function Settings() {
{checkingUpdate ? (
) : hasNewVersion ? (
-
- {Locale.Settings.Update.GoToUpdate}
-
+ clientConfig?.isApp ? (
+ }
+ text={Locale.Settings.Update.GoToUpdate}
+ onClick={() => clientUpdate()}
+ />
+ ) : (
+
+ {Locale.Settings.Update.GoToUpdate}
+
+ )
) : (
}
diff --git a/app/global.d.ts b/app/global.d.ts
index 8ee636bcd3c..897871fec37 100644
--- a/app/global.d.ts
+++ b/app/global.d.ts
@@ -26,6 +26,13 @@ declare interface Window {
isPermissionGranted(): Promise;
sendNotification(options: string | Options): void;
};
+ updater: {
+ checkUpdate(): Promise;
+ installUpdate(): Promise;
+ onUpdaterEvent(
+ handler: (status: UpdateStatusResult) => void,
+ ): Promise;
+ };
http: {
fetch(
url: string,
diff --git a/app/locales/cn.ts b/app/locales/cn.ts
index b7debe80514..e514eb4fe65 100644
--- a/app/locales/cn.ts
+++ b/app/locales/cn.ts
@@ -205,6 +205,8 @@ const cn = {
IsChecking: "正在检查更新...",
FoundUpdate: (x: string) => `发现新版本:${x}`,
GoToUpdate: "前往更新",
+ Success: "更新成功!",
+ Failed: "更新失败",
},
SendKey: "发送键",
Theme: "主题",
diff --git a/app/locales/en.ts b/app/locales/en.ts
index 5cc296f1efd..c86cc08f039 100644
--- a/app/locales/en.ts
+++ b/app/locales/en.ts
@@ -207,6 +207,8 @@ const en: LocaleType = {
IsChecking: "Checking update...",
FoundUpdate: (x: string) => `Found new version: ${x}`,
GoToUpdate: "Update",
+ Success: "Update Successful.",
+ Failed: "Update Failed.",
},
SendKey: "Send Key",
Theme: "Theme",
diff --git a/app/store/update.ts b/app/store/update.ts
index e68fde369d5..327dc5e88f9 100644
--- a/app/store/update.ts
+++ b/app/store/update.ts
@@ -6,6 +6,7 @@ import {
} from "../constant";
import { getClientConfig } from "../config/client";
import { createPersistStore } from "../utils/store";
+import { clientUpdate } from "../utils";
import ChatGptIcon from "../icons/chatgpt.png";
import Locale from "../locales";
import { ClientApi } from "../client/api";
@@ -119,6 +120,7 @@ export const useUpdateStore = createPersistStore(
icon: `${ChatGptIcon.src}`,
sound: "Default",
});
+ clientUpdate();
}
}
});
diff --git a/app/utils.ts b/app/utils.ts
index 5d45017107c..d8fc46330d1 100644
--- a/app/utils.ts
+++ b/app/utils.ts
@@ -386,3 +386,37 @@ export function getOperationId(operation: {
`${operation.method.toUpperCase()}${operation.path.replaceAll("/", "_")}`
);
}
+
+export function clientUpdate() {
+ // this a wild for updating client app
+ return window.__TAURI__?.updater
+ .checkUpdate()
+ .then((updateResult) => {
+ if (updateResult.shouldUpdate) {
+ window.__TAURI__?.updater
+ .installUpdate()
+ .then((result) => {
+ showToast(Locale.Settings.Update.Success);
+ })
+ .catch((e) => {
+ console.error("[Install Update Error]", e);
+ showToast(Locale.Settings.Update.Failed);
+ });
+ }
+ })
+ .catch((e) => {
+ console.error("[Check Update Error]", e);
+ showToast(Locale.Settings.Update.Failed);
+ });
+}
+
+// https://gist.github.com/iwill/a83038623ba4fef6abb9efca87ae9ccb
+export function semverCompare(a: string, b: string) {
+ if (a.startsWith(b + "-")) return -1;
+ if (b.startsWith(a + "-")) return 1;
+ return a.localeCompare(b, undefined, {
+ numeric: true,
+ sensitivity: "case",
+ caseFirst: "upper",
+ });
+}
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index cc137ee8afd..56a5b46a9e6 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -99,7 +99,7 @@
"endpoints": [
"https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/releases/latest/download/latest.json"
],
- "dialog": false,
+ "dialog": true,
"windows": {
"installMode": "passive"
},