feat(web): merge SettingsModal and ModelSettingsModal with tab navigation

Signed-off-by: baizhi958216 <1475289190@qq.com>
This commit is contained in:
baizhi958216
2026-06-11 11:33:44 +08:00
parent 94973bc6c6
commit 0f8e641c4c
5 changed files with 582 additions and 597 deletions
+8 -22
View File
@@ -12,7 +12,6 @@ import {
} from "@/lib/options";
import { readStoredTtsConfig } from "@/lib/clientTtsConfig";
import { SettingsModal, readStoredPlayerName, readStoredVisionClick } from "@/components/SettingsModal";
import { ModelSettingsModal } from "@/components/ModelSettingsModal";
import { analyzeImageDataUrl } from "@infiplot/ai-client";
import { readStoredModelConfig, resolveEngineConfig } from "@/lib/clientModelConfig";
import { STYLE_EXTRACTION_PROMPT } from "@/lib/styleExtraction";
@@ -1264,9 +1263,9 @@ export default function HomePage() {
// 顶部使用提示:默认展示,用户可点 × 永久关闭(localStorage:infiplot:hintClosed)。
const [hintClosed, setHintClosed] = useState(false);
// 统一设置弹窗(名字 + 识图 + TTS Key):可选增强,数据只存浏览器。
// 统一设置弹窗(通用 + 模型):可选增强,数据只存浏览器。
const [settingsOpen, setSettingsOpen] = useState(false);
const [modelSettingsOpen, setModelSettingsOpen] = useState(false);
const [settingsTab, setSettingsTab] = useState<"general" | "models">("general");
const [ttsConfigured, setTtsConfigured] = useState(false);
const [playerName, setPlayerName] = useState("");
const [visionClickEnabled, setVisionClickEnabled] = useState(true);
@@ -1486,16 +1485,10 @@ export default function HomePage() {
<div className="flex items-center gap-5">
<button
type="button"
onClick={() => setModelSettingsOpen(true)}
aria-label="模型设置"
title="模型设置"
className="text-base text-clay-500 hover:text-ember-500 transition-colors"
>
<i className="fa-solid fa-sliders" />
</button>
<button
type="button"
onClick={() => setSettingsOpen(true)}
onClick={() => {
setSettingsTab("general");
setSettingsOpen(true);
}}
aria-label="设置"
title="设置"
className="text-base text-clay-500 hover:text-ember-500 transition-colors"
@@ -1632,7 +1625,7 @@ export default function HomePage() {
<p className="font-serif text-[13px] md:text-sm leading-relaxed text-clay-500">
{" "}
<em className="not-italic text-ember-500">InfiPlot</em>
<span className="text-ember-500"></span>
<span className="inline-flex items-center gap-1 text-ember-500"><i className="fa-solid fa-gear text-[10px]" /></span>
API Key
</p>
<button
@@ -1793,25 +1786,18 @@ export default function HomePage() {
)}
{settingsOpen && (
<SettingsModal
initialTab={settingsTab}
initialVisionClickEnabled={visionClickEnabled}
onClose={() => setSettingsOpen(false)}
onSaved={(settings) => {
setPlayerName(settings.playerName);
setVisionClickEnabled(settings.visionClickEnabled);
}}
/>
)}
{modelSettingsOpen && (
<ModelSettingsModal
onClose={() => setModelSettingsOpen(false)}
onSaved={(settings) => {
setTtsConfigured(settings.ttsConfigured);
if (settings.ttsConfigured && voiceRow >= 0) {
const onIdx = OPTS[voiceRow]!.items.indexOf("开启");
if (onIdx >= 0)
setSel((s) => s.map((v, j) => (j === voiceRow ? onIdx : v)));
}
setModelSettingsOpen(false);
}}
/>
)}