From 2eebfcf6fe873595a69ac0de805811fa7ed94f12 Mon Sep 17 00:00:00 2001
From: lloydzhou <lloydzhou@qq.com>
Date: Fri, 11 Oct 2024 11:29:22 +0800
Subject: [PATCH] client app tauri updater #2966

---
 app/components/settings.tsx | 16 ++++++++++++----
 app/global.d.ts             |  7 +++++++
 app/locales/cn.ts           |  2 ++
 app/locales/en.ts           |  2 ++
 app/store/update.ts         |  2 ++
 app/utils.ts                | 23 +++++++++++++++++++++++
 6 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/app/components/settings.tsx b/app/components/settings.tsx
index 9f338718e..9ee919b8d 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 } from "../utils";
 import Link from "next/link";
 import {
   Anthropic,
@@ -1357,9 +1357,17 @@ export function Settings() {
             {checkingUpdate ? (
               <LoadingIcon />
             ) : hasNewVersion ? (
-              <Link href={updateUrl} target="_blank" className="link">
-                {Locale.Settings.Update.GoToUpdate}
-              </Link>
+              clientConfig?.isApp ? (
+                <IconButton
+                  icon={<ResetIcon></ResetIcon>}
+                  text={Locale.Settings.Update.GoToUpdate}
+                  onClick={() => clientUpdate()}
+                />
+              ) : (
+                <Link href={updateUrl} target="_blank" className="link">
+                  {Locale.Settings.Update.GoToUpdate}
+                </Link>
+              )
             ) : (
               <IconButton
                 icon={<ResetIcon></ResetIcon>}
diff --git a/app/global.d.ts b/app/global.d.ts
index 8ee636bcd..897871fec 100644
--- a/app/global.d.ts
+++ b/app/global.d.ts
@@ -26,6 +26,13 @@ declare interface Window {
       isPermissionGranted(): Promise<boolean>;
       sendNotification(options: string | Options): void;
     };
+    updater: {
+      checkUpdate(): Promise<UpdateResult>;
+      installUpdate(): Promise<void>;
+      onUpdaterEvent(
+        handler: (status: UpdateStatusResult) => void,
+      ): Promise<UnlistenFn>;
+    };
     http: {
       fetch<T>(
         url: string,
diff --git a/app/locales/cn.ts b/app/locales/cn.ts
index e5bcca0ed..3086cc63e 100644
--- a/app/locales/cn.ts
+++ b/app/locales/cn.ts
@@ -205,6 +205,8 @@ const cn = {
       IsChecking: "正在检查更新...",
       FoundUpdate: (x: string) => `发现新版本:${x}`,
       GoToUpdate: "前往更新",
+      Success: "Update Succesfull.",
+      Failed: "Update Failed.",
     },
     SendKey: "发送键",
     Theme: "主题",
diff --git a/app/locales/en.ts b/app/locales/en.ts
index 120457522..a025a522f 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 Succesfull.",
+      Failed: "Update Failed.",
     },
     SendKey: "Send Key",
     Theme: "Theme",
diff --git a/app/store/update.ts b/app/store/update.ts
index e68fde369..327dc5e88 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 5d4501710..9e75ffc7f 100644
--- a/app/utils.ts
+++ b/app/utils.ts
@@ -386,3 +386,26 @@ 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);
+    });
+}