Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/components/settings/sections/about-section.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useEffect, useState } from "react"
import { useTranslation } from "react-i18next"
import { clipServerStatus } from "@/commands/fs"

export function AboutSection() {
const { t } = useTranslation()
const [clipStatus, setClipStatus] = useState<string>("...")

useEffect(() => {
Expand All @@ -19,16 +21,16 @@ export function AboutSection() {
}, [])

const rows: Array<{ label: string; value: string; mono?: boolean }> = [
{ label: "版本", value: `v${__APP_VERSION__}`, mono: true },
{ label: "Clip Server", value: `${clipStatus} @ 127.0.0.1:19827`, mono: true },
{ label: t("settings.aboutVersion"), value: `v${__APP_VERSION__}`, mono: true },
{ label: t("settings.aboutClipServer"), value: `${clipStatus} @ 127.0.0.1:19827`, mono: true },
]

return (
<div className="space-y-6">
<div>
<h2 className="text-xl font-semibold">关于</h2>
<h2 className="text-xl font-semibold">{t("settings.aboutHeading")}</h2>
<p className="mt-1 text-sm text-muted-foreground">
构建信息和运行时状态。
{t("settings.aboutDescription")}
</p>
</div>

Expand Down
14 changes: 8 additions & 6 deletions src/components/settings/sections/embedding-section.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import type { SettingsDraft, DraftSetter } from "../settings-types"
Expand All @@ -8,21 +9,22 @@ interface Props {
}

export function EmbeddingSection({ draft, setDraft }: Props) {
const { t } = useTranslation()

return (
<div className="space-y-6">
<div>
<h2 className="text-xl font-semibold">向量嵌入</h2>
<h2 className="text-xl font-semibold">{t("settings.embeddingHeading")}</h2>
<p className="mt-1 text-sm text-muted-foreground">
启用语义搜索。对任何 OpenAI 兼容的 /v1/embeddings endpoint 工作。
本地模型(如 LM Studio、Ollama embedding)不需要 API Key。
{t("settings.embeddingDescription")}
</p>
</div>

<div className="flex items-center justify-between rounded-md border p-3">
<div>
<div className="text-sm font-medium">启用向量搜索</div>
<div className="text-sm font-medium">{t("settings.embeddingEnable")}</div>
<div className="text-xs text-muted-foreground">
关掉后搜索只走 token 匹配。
{t("settings.embeddingEnableHint")}
</div>
</div>
<button
Expand Down Expand Up @@ -57,7 +59,7 @@ export function EmbeddingSection({ draft, setDraft }: Props) {
type="password"
value={draft.embeddingApiKey}
onChange={(e) => setDraft("embeddingApiKey", e.target.value)}
placeholder="本地模型留空即可"
placeholder={t("settings.embeddingApiKeyPlaceholder")}
/>
</div>

Expand Down
11 changes: 7 additions & 4 deletions src/components/settings/sections/interface-section.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next"
import { Label } from "@/components/ui/label"
import type { SettingsDraft, DraftSetter } from "../settings-types"

Expand All @@ -12,17 +13,19 @@ const UI_LANGUAGES = [
]

export function InterfaceSection({ draft, setDraft }: Props) {
const { t } = useTranslation()

return (
<div className="space-y-6">
<div>
<h2 className="text-xl font-semibold">界面</h2>
<h2 className="text-xl font-semibold">{t("settings.interfaceHeading")}</h2>
<p className="mt-1 text-sm text-muted-foreground">
应用 UI 的显示语言。切换后立即生效并持久化。
{t("settings.interfaceDescription")}
</p>
</div>

<div className="space-y-2">
<Label>UI 语言</Label>
<Label>{t("settings.uiLanguage")}</Label>
<div className="flex flex-wrap gap-2">
{UI_LANGUAGES.map((l) => {
const active = draft.uiLanguage === l.value
Expand All @@ -43,7 +46,7 @@ export function InterfaceSection({ draft, setDraft }: Props) {
})}
</div>
<p className="text-xs text-muted-foreground">
只影响按钮、标签这些 UI 文案,不影响 AI 输出语言(那个在"输出偏好"里单独设置)。
{t("settings.uiLanguageHint")}
</p>
</div>
</div>
Expand Down
21 changes: 13 additions & 8 deletions src/components/settings/sections/output-section.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next"
import { Label } from "@/components/ui/label"
import type { SettingsDraft, DraftSetter } from "../settings-types"

Expand Down Expand Up @@ -33,20 +34,21 @@ const LANGUAGE_OPTIONS = [
const HISTORY_OPTIONS = [2, 4, 6, 8, 10, 20]

export function OutputSection({ draft, setDraft }: Props) {
const { t } = useTranslation()

return (
<div className="space-y-6">
<div>
<h2 className="text-xl font-semibold">输出偏好</h2>
<h2 className="text-xl font-semibold">{t("settings.outputHeading")}</h2>
<p className="mt-1 text-sm text-muted-foreground">
控制 AI 生成内容的语言和对话上下文长度。
{t("settings.outputDescription")}
</p>
</div>

<div className="space-y-2">
<Label>AI 输出语言</Label>
<Label>{t("settings.outputLanguageLabel")}</Label>
<p className="text-xs text-muted-foreground">
强制 AI 生成内容(chat 回复、wiki 页面、research 结果、lint 报告)使用指定语言。
选 "Auto" 让 AI 跟随用户输入或源文档的语言。
{t("settings.outputLanguageHint")}
</p>
<select
value={draft.outputLanguage}
Expand All @@ -62,9 +64,9 @@ export function OutputSection({ draft, setDraft }: Props) {
</div>

<div className="space-y-2">
<Label>对话历史长度</Label>
<Label>{t("settings.historyLength")}</Label>
<p className="text-xs text-muted-foreground">
每次请求发给 AI 的历史消息条数。多 = 上下文更完整但更费 token。
{t("settings.historyLengthHint")}
</p>
<div className="flex flex-wrap gap-2">
{HISTORY_OPTIONS.map((n) => {
Expand All @@ -86,7 +88,10 @@ export function OutputSection({ draft, setDraft }: Props) {
})}
</div>
<p className="text-xs text-muted-foreground">
当前 {draft.maxHistoryMessages} 条消息(约 {draft.maxHistoryMessages / 2} 轮对话)
{t("settings.historyLengthCurrent", {
count: draft.maxHistoryMessages,
turns: Math.floor(draft.maxHistoryMessages / 2),
})}
</p>
</div>
</div>
Expand Down
22 changes: 21 additions & 1 deletion src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,27 @@
"save": "Save Settings",
"saved": "Saved!",
"language": "Language",
"languageHint": "Interface language (wiki content follows source material language)"
"languageHint": "Interface language (wiki content follows source material language)",
"interfaceHeading": "Interface",
"interfaceDescription": "Display language for the application UI. Changes take effect immediately and are persisted.",
"uiLanguage": "UI Language",
"uiLanguageHint": "Affects only UI labels and buttons, not AI output language (configure that under Output Preferences).",
"outputHeading": "Output Preferences",
"outputDescription": "Control the language and context length for AI-generated content.",
"outputLanguageLabel": "AI Output Language",
"outputLanguageHint": "Force AI-generated content (chat replies, wiki pages, research results, lint reports) to use the specified language. Choose \"Auto\" to follow the user's input or source document language.",
"historyLength": "Conversation History Length",
"historyLengthHint": "Number of past messages sent to the AI per request. More = richer context but higher token cost.",
"historyLengthCurrent": "Currently {{count}} messages (~{{turns}} turns)",
"embeddingHeading": "Vector Embeddings",
"embeddingDescription": "Enables semantic search. Works with any OpenAI-compatible /v1/embeddings endpoint. No API key needed for local models (e.g. LM Studio, Ollama).",
"embeddingEnable": "Enable Vector Search",
"embeddingEnableHint": "When off, search uses token matching only.",
"embeddingApiKeyPlaceholder": "Leave blank for local models",
"aboutHeading": "About",
"aboutDescription": "Build information and runtime status.",
"aboutVersion": "Version",
"aboutClipServer": "Clip Server"
},
"preview": {
"selectFile": "Select a file to preview",
Expand Down
22 changes: 21 additions & 1 deletion src/i18n/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,27 @@
"save": "保存设置",
"saved": "已保存!",
"language": "语言",
"languageHint": "界面语言(Wiki 内容语言以原始资料为准)"
"languageHint": "界面语言(Wiki 内容语言以原始资料为准)",
"interfaceHeading": "界面",
"interfaceDescription": "应用 UI 的显示语言。切换后立即生效并持久化。",
"uiLanguage": "UI 语言",
"uiLanguageHint": "只影响按钮、标签这些 UI 文案,不影响 AI 输出语言(那个在"输出偏好"里单独设置)。",
"outputHeading": "输出偏好",
"outputDescription": "控制 AI 生成内容的语言和对话上下文长度。",
"outputLanguageLabel": "AI 输出语言",
"outputLanguageHint": "强制 AI 生成内容(chat 回复、wiki 页面、research 结果、lint 报告)使用指定语言。选 \"Auto\" 让 AI 跟随用户输入或源文档的语言。",
"historyLength": "对话历史长度",
"historyLengthHint": "每次请求发给 AI 的历史消息条数。多 = 上下文更完整但更费 token。",
"historyLengthCurrent": "当前 {{count}} 条消息(约 {{turns}} 轮对话)",
"embeddingHeading": "向量嵌入",
"embeddingDescription": "启用语义搜索。对任何 OpenAI 兼容的 /v1/embeddings endpoint 工作。本地模型(如 LM Studio、Ollama embedding)不需要 API Key。",
"embeddingEnable": "启用向量搜索",
"embeddingEnableHint": "关掉后搜索只走 token 匹配。",
"embeddingApiKeyPlaceholder": "本地模型留空即可",
"aboutHeading": "关于",
"aboutDescription": "构建信息和运行时状态。",
"aboutVersion": "版本",
"aboutClipServer": "Clip Server"
},
"preview": {
"selectFile": "选择文件以预览",
Expand Down