From 223ae743edc04c254f62bc9b8d0d5fae45dc908d Mon Sep 17 00:00:00 2001 From: an-lee Date: Sat, 20 Jul 2024 17:18:33 +0800 Subject: [PATCH] Feat may set api url (#850) * add api url settings * may edit api setting before login --- enjoy/src/i18n/en.json | 3 + enjoy/src/i18n/zh-CN.json | 3 + enjoy/src/main/settings.ts | 8 + enjoy/src/main/window.ts | 6 +- enjoy/src/preload.ts | 6 + .../renderer/components/misc/login-form.tsx | 148 +++++++++++------- .../preferences/api-url-settings.tsx | 112 +++++++++++++ .../renderer/components/preferences/index.ts | 1 + .../components/preferences/preferences.tsx | 3 + .../context/app-settings-provider.tsx | 8 + enjoy/src/types/enjoy-app.d.ts | 2 + 11 files changed, 242 insertions(+), 58 deletions(-) create mode 100644 enjoy/src/renderer/components/preferences/api-url-settings.tsx diff --git a/enjoy/src/i18n/en.json b/enjoy/src/i18n/en.json index c5968fe1..3a2af169 100644 --- a/enjoy/src/i18n/en.json +++ b/enjoy/src/i18n/en.json @@ -258,6 +258,8 @@ "resetSettingsConfirmation": "It will reset all of your settings, are you sure? The library will not be affected.", "proxySettings": "Proxy Settings", "proxyConfigUpdated": "Proxy config updated", + "apiSettings": "API Settings", + "apiUrlUpdated": "API url updated", "logoutAndRemoveAllPersonalData": "Logout and remove all personal data", "logoutAndRemoveAllPersonalSettings": "Logout and remove all personal settings", "hotkeys": "Hotkeys", @@ -380,6 +382,7 @@ "whisperModelIsWorkingGood": "Whisper model is working good", "whisperModelIsNotWorking": "Whisper model is not working", "relaunchIsNeededAfterChanged": "Relaunch is needed after changed", + "reloadIsNeededAfterChanged": "Reload is needed after changed", "defaultAiEngine": "Default AI engine", "aiEngine": "AI engine", "defaultAiModel": "Default AI model", diff --git a/enjoy/src/i18n/zh-CN.json b/enjoy/src/i18n/zh-CN.json index ece05b2f..a8220b4f 100644 --- a/enjoy/src/i18n/zh-CN.json +++ b/enjoy/src/i18n/zh-CN.json @@ -258,6 +258,8 @@ "resetSettingsConfirmation": "您确定要重置个人设置选项吗?资料库不会受影响。", "proxySettings": "代理设置", "proxyConfigUpdated": "代理配置已更新", + "apiSettings": "API 设置", + "apiUrlUpdated": "API 网址已更新", "logoutAndRemoveAllPersonalData": "退出登录并删除所有个人数据", "logoutAndRemoveAllPersonalSettings": "退出登录并删除所有个人设置选项", "hotkeys": "快捷键", @@ -380,6 +382,7 @@ "whisperModelIsWorkingGood": "Whisper 模型正常工作", "whisperModelIsNotWorking": "Whisper 模型无法正常工作,请尝试更换模型后重试,或联系开发者", "relaunchIsNeededAfterChanged": "更改后需要重新启动", + "reloadIsNeededAfterChanged": "更改后需要重新加载", "defaultAiEngine": "默认 AI 引擎", "aiEngine": "AI 引擎", "defaultAiModel": "默认 AI 模型", diff --git a/enjoy/src/main/settings.ts b/enjoy/src/main/settings.ts index 5bf92848..ec507b72 100644 --- a/enjoy/src/main/settings.ts +++ b/enjoy/src/main/settings.ts @@ -176,6 +176,14 @@ export default { ipcMain.handle("settings-set-default-hotkeys", (_event, records) => { return settings.setSync("defaultHotkeys", records); }); + + ipcMain.handle("settings-get-api-url", (_event, url) => { + return settings.getSync("apiUrl"); + }); + + ipcMain.handle("settings-set-api-url", (_event, url) => { + return settings.setSync("apiUrl", url); + }); }, cachePath, libraryPath, diff --git a/enjoy/src/main/window.ts b/enjoy/src/main/window.ts index 785d30f0..3abd811f 100644 --- a/enjoy/src/main/window.ts +++ b/enjoy/src/main/window.ts @@ -315,11 +315,13 @@ main.init = () => { }); ipcMain.handle("app-api-url", () => { - return process.env.WEB_API_URL || WEB_API_URL; + const apiUrl = settings.getSync("apiUrl"); + return process.env.WEB_API_URL || apiUrl || WEB_API_URL; }); ipcMain.handle("app-ws-url", () => { - return process.env.WS_URL || WS_URL; + const wsUrl = settings.getSync("wsUrl"); + return process.env.WS_URL || wsUrl || WS_URL; }); ipcMain.handle("app-quit", () => { diff --git a/enjoy/src/preload.ts b/enjoy/src/preload.ts index 0cb10864..d9b6900a 100644 --- a/enjoy/src/preload.ts +++ b/enjoy/src/preload.ts @@ -218,6 +218,12 @@ contextBridge.exposeInMainWorld("__ENJOY_APP__", { setDefaultHotkeys: (records: Record) => { return ipcRenderer.invoke("settings-set-default-hotkeys", records); }, + getApiUrl: () => { + return ipcRenderer.invoke("settings-get-api-url"); + }, + setApiUrl: (url: string) => { + return ipcRenderer.invoke("settings-set-api-url", url); + }, }, path: { join: (...paths: string[]) => { diff --git a/enjoy/src/renderer/components/misc/login-form.tsx b/enjoy/src/renderer/components/misc/login-form.tsx index 0c3842d6..95340385 100644 --- a/enjoy/src/renderer/components/misc/login-form.tsx +++ b/enjoy/src/renderer/components/misc/login-form.tsx @@ -9,6 +9,10 @@ import { AvatarFallback, Button, toast, + Tabs, + TabsList, + TabsTrigger, + TabsContent, } from "@renderer/components/ui"; import { useContext, useEffect, useState } from "react"; import { AppSettingsProviderContext } from "@renderer/context"; @@ -19,6 +23,8 @@ import { GithubLoginButton, BanduLoginButton, MixinLoginButton, + ProxySettings, + ApiUrlSettings, } from "@renderer/components"; import { EmailLoginForm } from "./email-login-form"; import { Client } from "@/api"; @@ -68,71 +74,101 @@ export const LoginForm = () => { if (rememberedUser) { return ( -
-
-
-
- - - - {rememberedUser.name[0].toUpperCase()} - - + + + {t("login")} + {t("advanced")} + + +
+
-
- {rememberedUser.name} -
-
- {rememberedUser.id} +
+ + + + {rememberedUser.name[0].toUpperCase()} + + +
+
+ {rememberedUser.name} +
+
+ {rememberedUser.id} +
+
+
+ + +
-
- - -
-
-
+ + + + + + + + + + + ); } return ( - - - {t("login")} - + + + {t("login")} + {t("advanced")} + + + + + - - - -
- -
- {t("youCanAlsoLoginWith")} -
-
- - - -
-
-
-
+
+ +
+ {t("youCanAlsoLoginWith")} +
+
+ + + +
+
+ +
+ + + + + + + + + + + ); }; diff --git a/enjoy/src/renderer/components/preferences/api-url-settings.tsx b/enjoy/src/renderer/components/preferences/api-url-settings.tsx new file mode 100644 index 00000000..d3c2e205 --- /dev/null +++ b/enjoy/src/renderer/components/preferences/api-url-settings.tsx @@ -0,0 +1,112 @@ +import * as z from "zod"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { t } from "i18next"; +import { + Button, + Form, + FormField, + FormItem, + FormControl, + Input, + toast, +} from "@renderer/components/ui"; +import { AppSettingsProviderContext } from "@renderer/context"; +import { useContext, useState, useEffect } from "react"; +import { InfoIcon } from "lucide-react"; + +export const ApiUrlSettings = () => { + const { apiUrl, setApiUrl } = useContext(AppSettingsProviderContext); + const [editing, setEditing] = useState(false); + + const apiConfigSchema = z.object({ + url: z.string().url(), + }); + const form = useForm({ + mode: "onBlur", + resolver: zodResolver(apiConfigSchema), + values: { + url: apiUrl, + }, + }); + + const onSubmit = async (data: z.infer) => { + setApiUrl(data.url).then(() => { + toast.success(t("apiUrlUpdated")); + setEditing(false); + }); + }; + + useEffect(() => {}, [apiUrl]); + + return ( +
+ +
+
+
{t("apiSettings")}
+
+ ( + + + + + + )} + /> +
+
+ +
+
+ {editing ? ( + <> + + + + ) : ( + + )} +
+
+ + {t("reloadIsNeededAfterChanged")} +
+
+
+
+ + ); +}; diff --git a/enjoy/src/renderer/components/preferences/index.ts b/enjoy/src/renderer/components/preferences/index.ts index 03195ff3..6b2edeb9 100644 --- a/enjoy/src/renderer/components/preferences/index.ts +++ b/enjoy/src/renderer/components/preferences/index.ts @@ -1,5 +1,6 @@ export * from "./preferences"; export * from "./about"; +export * from "./api-url-settings"; export * from "./appearance"; export * from "./hotkeys"; diff --git a/enjoy/src/renderer/components/preferences/preferences.tsx b/enjoy/src/renderer/components/preferences/preferences.tsx index 9bebe700..b323fd8c 100644 --- a/enjoy/src/renderer/components/preferences/preferences.tsx +++ b/enjoy/src/renderer/components/preferences/preferences.tsx @@ -2,6 +2,7 @@ import { t } from "i18next"; import { Button, ScrollArea, Separator } from "@renderer/components/ui"; import { About, + ApiUrlSettings, Appearance, DefaultEngineSettings, Hotkeys, @@ -54,6 +55,8 @@ export const Preferences = () => {
{t("advancedSettings")}
+ + diff --git a/enjoy/src/renderer/context/app-settings-provider.tsx b/enjoy/src/renderer/context/app-settings-provider.tsx index f89c8260..3b5e599b 100644 --- a/enjoy/src/renderer/context/app-settings-provider.tsx +++ b/enjoy/src/renderer/context/app-settings-provider.tsx @@ -10,6 +10,7 @@ import { SENTRY_DSN } from "@/constants"; type AppSettingsProviderState = { webApi: Client; apiUrl?: string; + setApiUrl?: (url: string) => Promise; user: UserType | null; initialized: boolean; version?: string; @@ -164,6 +165,12 @@ export const AppSettingsProvider = ({ }); }; + const setApiUrlHandler = async (url: string) => { + EnjoyApp.settings.setApiUrl(url).then(() => { + EnjoyApp.app.reload(); + }); + }; + const createCable = async (token: string) => { const wsUrl = await EnjoyApp.app.wsUrl(); const consumer = createConsumer(wsUrl + "/cable?token=" + token); @@ -220,6 +227,7 @@ export const AppSettingsProvider = ({ version, webApi, apiUrl, + setApiUrl: setApiUrlHandler, user, login, logout, diff --git a/enjoy/src/types/enjoy-app.d.ts b/enjoy/src/types/enjoy-app.d.ts index 0666e6c7..8d4467ad 100644 --- a/enjoy/src/types/enjoy-app.d.ts +++ b/enjoy/src/types/enjoy-app.d.ts @@ -128,6 +128,8 @@ type EnjoyAppType = { switchLanguage: (language: string) => Promise; getDefaultHotkeys: () => Promise | undefined>; setDefaultHotkeys: (records: Record) => Promise; + getApiUrl: () => Promise; + setApiUrl: (url: string) => Promise; }; fs: { ensureDir: (path: string) => Promise;