Update locale files for English, Traditional Chinese, and Simplified Chinese to include new confirmation prompts for enabling audio effects; refactor EffectsPage and EQPage to integrate FeatureGate for managing effect states and user interactions.

This commit is contained in:
yangy
2026-05-19 13:33:10 +08:00
parent edd677c79d
commit 21839ff339
7 changed files with 315 additions and 43 deletions
+34 -12
View File
@@ -17,6 +17,7 @@ import { useState, useMemo, useEffect, useRef, useCallback } from "react";
import { cn } from "@/lib/utils";
import { useStrokeDrawAnimation } from "@/lib/useStrokeDrawAnimation";
import BottomNav from "@/components/BottomNav";
import { FeatureGate } from "@/components/FeatureGate";
import { toast } from "sonner";
import {
decodeCustomBase64,
@@ -594,7 +595,9 @@ function bandToPeqFilter(b: { freq: number; gain: number; q: number; type: strin
export default function EQPage() {
const [, setLocation] = useLocation();
const { deviceState, updateSetting, api, isDemoMode, upgradePeqChange, upgradePeqApply } = useDevice();
const eqOn = (deviceState?.peqEnable ?? 0) === 1;
const bypassOn = (deviceState?.dsp_enable ?? 0) === 0;
const peqOn = (deviceState?.peqEnable ?? 0) === 1;
const eqOn = peqOn && !bypassOn;
const eqUi = useMemo((): PeqEqUi => {
const lang = deviceState?.language;
@@ -1361,8 +1364,6 @@ export default function EQPage() {
window.clearTimeout(peqSyncTimerRef.current);
}
const useApply = abMode === "B";
peqSyncTimerRef.current = window.setTimeout(() => {
const filters = filtersSource.map(bandToPeqFilter);
const body: PeqPresetBody = {
@@ -1372,16 +1373,13 @@ export default function EQPage() {
preamp: peq.preamp ?? 0,
canDel: peq.canDel ?? 1,
};
const request = useApply
? upgradePeqApply({ peqApply: body } satisfies PeqApplyPayload)
: upgradePeqChange({ peqChange: body } satisfies PeqChangePayload);
request.catch(() => {
upgradePeqApply({ peqApply: body } satisfies PeqApplyPayload).catch(() => {
toast.error("EQ 保存失败");
});
}, delay);
};
// A 模式编辑 → peqChange;B 模式编辑(含切换后展示)→ peqApply(防抖
// A/B 切换与曲线编辑防抖同步 → peqApply(仅试听,不写预设
useEffect(() => {
if (syncingHeadphoneRef.current) return;
if (skipPeqAutoSyncRef.current) {
@@ -1394,7 +1392,7 @@ export default function EQPage() {
window.clearTimeout(peqSyncTimerRef.current);
}
};
}, [bands, abMode, headphoneIdx, peqItems, api, isDemoMode, upgradePeqChange, upgradePeqApply]);
}, [bands, abMode, headphoneIdx, peqItems, api, isDemoMode, upgradePeqApply]);
useEffect(() => {
const onPointerDown = (event: PointerEvent) => {
@@ -1575,10 +1573,34 @@ export default function EQPage() {
<ChevronLeft size={24} />
</button>
<h1 className="flex-1 text-center text-[17px] font-semibold text-white">HP-EQ</h1>
<IOSToggle checked={eqOn} onChange={(v) => updateSetting({ peqEnable: v ? 1 : 0 })} />
<IOSToggle
checked={eqOn}
onChange={(v) => {
if (v) {
void updateSetting(
bypassOn ? { peqEnable: 1, dsp_enable: 1 } : { peqEnable: 1 },
);
} else {
void updateSetting({ peqEnable: 0 });
}
}}
/>
</div>
<div className="px-4 pb-32 pt-3 space-y-3">
<FeatureGate
enabled={eqOn}
className="px-4 pb-32 pt-3 space-y-3"
labels={{
title: eqUi.enableConfirmTitle ?? "HP-EQ 未开启",
description: eqUi.enableConfirmDesc ?? "当前 HP-EQ 功能已关闭,是否开启?",
cancel: eqUi.cancel ?? "取消",
confirm: eqUi.enableConfirmOk ?? "开启",
}}
onEnable={() => {
const bypass = (deviceState?.dsp_enable ?? 0) === 0;
return updateSetting(bypass ? { peqEnable: 1, dsp_enable: 1 } : { peqEnable: 1 });
}}
>
{/* ── Action cards: 批量编辑 / 添加耳机型号 ── */}
<div className="grid grid-cols-2 gap-3">
<button
@@ -1840,7 +1862,7 @@ export default function EQPage() {
onChange={(v) => updateCurrentPeqMeta({ preamp: Number((v - 15).toFixed(1)) })}
/>
</div>
</div>
</FeatureGate>
</div>
{isSaveBDialogOpen && (