Enhance DeviceContext and LuxsinAPI to support new PEQ apply functionality; update locale files for English and Chinese to include new UI strings for applying and saving PEQ settings. Refactor AudioPage and EQPage to integrate boot sound management and improve state handling.
This commit is contained in:
@@ -13,6 +13,12 @@ import { useLocation } from "wouter";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import BottomNav from "@/components/BottomNav";
|
||||
import { navigateToSelect } from "./SelectPage";
|
||||
import {
|
||||
getBootSoundMaxIndex,
|
||||
normalizeBootSound,
|
||||
parseFirmwareVersion,
|
||||
readBootSoundFromState,
|
||||
} from "@/lib/luxsinApi";
|
||||
import localeZh from "@/locales/data-zh.json";
|
||||
import localeZhHK from "@/locales/data-zh-HK.json";
|
||||
import localeEn from "@/locales/data-en.json";
|
||||
@@ -83,6 +89,7 @@ type LocaleDac = {
|
||||
filters?: { label?: string; options?: Array<{ index: number; label: string }> };
|
||||
dacGain?: { label?: string; options?: Array<{ index: number; label: string }> };
|
||||
volumeStep?: string;
|
||||
bootVolume?: string | { label?: string; options?: Array<{ index: number; label: string }> };
|
||||
xlr?: { label?: string; options?: Array<{ index: number; label: string }> };
|
||||
mutePolar?: { label?: string; options?: Array<{ index: number; label: string }> };
|
||||
IISMode?: { label?: string; options?: Array<{ index: number; label: string }> };
|
||||
@@ -104,8 +111,48 @@ function optionLabels(items: Array<{ index: number; label: string }> | undefined
|
||||
|
||||
const STEP_OPTIONS = ["0.5dB", "1dB", "2dB", "3dB"];
|
||||
|
||||
const BOOT_VOLUME_FALLBACK = [
|
||||
"Default",
|
||||
"-5dB",
|
||||
"-10dB",
|
||||
"-15dB",
|
||||
"-20dB",
|
||||
"-25dB",
|
||||
"-30dB",
|
||||
"-35dB",
|
||||
"-40dB",
|
||||
"-45dB",
|
||||
"-50dB",
|
||||
];
|
||||
|
||||
function bootVolumeLabel(dacText: LocaleDac["dac"], index: number): string {
|
||||
const boot = dacText?.bootVolume;
|
||||
if (boot && typeof boot === "object" && boot.options?.length) {
|
||||
const hit = boot.options.find((o) => o.index === index);
|
||||
if (hit) return hit.label;
|
||||
const sorted = [...boot.options].sort((a, b) => a.index - b.index);
|
||||
if (index >= 0 && index < sorted.length) return sorted[index]?.label ?? BOOT_VOLUME_FALLBACK[index] ?? "—";
|
||||
}
|
||||
return BOOT_VOLUME_FALLBACK[index] ?? "—";
|
||||
}
|
||||
|
||||
function bootVolumeOptions(dacText: LocaleDac["dac"], maxIndex: number): string[] {
|
||||
const labels: string[] = [];
|
||||
for (let i = 0; i <= maxIndex; i += 1) {
|
||||
labels.push(bootVolumeLabel(dacText, i));
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
|
||||
function bootVolumeRowLabel(dacText: LocaleDac["dac"]): string {
|
||||
const boot = dacText?.bootVolume;
|
||||
if (boot && typeof boot === "object" && boot.label) return boot.label;
|
||||
if (typeof boot === "string") return boot;
|
||||
return "Boot volume";
|
||||
}
|
||||
|
||||
export default function AudioPage() {
|
||||
const [, setLocation] = useLocation();
|
||||
const [location, setLocation] = useLocation();
|
||||
const { deviceState, updateSetting, refresh, isConnected, api } = useDevice();
|
||||
const ds = deviceState;
|
||||
const vuSensor = (ds as ({ vuSensor?: number } | null))?.vuSensor;
|
||||
@@ -117,6 +164,8 @@ export default function AudioPage() {
|
||||
const balanceVal = ds?.balance !== undefined ? ds.balance / 10 : 0;
|
||||
// vuSensor 从接口获取的是放大 2 倍的值,需要除以 2 显示(例如:20 → +10dB)
|
||||
const vuSensVal = vuSensor !== undefined ? vuSensor / 2 : 0;
|
||||
const bootSoundFromApi = readBootSoundFromState(ds);
|
||||
const [localBootSound, setLocalBootSound] = useState(bootSoundFromApi);
|
||||
const [localBalance, setLocalBalance] = useState(balanceVal);
|
||||
const [localVuSens, setLocalVuSens] = useState(0);
|
||||
const isBalanceDragging = useRef(false);
|
||||
@@ -125,11 +174,20 @@ export default function AudioPage() {
|
||||
useEffect(() => { if (!isBalanceDragging.current) setLocalBalance(balanceVal); }, [balanceVal]);
|
||||
useEffect(() => { if (!isVuDragging.current) setLocalVuSens(vuSensVal); }, [vuSensVal]);
|
||||
useEffect(() => {
|
||||
// Ensure we have the latest pcm value from syncData when entering this page
|
||||
setLocalBootSound(readBootSoundFromState(ds));
|
||||
}, [ds?.bootSound]);
|
||||
|
||||
useEffect(() => {
|
||||
if (location !== "/audio") return;
|
||||
setLocalBootSound(readBootSoundFromState(ds));
|
||||
}, [location, ds?.bootSound, ds]);
|
||||
|
||||
useEffect(() => {
|
||||
if (location !== "/audio") return;
|
||||
if (isConnected || api) {
|
||||
refresh();
|
||||
void refresh();
|
||||
}
|
||||
}, [isConnected, api, refresh]);
|
||||
}, [location, isConnected, api, refresh]);
|
||||
|
||||
const gainIdx = ds?.dacGain ?? 0;
|
||||
const stepIdx = ds?.soundStep ?? 1;
|
||||
@@ -137,6 +195,11 @@ export default function AudioPage() {
|
||||
const xlrIdx = ds?.xlr ?? 0;
|
||||
const mutePolarIdx = (ds as ({ hdmimutepolar?: number } | null))?.hdmimutepolar ?? 0;
|
||||
const iisModeIdx = (ds as ({ hdmiType?: number } | null))?.hdmiType ?? 0;
|
||||
const bootSoundVal = normalizeBootSound(localBootSound);
|
||||
const firmwareVersion = parseFirmwareVersion(ds?.version);
|
||||
const bootSoundMaxIdx = getBootSoundMaxIndex(firmwareVersion);
|
||||
const bootSoundSelectIdx = Math.min(bootSoundVal, bootSoundMaxIdx);
|
||||
const BOOT_VOLUME_OPTIONS = bootVolumeOptions(dacText, bootSoundMaxIdx);
|
||||
|
||||
const FILTER_OPTIONS = optionLabels(dacText.filters?.options, ["快速滚降", "慢速滚降", "短延迟快速滚降", "短延迟慢速滚降", "去重强调", "非过采样(NOS)"]);
|
||||
const GAIN_OPTIONS = optionLabels(dacText.dacGain?.options, ["低", "中", "高"]);
|
||||
@@ -237,6 +300,18 @@ export default function AudioPage() {
|
||||
{/* ── 系统与接口 ── */}
|
||||
<SectionHeader title={dacText.sectionSystemInterface ?? "系统与接口"} />
|
||||
<div className="ios-list-group">
|
||||
<ListRow
|
||||
label={bootVolumeRowLabel(dacText)}
|
||||
value={bootVolumeLabel(dacText, bootSoundVal)}
|
||||
onClick={() =>
|
||||
goSelect(
|
||||
bootVolumeRowLabel(dacText),
|
||||
BOOT_VOLUME_OPTIONS,
|
||||
bootSoundSelectIdx,
|
||||
"bootSound",
|
||||
)
|
||||
}
|
||||
/>
|
||||
<ListRow
|
||||
label={dacText.xlr?.label ?? "XLR 端口极性"}
|
||||
value={XLR_OPTIONS[xlrIdx] ?? XLR_OPTIONS[0] ?? "—"}
|
||||
|
||||
Reference in New Issue
Block a user