diff --git a/client/src/lib/luxsinApi.ts b/client/src/lib/luxsinApi.ts index 7c466ae..c3e14d8 100644 --- a/client/src/lib/luxsinApi.ts +++ b/client/src/lib/luxsinApi.ts @@ -62,6 +62,7 @@ export interface DeviceState { audioFormat: string; pcm: number; vu: number; + vuSensor: number; vu_count: number; screenLight: number; knob_breathlight: number; @@ -227,6 +228,7 @@ export const MOCK_DEVICE_STATE: DeviceState = { audioFormat: "PCM 44.1 KHz", pcm: 1, vu: 0, + vuSensor: 0, vu_count: 5, screenLight: 0, knob_breathlight: 1, diff --git a/client/src/pages/AudioPage.tsx b/client/src/pages/AudioPage.tsx index eb7fb5d..99686bd 100644 --- a/client/src/pages/AudioPage.tsx +++ b/client/src/pages/AudioPage.tsx @@ -58,14 +58,20 @@ export default function AudioPage() { const [, setLocation] = useLocation(); const { deviceState, updateSetting } = useDevice(); const ds = deviceState; + const vuSensor = (ds as ({ vuSensor?: number } | null))?.vuSensor; - const balanceVal = ds?.balance ?? 0; + // balance 从接口获取的是乘以 10 后的值,需要除以 10 显示(例如:-130 → -13.0) + const balanceVal = ds?.balance !== undefined ? ds.balance / 10 : 0; + // vuSensor 从接口获取的是放大 2 倍的值,需要除以 2 显示(例如:20 → +10dB) + const vuSensVal = vuSensor !== undefined ? vuSensor / 2 : 0; const [localBalance, setLocalBalance] = useState(balanceVal); - const [localVuSens, setLocalVuSens] = useState(12); + const [localVuSens, setLocalVuSens] = useState(0); const [filterIdx] = useState(0); - const isDragging = useRef(false); + const isBalanceDragging = useRef(false); + const isVuDragging = useRef(false); - useEffect(() => { if (!isDragging.current) setLocalBalance(balanceVal); }, [balanceVal]); + useEffect(() => { if (!isBalanceDragging.current) setLocalBalance(balanceVal); }, [balanceVal]); + useEffect(() => { if (!isVuDragging.current) setLocalVuSens(vuSensVal); }, [vuSensVal]); const gainIdx = ds?.analogGain ?? 0; const stepIdx = ds?.soundStep ?? 1; @@ -99,12 +105,13 @@ export default function AudioPage() { {localBalance >= 0 ? `+${localBalance.toFixed(1)}` : localBalance.toFixed(1)} dB - { - isDragging.current = true; + isBalanceDragging.current = true; setLocalBalance(v); - updateSetting({ balance: v }); - setTimeout(() => { isDragging.current = false; }, 500); + // 实时调用接口(例如:-13.0 → -130) + updateSetting({ balance: Math.round(v * 10) }); + setTimeout(() => { isBalanceDragging.current = false; }, 500); }} />
@@ -112,14 +119,16 @@ export default function AudioPage() {
VU 表灵敏度 - {localVuSens} dB + {localVuSens >= 0 ? `+${localVuSens}` : localVuSens} dB
- { - isDragging.current = true; + isVuDragging.current = true; setLocalVuSens(v); - setTimeout(() => { isDragging.current = false; }, 500); + // 接口参数需要将显示值乘以 2(例如:10dB -> vuSensor=20) + updateSetting({ vuSensor: Math.round(v * 2) }); + setTimeout(() => { isVuDragging.current = false; }, 500); }} />
diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx index 6515ae6..b61d1ec 100644 --- a/client/src/pages/Home.tsx +++ b/client/src/pages/Home.tsx @@ -341,9 +341,7 @@ export default function Home() { } label="音频设置" - toggle - checked={audioOn} - onToggle={(v) => updateSetting({ audio_enable: v ? 1 : 0 })} + onClick={() => setLocation("/audio")} /> } diff --git a/client/src/pages/SystemPage.tsx b/client/src/pages/SystemPage.tsx index 6df8c8b..29032c7 100644 --- a/client/src/pages/SystemPage.tsx +++ b/client/src/pages/SystemPage.tsx @@ -14,6 +14,9 @@ import { useLocation } from "wouter"; import { useEffect } from "react"; import BottomNav from "@/components/BottomNav"; import { navigateToSelect } from "./SelectPage"; +import localeZh from "@/locales/data-zh.json"; +import localeZhHK from "@/locales/data-zh-HK.json"; +import localeEn from "@/locales/data-en.json"; function IOSToggle({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) { return ( @@ -61,12 +64,31 @@ function ListRow({ label, description, value, onClick, toggle, checked, onToggle ); } -const SCREEN_LIGHT_OPTIONS = ["亮", "中等", "暗"]; -const KNOB_LIGHT_OPTIONS = ["关闭", "亮", "中等", "暗"]; -const SCREEN_OFF_OPTIONS = ["常亮", "30秒", "1分钟", "3分钟", "5分钟"]; -const SLEEP_OPTIONS = ["关闭", "1分钟", "5分钟", "10分钟"]; -const AUTO_HOME_OPTIONS = ["关闭", "20秒", "40秒", "60秒"]; -const LANG_OPTIONS = ["English", "繁體中文", "简体中文"]; +type LocaleSettings = { + settings: { + vu: string; + screenBrightness: { label: string; options: Array<{ index: number; label: string }> }; + turnOffScreen: { label: string; options: Array<{ index: number; label: string }> }; + knobBrightness: { label: string; options: Array<{ index: number; label: string }> }; + buttonLight: { label: string; options: Array<{ index: number; label: string }> }; + language: { label: string; options: Array<{ index: number; label: string }> }; + Automatic: { label: string; options: Array<{ index: number; label: string }> }; + sleepTime?: { label: string; options: Array<{ index: number; label: string }> }; + sleep?: { label: string; options: Array<{ index: number; label: string }> }; + }; +}; + +const LOCALE_BY_LANG: Record = { + 0: localeEn as LocaleSettings, + 1: localeZhHK as LocaleSettings, + 2: localeZh as LocaleSettings, +}; + +function optionLabels(items: Array<{ index: number; label: string }> | undefined, fallback: string[]) { + if (!items || items.length === 0) return fallback; + const sorted = [...items].sort((a, b) => a.index - b.index); + return sorted.map((item) => item.label); +} export default function SystemPage() { const [, setLocation] = useLocation(); @@ -87,6 +109,14 @@ export default function SystemPage() { const autoHomeIdx = ds?.autoHome ?? 1; const langIdx = ds?.language ?? 2; const knobBreathLightOn = (ds?.knob_breathlight ?? 1) === 0; + const localeData = LOCALE_BY_LANG[langIdx] ?? localeZh; + const settingsText = localeData.settings; + const SCREEN_LIGHT_OPTIONS = optionLabels(settingsText.screenBrightness?.options, ["亮", "中等", "暗"]); + const KNOB_LIGHT_OPTIONS = optionLabels(settingsText.knobBrightness?.options, ["关闭", "亮", "中等", "暗"]); + const SCREEN_OFF_OPTIONS = optionLabels(settingsText.turnOffScreen?.options, ["常亮", "30秒", "1分钟", "3分钟", "5分钟"]); + const SLEEP_OPTIONS = optionLabels(settingsText.sleepTime?.options ?? settingsText.sleep?.options, ["关闭", "1分钟", "5分钟", "10分钟"]); + const AUTO_HOME_OPTIONS = optionLabels(settingsText.Automatic?.options, ["关闭", "20秒", "40秒", "60秒"]); + const LANG_OPTIONS = optionLabels(settingsText.language?.options, ["English", "繁體中文", "简体中文"]); const goSelect = (title: string, options: string[], selected: number, key: string) => { navigateToSelect(title, options, selected, "/system", key); @@ -99,7 +129,7 @@ export default function SystemPage() { -

设置

+

{settingsText.vu}

@@ -107,16 +137,16 @@ export default function SystemPage() { {/* ── 显示 ── */}
- goSelect("屏幕亮度", SCREEN_LIGHT_OPTIONS, screenLightIdx, "screenLight")} /> - goSelect(settingsText.screenBrightness.label, SCREEN_LIGHT_OPTIONS, screenLightIdx, "screenLight")} /> + goSelect("自动锁屏", SCREEN_OFF_OPTIONS, screenOffIdx, "screenOff")} /> - goSelect(settingsText.turnOffScreen.label, SCREEN_OFF_OPTIONS, screenOffIdx, "screenOff")} /> + goSelect("旋钮亮度", KNOB_LIGHT_OPTIONS, buttonLightIdx, "buttonLight")} /> - goSelect(settingsText.knobBrightness.label, KNOB_LIGHT_OPTIONS, buttonLightIdx, "buttonLight")} /> + updateSetting({ knob_breathlight: v ? 0 : 1 })} />
@@ -124,15 +154,15 @@ export default function SystemPage() { {/* ── 通用 ── */}
- goSelect("选择语言", LANG_OPTIONS, langIdx, "language")} /> - goSelect(settingsText.language.label, LANG_OPTIONS, langIdx, "language")} /> + goSelect("自动返回首页", AUTO_HOME_OPTIONS, autoHomeIdx, "autoHome")} /> - goSelect(settingsText.Automatic.label, AUTO_HOME_OPTIONS, autoHomeIdx, "autoHome")} /> + goSelect("休眠时间", SLEEP_OPTIONS, sleepIdx, "sleep")} /> + onClick={() => goSelect(settingsText.sleepTime?.label ?? settingsText.sleep?.label ?? "休眠", SLEEP_OPTIONS, sleepIdx, "sleep")} />
{/* ── 关于 ── */}