From 8cde8204670fb3b58e266278733796f562d2396a Mon Sep 17 00:00:00 2001 From: yangy Date: Wed, 27 May 2026 13:52:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/lib/luxsinApi.ts | 16 +++++++++++ client/src/locales/data-en.json | 4 +-- client/src/locales/data-zh-HK.json | 4 +-- client/src/locales/data-zh.json | 4 +-- client/src/pages/AudioPage.tsx | 2 +- client/src/pages/EffectsPage.tsx | 44 +++++++++++++++++++++++------- client/src/pages/Home.tsx | 25 ++++++++--------- client/src/pages/SystemPage.tsx | 3 +- 8 files changed, 71 insertions(+), 31 deletions(-) diff --git a/client/src/lib/luxsinApi.ts b/client/src/lib/luxsinApi.ts index 7a196a3..7779a05 100644 --- a/client/src/lib/luxsinApi.ts +++ b/client/src/lib/luxsinApi.ts @@ -171,6 +171,9 @@ export interface PeqApplyPayload { export const INPUT_LABELS = ["USB", "USB-C", "Coaxial", "Optical", "Bluetooth", "IIS", "RCA"]; export const OUTPUT_LABELS = ["XLR", "RCA", "Headset", "XLR/RCA"]; +/** Device `input` index for Bluetooth source. */ +export const INPUT_BLUETOOTH_INDEX = 4; + /** Device `output` index for headphone / headset. */ export const OUTPUT_HEADSET_INDEX = 2; export const LANGUAGE_LABELS = ["English", "繁體中文", "简体中文"]; @@ -345,6 +348,19 @@ export function parseFirmwareVersion(version: unknown): number { return Number(parts[parts.length - 1]); } +/** Display firmware version as X.Y.0.Z (e.g. 2005 → 2.0.0.5). */ +export function formatFirmwareVersionDisplay(version: unknown): string { + if (version === null || version === undefined || String(version).trim() === "") { + return "—"; + } + const n = parseFirmwareVersion(version); + const major = Math.floor(n / 1000); + const minor = Math.floor((n % 1000) / 100); + const patch = 0; + const build = n % 10; + return `${major}.${minor}.${patch}.${build}`; +} + /** Pre-out volume passthrough mode selected (0dB or -12dB). */ export function isVolumePassthroughActive(dacVolumeDirect: number | undefined): boolean { return dacVolumeDirect === 1 || dacVolumeDirect === 2; diff --git a/client/src/locales/data-en.json b/client/src/locales/data-en.json index 5aa8f79..3a43054 100644 --- a/client/src/locales/data-en.json +++ b/client/src/locales/data-en.json @@ -404,11 +404,11 @@ }, { "index": 4, - "label": "De-emphasis filter" + "label": "Super Slow Roll-off" }, { "index": 5, - "label": "Non-oversampling" + "label": "Low Dispersion Short Delay" } ] }, diff --git a/client/src/locales/data-zh-HK.json b/client/src/locales/data-zh-HK.json index 7ce6fea..563fb50 100644 --- a/client/src/locales/data-zh-HK.json +++ b/client/src/locales/data-zh-HK.json @@ -326,8 +326,8 @@ { "index": 1, "label": "慢速衰減" }, { "index": 2, "label": "短延遲快速衰減" }, { "index": 3, "label": "短延遲慢速衰減" }, - { "index": 4, "label": "去重強調" }, - { "index": 5, "label": "非過采樣(NOS)" } + { "index": 4, "label": "超慢速滾降" }, + { "index": 5, "label": "低離散短延遲" } ] }, "dacGain": { diff --git a/client/src/locales/data-zh.json b/client/src/locales/data-zh.json index b01249e..6afa824 100644 --- a/client/src/locales/data-zh.json +++ b/client/src/locales/data-zh.json @@ -326,8 +326,8 @@ { "index": 1, "label": "慢速滚降" }, { "index": 2, "label": "短延迟快速滚降" }, { "index": 3, "label": "短延迟慢速滚降" }, - { "index": 4, "label": "去重强调" }, - { "index": 5, "label": "非过采样(NOS)" } + { "index": 4, "label": "超慢速滚降" }, + { "index": 5, "label": "低离散短延迟" } ] }, "dacGain": { diff --git a/client/src/pages/AudioPage.tsx b/client/src/pages/AudioPage.tsx index 62837da..ea503c3 100644 --- a/client/src/pages/AudioPage.tsx +++ b/client/src/pages/AudioPage.tsx @@ -235,7 +235,7 @@ export default function AudioPage() { const bootSoundSelectIdx = Math.min(bootSoundVal, bootSoundMaxIdx); const BOOT_VOLUME_OPTIONS = bootVolumeOptions(dacText, bootSoundMaxIdx); - const FILTER_OPTIONS = optionLabels(dacText.filters?.options, ["快速滚降", "慢速滚降", "短延迟快速滚降", "短延迟慢速滚降", "去重强调", "非过采样(NOS)"]); + const FILTER_OPTIONS = optionLabels(dacText.filters?.options, ["快速滚降", "慢速滚降", "短延迟快速滚降", "短延迟慢速滚降", "超慢速滚降", "低离散短延迟"]); const GAIN_OPTIONS = optionLabels(dacText.dacGain?.options, ["低", "中", "高"]); const DAC_VOLUME_DIRECT_OPTIONS = optionLabels(dacText.dacVolumeDirect?.options, ["关闭", "0dB", "-12dB"]); const DAC_ARC_OPTIONS = optionLabels(dacText.dacArc?.options, ["ARC", "EARC"]); diff --git a/client/src/pages/EffectsPage.tsx b/client/src/pages/EffectsPage.tsx index e823a42..6f2b26f 100644 --- a/client/src/pages/EffectsPage.tsx +++ b/client/src/pages/EffectsPage.tsx @@ -144,27 +144,31 @@ function IOSToggle({ checked, onChange }: { checked: boolean; onChange: (v: bool ); } -function CyanSlider({ value, min, max, step = 0.1, onChange, onRelease }: { +function CyanSlider({ value, min, max, step = 0.1, disabled = false, onChange, onRelease }: { value: number; min: number; max: number; step?: number; + disabled?: boolean; onChange: (v: number) => void; /** Fires once when the user releases the thumb (pointer/mouse/touch). Read value from DOM to avoid stale React state. */ onRelease?: (v: number) => void; }) { const fillPct = ((value - min) / (max - min)) * 100; const emitRelease = (el: EventTarget | null) => { - if (!(el instanceof HTMLInputElement)) return; + if (disabled || !(el instanceof HTMLInputElement)) return; onRelease?.(Number(el.value)); }; return ( -
+
- onChange(Number(e.target.value))} + onChange={(e) => { + if (disabled) return; + onChange(Number(e.target.value)); + }} onPointerUp={(e) => emitRelease(e.currentTarget)} onPointerCancel={(e) => emitRelease(e.currentTarget)} onKeyUp={(e) => { @@ -359,8 +363,16 @@ export default function EffectsPage() { updateSetting({ effect_enable: v ? 1 : 0 })} />
@@ -380,16 +392,20 @@ export default function EffectsPage() { min={0} max={100} step={1} + disabled={!widthOn} onChange={(v) => { + if (!widthOn) return; isDragging.current = true; setLocalWidth(Math.round(v)); }} onRelease={(v) => { + if (!widthOn) return; isDragging.current = false; const w = Math.round(v); setLocalWidth(w); updateSetting({ width_value: w }); - }} /> + }} + />
{/* ── 交叉反馈 ── */} @@ -399,8 +415,16 @@ export default function EffectsPage() { updateSetting({ crossfeed_enable: v ? 1 : 0 })} />
diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx index 03981ee..d2b1890 100644 --- a/client/src/pages/Home.tsx +++ b/client/src/pages/Home.tsx @@ -22,7 +22,12 @@ import { AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; -import { INPUT_LABELS, isHomeVolumeLockedByPassthrough, OUTPUT_LABELS } from "@/lib/luxsinApi"; +import { + INPUT_BLUETOOTH_INDEX, + INPUT_LABELS, + isHomeVolumeLockedByPassthrough, + OUTPUT_LABELS, +} from "@/lib/luxsinApi"; import { cn } from "@/lib/utils"; import { ChevronRight, @@ -164,7 +169,7 @@ function ListRow({ } export default function Home() { - const { isConnected, deviceState, setVolume, updateSetting, api, disconnect, isDemoMode, ip } = useDevice(); + const { isConnected, deviceState, setVolume, updateSetting, api, isDemoMode, ip } = useDevice(); const [, setLocation] = useLocation(); const powerActionRef = useRef(false); const hpEqLastTapRef = useRef(null); @@ -232,24 +237,18 @@ export default function Home() { if (powerActionRef.current) return; powerActionRef.current = true; try { - if (isDemoMode) { - toast.info(homeText.powerOffToastDemo ?? "演示模式:已断开与设备的连接"); - disconnect(); - return; - } - if (api) { + if (!isDemoMode && api) { try { await api.powerOff(); } catch { - // 设备可能已掉线或未返回响应,仍断开本地会话 + // 设备关机后可能已无响应,仍保留当前页面与连接状态 } } - disconnect(); toast.success(homeText.powerOffToastSent ?? "已发送关机指令"); } finally { powerActionRef.current = false; } - }, [api, disconnect, isDemoMode, homeText]); + }, [api, isDemoMode, homeText]); /** HP-EQ 圆钮:单击在短延迟后切换 peqEnable(避免与双击抢);280ms 内第二次点击则取消开关并进入 /eq */ const HP_EQ_DOUBLE_CLICK_MS = 280; @@ -779,8 +778,8 @@ export default function Home() { - {/* Bluetooth info */} - {ds.bt_status !== 0 && ( + {/* Bluetooth info — only when input source is Bluetooth */} + {ds.input === INPUT_BLUETOOTH_INDEX && ds.bt_status !== 0 && (
diff --git a/client/src/pages/SystemPage.tsx b/client/src/pages/SystemPage.tsx index 5a033cf..8787390 100644 --- a/client/src/pages/SystemPage.tsx +++ b/client/src/pages/SystemPage.tsx @@ -13,6 +13,7 @@ import { ChevronLeft, ChevronRight } from "lucide-react"; import { useLocation } from "wouter"; import { useEffect } from "react"; import BottomNav from "@/components/BottomNav"; +import { formatFirmwareVersionDisplay } from "@/lib/luxsinApi"; import { navigateToSelect } from "./SelectPage"; import localeZh from "@/locales/data-zh.json"; import localeZhHK from "@/locales/data-zh-HK.json"; @@ -215,7 +216,7 @@ export default function SystemPage() {
{ui.firmwareVersion} - {ds?.version ?? "—"} + {formatFirmwareVersionDisplay(ds?.version)}
{ui.macAddress}