diff --git a/app/command.ts b/app/command.ts
index e515e5f0bb4..fc349bfe201 100644
--- a/app/command.ts
+++ b/app/command.ts
@@ -1,6 +1,9 @@
import { useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import Locale from "./locales";
+import { getClientConfig } from "@/app/config/client";
+
+const isApp = !!getClientConfig()?.isApp;
type Command = (param: string) => void;
interface Commands {
@@ -37,6 +40,7 @@ interface ChatCommands {
newm?: Command;
next?: Command;
prev?: Command;
+ restart?: Command;
clear?: Command;
del?: Command;
}
@@ -44,6 +48,12 @@ interface ChatCommands {
export const ChatCommandPrefix = ":";
export function useChatCommand(commands: ChatCommands = {}) {
+ const chatCommands = { ...commands };
+
+ if (!isApp) {
+ delete chatCommands.restart;
+ }
+
function extract(userInput: string) {
return (
userInput.startsWith(ChatCommandPrefix) ? userInput.slice(1) : userInput
@@ -53,7 +63,7 @@ export function useChatCommand(commands: ChatCommands = {}) {
function search(userInput: string) {
const input = extract(userInput);
const desc = Locale.Chat.Commands;
- return Object.keys(commands)
+ return Object.keys(chatCommands)
.filter((c) => c.startsWith(input))
.map((c) => ({
title: desc[c as keyof ChatCommands],
@@ -63,11 +73,11 @@ export function useChatCommand(commands: ChatCommands = {}) {
function match(userInput: string) {
const command = extract(userInput);
- const matched = typeof commands[command] === "function";
+ const matched = typeof chatCommands[command] === "function";
return {
matched,
- invoke: () => matched && commands[command]!(userInput),
+ invoke: () => matched && chatCommands[command]!(userInput),
};
}
diff --git a/app/components/chat.tsx b/app/components/chat.tsx
index cca096eb874..f89a888270d 100644
--- a/app/components/chat.tsx
+++ b/app/components/chat.tsx
@@ -657,6 +657,7 @@ function _Chat() {
newm: () => navigate(Path.NewChat),
prev: () => chatStore.nextSession(-1),
next: () => chatStore.nextSession(1),
+ restart: () => window.__TAURI__?.process.relaunch(),
clear: () =>
chatStore.updateCurrentSession(
(session) => (session.clearContextIndex = session.messages.length),
diff --git a/app/components/settings.tsx b/app/components/settings.tsx
index 8ed6b77383c..43bc4db7a40 100644
--- a/app/components/settings.tsx
+++ b/app/components/settings.tsx
@@ -565,6 +565,14 @@ export function Settings() {
setCheckingUpdate(true);
updateStore.getLatestVersion(force).then(() => {
setCheckingUpdate(false);
+ window.__TAURI__?.updater.checkUpdate().then((updateResult) => {
+ if (updateResult.status === "DONE") {
+ window.__TAURI__?.updater.installUpdate();
+ }
+ }).catch((e) => {
+ console.error("[Check Update Error]", e);
+ showToast(Locale.Settings.Update.Failed);
+ });
});
console.log("[Update] local version ", updateStore.version);
@@ -683,9 +691,19 @@ export function Settings() {
{checkingUpdate ? (
) : hasNewVersion ? (
-
- {Locale.Settings.Update.GoToUpdate}
-
+ <>
+ {clientConfig?.isApp ? (
+ }
+ text={Locale.Settings.Update.GoToUpdate}
+ onClick={() => checkUpdate(true)}
+ />
+ ) : (
+
+ {Locale.Settings.Update.GoToUpdate}
+
+ )}
+ >
) : (
}
diff --git a/app/global.d.ts b/app/global.d.ts
index e0a2c3f0686..29dc0faf431 100644
--- a/app/global.d.ts
+++ b/app/global.d.ts
@@ -16,14 +16,31 @@ declare interface Window {
invoke(command: string, payload?: Record): Promise;
dialog: {
save(options?: Record): Promise;
+ open(options?: OpenDialogOptions): Promise;
+ // support locale language
+ message(message: string, options?: string | MessageDialogOptions): Promise;
+ ask(message: string, options?: string | ConfirmDialogOptions): Promise;
};
fs: {
writeBinaryFile(path: string, data: Uint8Array): Promise;
};
+ process: {
+ relaunch(): Promise;
+ };
notification:{
requestPermission(): Promise;
isPermissionGranted(): Promise;
sendNotification(options: string | Options): void;
};
+ updater: {
+ checkUpdate(): Promise;
+ installUpdate(): Promise;
+ onUpdaterEvent(handler: (status: UpdateStatusResult) => void): Promise;
+ };
+ // can do route in client app like CORS fetch, currently is not enabled yet only module added.
+ http: {
+ fetch(url: string, options?: FetchOptions): Promise>;
+ getClient(options?: ClientOptions): Promise;
+ };
};
}
diff --git a/app/locales/cn.ts b/app/locales/cn.ts
index 4cd963fb8e2..84b5f6e77c9 100644
--- a/app/locales/cn.ts
+++ b/app/locales/cn.ts
@@ -48,6 +48,7 @@ const cn = {
newm: "从面具新建聊天",
next: "下一个聊天",
prev: "上一个聊天",
+ restart: "重新启动客户端",
clear: "清除上下文",
del: "删除聊天",
},
@@ -167,6 +168,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 928c4b72d4e..17992ffa720 100644
--- a/app/locales/en.ts
+++ b/app/locales/en.ts
@@ -50,6 +50,7 @@ const en: LocaleType = {
newm: "Start a new chat with mask",
next: "Next Chat",
prev: "Previous Chat",
+ restart: "Restart a client",
clear: "Clear Context",
del: "Delete Chat",
},
@@ -169,6 +170,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/locales/id.ts b/app/locales/id.ts
index b5e4a70b751..9af946f8cdf 100644
--- a/app/locales/id.ts
+++ b/app/locales/id.ts
@@ -37,6 +37,7 @@ const id: PartialLocaleType = {
newm: "Mulai Chat Baru dengan Masks",
next: "Chat Selanjutnya",
prev: "Chat Sebelumnya",
+ restart: "Restart klien",
clear: "Bersihkan Percakapan",
del: "Hapus Chat",
},
@@ -156,6 +157,8 @@ const id: PartialLocaleType = {
IsChecking: "Memeriksa pembaruan...",
FoundUpdate: (x: string) => `Versi terbaru ditemukan: ${x}`,
GoToUpdate: "Perbarui Sekarang",
+ Success: "Pembaruan Berhasil.",
+ Failed: "Pembaruan Gagal.",
},
AutoGenerateTitle: {
Title: "Hasilkan Judul Otomatis",
diff --git a/app/store/update.ts b/app/store/update.ts
index 2b088a13d7a..fb5805a6c1e 100644
--- a/app/store/update.ts
+++ b/app/store/update.ts
@@ -4,6 +4,7 @@ import { getClientConfig } from "../config/client";
import { createPersistStore } from "../utils/store";
import ChatGptIcon from "../icons/chatgpt.png";
import Locale from "../locales";
+import { showToast } from "../components/ui-lib";
const ONE_MINUTE = 60 * 1000;
const isApp = !!getClientConfig()?.isApp;
@@ -109,6 +110,15 @@ export const useUpdateStore = createPersistStore(
icon: `${ChatGptIcon.src}`,
sound: "Default"
});
+ // this a wild for updating client app
+ window.__TAURI__?.updater.checkUpdate().then((updateResult) => {
+ if (updateResult.status === "DONE") {
+ window.__TAURI__?.updater.installUpdate();
+ }
+ }).catch((e) => {
+ console.error("[Check Update Error]", e);
+ showToast(Locale.Settings.Update.Failed);
+ });
}
}
});
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 68f9c07c037..3e90120d420 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -93,7 +93,7 @@
"endpoints": [
"https://github.com/Yidadaa/ChatGPT-Next-Web/releases/latest/download/latest.json"
],
- "dialog": false,
+ "dialog": true,
"windows": {
"installMode": "passive"
},