Refactor BottomNav and CommunityPage to enhance community forum integration; update navigation logic for mobile and desktop views. Add new localized strings for community page and system settings, including device information and user prompts.

This commit is contained in:
yangy
2026-05-13 17:42:26 +08:00
parent 5285b886ea
commit b3d3f0edcb
9 changed files with 372 additions and 92 deletions
+55 -15
View File
@@ -17,17 +17,40 @@ import localeZh from "@/locales/data-zh.json";
import localeZhHK from "@/locales/data-zh-HK.json";
import localeEn from "@/locales/data-en.json";
function CyanSlider({ value, min, max, step = 1, onChange }: {
value: number; min: number; max: number; step?: number; onChange: (v: number) => void;
function CyanSlider({ value, min, max, step = 1, onChange, onRelease }: {
value: number;
min: number;
max: number;
step?: number;
onChange: (v: number) => void;
/** Commit to device once when the user releases the thumb (pointer / keyboard). */
onRelease?: (v: number) => void;
}) {
const fillPct = ((value - min) / (max - min)) * 100;
const emitRelease = (el: EventTarget | null) => {
if (!(el instanceof HTMLInputElement)) return;
onRelease?.(Number(el.value));
};
return (
<div className="relative flex items-center w-full mt-2">
<div className="absolute left-0 h-[4px] rounded-full pointer-events-none"
style={{ width: `${fillPct}%`, background: "#00FFF6", boxShadow: "0 0 6px rgba(0,255,246,0.5)" }} />
<input type="range" min={min} max={max} step={step} value={value}
<input
type="range"
min={min}
max={max}
step={step}
value={value}
className="cyan-slider relative z-10"
onChange={(e) => onChange(Number(e.target.value))} />
onChange={(e) => onChange(Number(e.target.value))}
onPointerUp={(e) => emitRelease(e.currentTarget)}
onPointerCancel={(e) => emitRelease(e.currentTarget)}
onKeyUp={(e) => {
if (["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End", "PageUp", "PageDown"].includes(e.key)) {
emitRelease(e.currentTarget);
}
}}
/>
</div>
);
}
@@ -52,6 +75,9 @@ function ListRow({ label, value, onClick }: { label: string; value: string; onCl
type LocaleDac = {
dac?: {
sectionBalanceSensitivity?: string;
sectionOutput?: string;
sectionSystemInterface?: string;
balance?: string;
sensitivity?: string;
filters?: { label?: string; options?: Array<{ index: number; label: string }> };
@@ -137,7 +163,7 @@ export default function AudioPage() {
<div className="px-4 pb-32">
{/* ── 平衡与灵敏度 ── */}
<SectionHeader title="平衡与灵敏度" />
<SectionHeader title={dacText.sectionBalanceSensitivity ?? "平衡与灵敏度"} />
<div className="ios-list-group px-4 py-3 space-y-4">
<div>
<div className="flex items-center justify-between">
@@ -146,14 +172,21 @@ export default function AudioPage() {
{localBalance >= 0 ? `+${localBalance.toFixed(1)}` : localBalance.toFixed(1)} dB
</span>
</div>
<CyanSlider value={localBalance} min={-15} max={15} step={0.1}
<CyanSlider
value={localBalance}
min={-15}
max={15}
step={0.1}
onChange={(v) => {
isBalanceDragging.current = true;
setLocalBalance(v);
// 实时调用接口(例如:-13.0 → -130)
}}
onRelease={(v) => {
isBalanceDragging.current = false;
setLocalBalance(v);
updateSetting({ balance: Math.round(v * 10) });
setTimeout(() => { isBalanceDragging.current = false; }, 500);
}} />
}}
/>
</div>
<div className="border-t border-white/[0.06]" />
<div>
@@ -163,19 +196,26 @@ export default function AudioPage() {
{localVuSens >= 0 ? `+${localVuSens}` : localVuSens} dB
</span>
</div>
<CyanSlider value={localVuSens} min={-20} max={20}
<CyanSlider
value={localVuSens}
min={-20}
max={20}
step={1}
onChange={(v) => {
isVuDragging.current = true;
setLocalVuSens(v);
// 接口参数需要将显示值乘以 2(例如:10dB -> vuSensor=20
}}
onRelease={(v) => {
isVuDragging.current = false;
setLocalVuSens(v);
updateSetting({ vuSensor: Math.round(v * 2) });
setTimeout(() => { isVuDragging.current = false; }, 500);
}} />
}}
/>
</div>
</div>
{/* ── 输出特性 ── */}
<SectionHeader title="输出特性" />
<SectionHeader title={dacText.sectionOutput ?? "输出特性"} />
<div className="ios-list-group">
<ListRow
label={dacText.filters?.label ?? "滤波特性"}
@@ -195,7 +235,7 @@ export default function AudioPage() {
</div>
{/* ── 系统与接口 ── */}
<SectionHeader title="系统与接口" />
<SectionHeader title={dacText.sectionSystemInterface ?? "系统与接口"} />
<div className="ios-list-group">
<ListRow
label={dacText.xlr?.label ?? "XLR 端口极性"}