diff --git a/client/src/lib/luxsinApi.ts b/client/src/lib/luxsinApi.ts index 4243e2c..766e244 100644 --- a/client/src/lib/luxsinApi.ts +++ b/client/src/lib/luxsinApi.ts @@ -138,6 +138,7 @@ export interface PeqFilter { export interface PeqState { filters: PeqFilter[]; peqSelect?: number; + peqEnable?: number; peq?: Array<{ name: string; filters?: PeqFilter[] | string; diff --git a/client/src/pages/AIPage.tsx b/client/src/pages/AIPage.tsx index 14cfbbf..c6101b6 100644 --- a/client/src/pages/AIPage.tsx +++ b/client/src/pages/AIPage.tsx @@ -215,13 +215,18 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {}) const [routePath, setLocation] = useLocation(); const isLgUp = useIsLgUp(); const { setOpen: setAiPanelOpen } = useAIDrawer(); - const { isConnected, deviceState, api } = useDevice(); + const { isConnected, deviceState, api, updateSetting } = useDevice(); const mac = deviceState?.mac ?? ""; const language = resolveDeviceLanguage(deviceState?.language); const deviceName = deviceState?.device ?? "Luxsin X9"; const aiText = useMemo(() => resolveAILocale(language), [language]); const promptText = useMemo(() => resolveLocalePack(language).prompt, [language]); + const eqUi = useMemo(() => { + const pack = resolveLocalePack(language); + const peq = pack.peq as typeof localeZh.peq; + return peq.eqUi ?? (localeEn.peq as typeof localeEn.peq).eqUi; + }, [language]); const restoreDesktopSplit = useCallback(() => { const path = readAndClearAiSplitRestorePath(); @@ -235,6 +240,7 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {}) const [sending, setSending] = useState(false); const [historyOpen, setHistoryOpen] = useState(false); const [pendingDeleteId, setPendingDeleteId] = useState(null); + const [pendingApplyMsg, setPendingApplyMsg] = useState(null); const [chats, setChats] = useState([]); // 初次加载历史会话期间,避免先闪一下欢迎页再切到消息 const [initializing, setInitializing] = useState(true); @@ -638,7 +644,7 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {}) if (isConnected) void refreshCurrentDevicePeq(); }, [isConnected, refreshCurrentDevicePeq]); - const handleApplyToggle = useCallback( + const executeApplyToggle = useCallback( async (msg: OptimizeUIMessage) => { if (!api) { toast.error(aiText.deviceDisconnected); @@ -687,6 +693,35 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {}) [aiText, api, refreshCurrentDevicePeq], ); + const handleApplyToggle = useCallback( + (msg: OptimizeUIMessage) => { + if (!api) { + toast.error(aiText.deviceDisconnected); + return; + } + const nextApplied = !msg.applied; + if (nextApplied && (deviceState?.peqEnable ?? 0) !== 1) { + setPendingApplyMsg(msg); + return; + } + void executeApplyToggle(msg); + }, + [aiText, api, deviceState?.peqEnable, executeApplyToggle], + ); + + const confirmEnableAndApply = useCallback( + async (msg: OptimizeUIMessage) => { + try { + const bypassOn = (deviceState?.dsp_enable ?? 0) === 0; + await updateSetting(bypassOn ? { peqEnable: 1, dsp_enable: 1 } : { peqEnable: 1 }); + await executeApplyToggle(msg); + } catch (e: any) { + toast.error(formatText(aiText.optimize.applyFailed, { message: e?.message ?? e })); + } + }, + [aiText, deviceState?.dsp_enable, executeApplyToggle, updateSetting], + ); + const openCompare = useCallback( (m: OptimizeUIMessage) => { setCompareMsg(m); @@ -939,6 +974,37 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {}) + { + if (!open) setPendingApplyMsg(null); + }} + > + + + + {eqUi.enableConfirmTitle} + + + {eqUi.enableConfirmDesc} + + + + + {eqUi.cancel} + + { + if (pendingApplyMsg) void confirmEnableAndApply(pendingApplyMsg); + }} + > + {eqUi.enableConfirmOk} + + + + + {/* ── 对比对话框 ── */} {compareMsg && (