diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index 9dc92e9ae..fd4eb59ce 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -13,6 +13,7 @@ import { fetchEventSource, } from "@fortaine/fetch-event-source"; import { prettyObject } from "@/app/utils/format"; +import { getClientConfig } from "@/app/config/client"; export interface OpenAIListModelResponse { object: string; @@ -28,13 +29,16 @@ export class ChatGPTApi implements LLMApi { path(path: string): string { let openaiUrl = useAccessStore.getState().openaiUrl; + const apiPath = "/api/openai"; + if (openaiUrl.length === 0) { - openaiUrl = DEFAULT_API_HOST; + const isApp = !!getClientConfig()?.isApp; + openaiUrl = isApp ? DEFAULT_API_HOST : apiPath; } if (openaiUrl.endsWith("/")) { openaiUrl = openaiUrl.slice(0, openaiUrl.length - 1); } - if (!openaiUrl.startsWith("http") && !openaiUrl.startsWith("/api/openai")) { + if (!openaiUrl.startsWith("http") && !openaiUrl.startsWith(apiPath)) { openaiUrl = "https://" + openaiUrl; } return [openaiUrl, path].join("/"); diff --git a/app/components/chat.tsx b/app/components/chat.tsx index a99f72f15..f661d0a47 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -940,7 +940,7 @@ function _Chat() { const prevPageMsgIndex = msgRenderIndex - CHAT_PAGE_SIZE; const nextPageMsgIndex = msgRenderIndex + CHAT_PAGE_SIZE; - if (isTouchTopEdge) { + if (isTouchTopEdge && !isTouchBottomEdge) { setMsgRenderIndex(prevPageMsgIndex); } else if (isTouchBottomEdge) { setMsgRenderIndex(nextPageMsgIndex); diff --git a/app/components/home.tsx b/app/components/home.tsx index c6829c2dc..745298d56 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -15,7 +15,7 @@ import dynamic from "next/dynamic"; import { Path, SlotID } from "../constant"; import { ErrorBoundary } from "./error"; -import { getLang } from "../locales"; +import { getISOLang, getLang } from "../locales"; import { HashRouter as Router, @@ -86,6 +86,17 @@ export function useSwitchTheme() { }, [config.theme]); } +function useHtmlLang() { + useEffect(() => { + const lang = getISOLang(); + const htmlLang = document.documentElement.lang; + + if (lang !== htmlLang) { + document.documentElement.lang = lang; + } + }, []); +} + const useHasHydrated = () => { const [hasHydrated, setHasHydrated] = useState(false); @@ -168,6 +179,7 @@ export function useLoadData() { export function Home() { useSwitchTheme(); useLoadData(); + useHtmlLang(); useEffect(() => { console.log("[Config] got config from build time", getClientConfig()); diff --git a/app/components/markdown.tsx b/app/components/markdown.tsx index 0c6a2d437..4a84969c5 100644 --- a/app/components/markdown.tsx +++ b/app/components/markdown.tsx @@ -38,12 +38,6 @@ export function Mermaid(props: { code: string }) { if (!svg) return; const text = new XMLSerializer().serializeToString(svg); const blob = new Blob([text], { type: "image/svg+xml" }); - console.log(blob); - // const url = URL.createObjectURL(blob); - // const win = window.open(url); - // if (win) { - // win.onload = () => URL.revokeObjectURL(url); - // } showImageModal(URL.createObjectURL(blob)); } @@ -152,11 +146,11 @@ export function Markdown( className="markdown-body" style={{ fontSize: `${props.fontSize ?? 14}px`, - direction: /[\u0600-\u06FF]/.test(props.content) ? "rtl" : "ltr", }} ref={mdRef} onContextMenu={props.onContextMenu} onDoubleClickCapture={props.onDoubleClickCapture} + dir="auto" > {props.loading ? ( diff --git a/app/components/settings.tsx b/app/components/settings.tsx index c438f68c5..1e6ef7139 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -529,6 +529,22 @@ export function Settings() { > + + + updateConfig( + (config) => + (config.enableAutoGenerateTitle = e.currentTarget.checked), + ) + } + > + + = { + cn: "zh-Hans", + tw: "zh-Hant", + }; + + const lang = getLang(); + return isoLangString[lang] ?? lang; +} diff --git a/app/store/chat.ts b/app/store/chat.ts index a61765899..bcdd99569 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -479,6 +479,7 @@ export const useChatStore = create()( }, summarizeSession() { + const config = useAppConfig.getState(); const session = get().currentSession(); // remove error messages if any @@ -487,6 +488,7 @@ export const useChatStore = create()( // should summarize topic after chating more than 50 words const SUMMARIZE_MIN_LEN = 50; if ( + config.enableAutoGenerateTitle && session.topic === DEFAULT_TOPIC && countMessages(messages) >= SUMMARIZE_MIN_LEN ) { diff --git a/app/store/config.ts b/app/store/config.ts index d963d39dd..7070ea05e 100644 --- a/app/store/config.ts +++ b/app/store/config.ts @@ -27,6 +27,7 @@ export const DEFAULT_CONFIG = { theme: Theme.Auto as Theme, tightBorder: !!getClientConfig()?.isApp, sendPreviewBubble: true, + enableAutoGenerateTitle: true, sidebarWidth: 300, disablePromptHint: false, @@ -147,7 +148,7 @@ export const useAppConfig = create()( }), { name: StoreKey.Config, - version: 3.6, + version: 3.7, migrate(persistedState, version) { const state = persistedState as ChatConfig; @@ -170,6 +171,10 @@ export const useAppConfig = create()( state.modelConfig.enableInjectSystemPrompts = true; } + if (version < 3.7) { + state.enableAutoGenerateTitle = true; + } + return state as any; }, },