diff --git a/app/src/components/ReloadService.tsx b/app/src/components/ReloadService.tsx index 843d19b..0514f7d 100644 --- a/app/src/components/ReloadService.tsx +++ b/app/src/components/ReloadService.tsx @@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next"; import { useToast } from "./ui/use-toast.ts"; import { useEffect } from "react"; import { ToastAction } from "./ui/toast.tsx"; +import { getMemory, setMemory } from "@/utils/memory.ts"; function ReloadPrompt() { const { t } = useTranslation(); @@ -24,7 +25,7 @@ function ReloadPrompt() { }, }); - const before = localStorage.getItem("version") || ""; + const before = getMemory("version"); if (before.length > 0 && before !== version) { toast({ title: t("service.update-success"), @@ -34,7 +35,7 @@ function ReloadPrompt() { `[service] service worker updated (from ${before} to ${version})`, ); } - localStorage.setItem("version", version); + setMemory("version", version); useEffect(() => { if (offlineReady) { diff --git a/app/src/components/ThemeProvider.tsx b/app/src/components/ThemeProvider.tsx index 7662b40..f7cb501 100644 --- a/app/src/components/ThemeProvider.tsx +++ b/app/src/components/ThemeProvider.tsx @@ -2,6 +2,7 @@ import { createContext, useContext, useEffect, useState } from "react"; import { Moon, Sun } from "lucide-react"; import { Button } from "./ui/button"; +import { getMemory, setMemory } from "@/utils/memory.ts"; type Theme = "dark" | "light" | "system"; @@ -25,7 +26,7 @@ export function activeTheme(theme: Theme) { : "light"; root.classList.add(theme); - localStorage.setItem("theme", theme); + setMemory("theme", theme); } const initialState: ThemeProviderState = { @@ -34,7 +35,7 @@ const initialState: ThemeProviderState = { activeTheme(theme); }, toggleTheme: () => { - const theme = localStorage.getItem("theme") as Theme; + const theme = getMemory("theme") as Theme; activeTheme(theme === "dark" ? "light" : "dark"); }, }; @@ -46,7 +47,7 @@ export function ThemeProvider({ ...props }: ThemeProviderProps) { const [theme, setTheme] = useState( - () => (localStorage.getItem("theme") as Theme) || defaultTheme, + () => (getMemory("theme") as Theme) || defaultTheme, ); useEffect(() => { @@ -70,7 +71,7 @@ export function ThemeProvider({ const value = { theme, setTheme: (theme: Theme) => { - localStorage.setItem("theme", theme); + setMemory("theme", theme); setTheme(theme); }, }; diff --git a/app/src/components/app/NavBar.tsx b/app/src/components/app/NavBar.tsx index d611f95..7d91697 100644 --- a/app/src/components/app/NavBar.tsx +++ b/app/src/components/app/NavBar.tsx @@ -16,6 +16,7 @@ import ModeToggle from "@/components/ThemeProvider.tsx"; import I18nProvider from "@/components/I18nProvider.tsx"; import router from "@/router.tsx"; import MenuBar from "./MenuBar.tsx"; +import { getMemory } from "@/utils/memory.ts"; function NavMenu() { const username = useSelector(selectUsername); @@ -35,7 +36,7 @@ function NavBar() { const { t } = useTranslation(); const dispatch = useDispatch(); useEffect(() => { - validateToken(dispatch, localStorage.getItem(tokenField) ?? ""); + validateToken(dispatch, getMemory(tokenField)); }, []); const auth = useSelector(selectAuthenticated); diff --git a/app/src/components/home/ChatWrapper.tsx b/app/src/components/home/ChatWrapper.tsx index 00801b1..0a7c57a 100644 --- a/app/src/components/home/ChatWrapper.tsx +++ b/app/src/components/home/ChatWrapper.tsx @@ -40,10 +40,10 @@ import { DialogTitle, } from "@/components/ui/dialog.tsx"; import { version } from "@/conf.ts"; -import {clearHistoryState, getQueryParam} from "@/utils/path.ts"; -import {forgetMemory, popMemory, recordMemory} from "@/utils/memory.ts"; -import {useToast} from "@/components/ui/use-toast.ts"; -import {ToastAction} from "@/components/ui/toast.tsx"; +import { clearHistoryState, getQueryParam } from "@/utils/path.ts"; +import { forgetMemory, popMemory, setMemory } from "@/utils/memory.ts"; +import { useToast } from "@/components/ui/use-toast.ts"; +import { ToastAction } from "@/components/ui/toast.tsx"; function ChatSpace() { const [open, setOpen] = useState(false); @@ -165,12 +165,15 @@ function ChatWrapper() { title: t("chat.recall"), description: t("chat.recall-desc"), action: ( - { - setInput(""); - }}> + { + setInput(""); + }} + > {t("chat.recall-cancel")} - ) + ), }); } }, []); @@ -217,7 +220,7 @@ function ChatWrapper() { value={input} onChange={(e: React.ChangeEvent) => { setInput(e.target.value); - recordMemory("history", e.target.value); + setMemory("history", e.target.value); }} placeholder={t("chat.placeholder")} onKeyDown={async (e: React.KeyboardEvent) => { diff --git a/app/src/conf.ts b/app/src/conf.ts index f14808e..af97adb 100644 --- a/app/src/conf.ts +++ b/app/src/conf.ts @@ -1,8 +1,14 @@ import axios from "axios"; import { Model } from "./conversation/types.ts"; -import {getDev, getRestApi, getTokenField, getWebsocketApi} from "@/utils/env.ts"; +import { + getDev, + getRestApi, + getTokenField, + getWebsocketApi, +} from "@/utils/env.ts"; +import { getMemory } from "@/utils/memory.ts"; -export const version = "3.5.21"; +export const version = "3.6.0"; export const dev: boolean = getDev(); export const deploy: boolean = true; export let rest_api: string = getRestApi(deploy); @@ -30,9 +36,24 @@ export const supportModels: Model[] = [ { id: "bing-creative", name: "New Bing", free: true, auth: true }, // zhipu models - { id: "zhipu-chatglm-pro", name: "智谱 ChatGLM Pro", free: false, auth: true }, - { id: "zhipu-chatglm-std", name: "智谱 ChatGLM Std", free: false, auth: true }, - { id: "zhipu-chatglm-lite", name: "智谱 ChatGLM Lite", free: true, auth: true }, + { + id: "zhipu-chatglm-pro", + name: "智谱 ChatGLM Pro", + free: false, + auth: true, + }, + { + id: "zhipu-chatglm-std", + name: "智谱 ChatGLM Std", + free: false, + auth: true, + }, + { + id: "zhipu-chatglm-lite", + name: "智谱 ChatGLM Lite", + free: true, + auth: true, + }, ]; export function login() { @@ -41,3 +62,4 @@ export function login() { axios.defaults.baseURL = rest_api; axios.defaults.headers.post["Content-Type"] = "application/json"; +axios.defaults.headers.common["Authorization"] = getMemory(tokenField); diff --git a/app/src/conversation/connection.ts b/app/src/conversation/connection.ts index 5132bf6..0b177da 100644 --- a/app/src/conversation/connection.ts +++ b/app/src/conversation/connection.ts @@ -1,4 +1,5 @@ import { tokenField, ws_api } from "@/conf.ts"; +import { getMemory } from "@/utils/memory.ts"; export const endpoint = `${ws_api}/chat`; @@ -37,7 +38,7 @@ export class Connection { this.connection.onopen = () => { this.state = true; this.send({ - token: localStorage.getItem(tokenField) || "anonymous", + token: getMemory(tokenField) || "anonymous", id: this.id, }); }; diff --git a/app/src/conversation/generation.ts b/app/src/conversation/generation.ts index 5a93ab1..81e5e8f 100644 --- a/app/src/conversation/generation.ts +++ b/app/src/conversation/generation.ts @@ -1,4 +1,5 @@ -import { ws_api } from "@/conf.ts"; +import { tokenField, ws_api } from "@/conf.ts"; +import { getMemory } from "@/utils/memory.ts"; export const endpoint = `${ws_api}/generation/create`; @@ -93,7 +94,7 @@ export class GenerationManager { public generate(prompt: string, model: string) { this.setProcessing(true); - const token = localStorage.getItem("token") || "anonymous"; + const token = getMemory(tokenField) || "anonymous"; if (token) { this.connection = new WebSocket(endpoint); this.connection.onopen = () => { diff --git a/app/src/i18n.ts b/app/src/i18n.ts index e4f0aab..223489f 100644 --- a/app/src/i18n.ts +++ b/app/src/i18n.ts @@ -1,5 +1,6 @@ import i18n from "i18next"; import { initReactI18next } from "react-i18next"; +import { getMemory, setMemory } from "@/utils/memory.ts"; // the translations // (tip move them in a JSON file and import them, @@ -654,7 +655,7 @@ i18n export default i18n; export function getStorage(): string { - const storage = localStorage.getItem("language"); + const storage = getMemory("language"); if (storage && supportedLanguages.includes(storage)) { return storage; } @@ -673,7 +674,7 @@ export function setLanguage(i18n: any, lang: string): void { .then(() => console.debug(`[i18n] language changed (language: ${i18n.language})`), ); - localStorage.setItem("language", lang); + setMemory("language", lang); return; } console.warn(`[i18n] language ${lang} is not supported`); diff --git a/app/src/store/auth.ts b/app/src/store/auth.ts index c86b160..2791ae3 100644 --- a/app/src/store/auth.ts +++ b/app/src/store/auth.ts @@ -2,6 +2,7 @@ import { createSlice } from "@reduxjs/toolkit"; import axios from "axios"; import { tokenField } from "@/conf.ts"; import { AppDispatch } from "./index.ts"; +import { forgetMemory, setMemory } from "@/utils/memory.ts"; export const authSlice = createSlice({ name: "auth", @@ -16,7 +17,7 @@ export const authSlice = createSlice({ const token = (action.payload as string).trim(); state.token = token; axios.defaults.headers.common["Authorization"] = token; - if (token.length > 0) localStorage.setItem(tokenField, token); + if (token.length > 0) setMemory(tokenField, token); }, setAuthenticated: (state, action) => { state.authenticated = action.payload as boolean; @@ -32,7 +33,7 @@ export const authSlice = createSlice({ state.authenticated = false; state.username = ""; axios.defaults.headers.common["Authorization"] = ""; - localStorage.removeItem(tokenField); + forgetMemory(tokenField); location.reload(); }, diff --git a/app/src/store/chat.ts b/app/src/store/chat.ts index 1fb3a0a..2ad3ed5 100644 --- a/app/src/store/chat.ts +++ b/app/src/store/chat.ts @@ -4,6 +4,7 @@ import { Message } from "@/conversation/types.ts"; import { insertStart } from "@/utils/base.ts"; import { RootState } from "./index.ts"; import { supportModels } from "@/conf.ts"; +import { getMemory, setMemory } from "@/utils/memory.ts"; type initialStateType = { history: ConversationInstance[]; @@ -25,7 +26,7 @@ const chatSlice = createSlice({ initialState: { history: [], messages: [], - model: GetModel(localStorage.getItem("model")), + model: GetModel(getMemory("model")), web: false, current: -1, } as initialStateType, @@ -52,7 +53,7 @@ const chatSlice = createSlice({ state.messages = action.payload as Message[]; }, setModel: (state, action) => { - localStorage.setItem("model", action.payload as string); + setMemory("model", action.payload as string); state.model = action.payload as string; }, setWeb: (state, action) => { diff --git a/app/src/utils/memory.ts b/app/src/utils/memory.ts index cf16626..a12cca3 100644 --- a/app/src/utils/memory.ts +++ b/app/src/utils/memory.ts @@ -1,9 +1,9 @@ -export function recordMemory(key: string, value: string) { +export function setMemory(key: string, value: string) { const data = value.trim(); localStorage.setItem(key, data); } -export function recallMemory(key: string): string { +export function getMemory(key: string): string { return (localStorage.getItem(key) || "").trim(); } @@ -16,7 +16,7 @@ export function clearMemory() { } export function popMemory(key: string): string { - const value = recallMemory(key); + const value = getMemory(key); forgetMemory(key); return value; }