清理项目没用的代码,新增 EQ 预设管理界面

This commit is contained in:
eafonyang
2026-06-18 12:01:12 +08:00
parent 0d577f939c
commit e16c3ebd9d
13 changed files with 460 additions and 130 deletions
+90
View File
@@ -20,6 +20,7 @@ import { FeatureGate } from "@/components/FeatureGate";
import { toast } from "sonner";
import {
fetchLuxsinAudioCurve,
normalizePeqFiltersForSubmit,
type PeqFilter,
type PeqApplyPayload,
type PeqChangePayload,
@@ -39,6 +40,7 @@ import { BatchEditDialog } from "./eq/components/BatchEditDialog";
import { ShareDialog } from "./eq/components/ShareDialog";
import { BrandDrawer } from "./eq/components/BrandDrawer";
import { PeqOverwriteConfirmDialog } from "./eq/components/PeqOverwriteConfirmDialog";
import { PeqPresetManageDialog } from "./eq/components/PeqPresetManageDialog";
import { useRawCurve } from "./eq/hooks/useRawCurve";
import {
BAND_FREQ_MAX,
@@ -151,6 +153,7 @@ export default function EQPage() {
const [brandDrawerKey, setBrandDrawerKey] = useState(0);
const [isShareDialogOpen, setIsShareDialogOpen] = useState(false);
const [shareDialogKey, setShareDialogKey] = useState(0);
const [isPresetManageDialogOpen, setIsPresetManageDialogOpen] = useState(false);
const [overwritePresetDialog, setOverwritePresetDialog] = useState<{
name: string;
onConfirm: () => void | Promise<void>;
@@ -297,6 +300,10 @@ export default function EQPage() {
setIsBatchEditDialogOpen(true);
};
const openPresetManageDialog = () => {
setIsPresetManageDialogOpen(true);
};
const parseBatchEditText = useCallback(
(raw: string) => {
const t = eqUi;
@@ -1406,6 +1413,13 @@ export default function EQPage() {
)}
</div>
<div className="flex items-center gap-2">
<button
className="w-9 h-9 rounded-full flex items-center justify-center text-white/60 active:text-white transition-colors"
style={{ background: "rgba(44,44,46,0.8)", border: "1px solid rgba(255,255,255,0.1)" }}
onClick={openPresetManageDialog}
>
<Edit3 size={15} />
</button>
<button
className="w-9 h-9 rounded-full flex items-center justify-center text-white/60 active:text-white transition-colors"
style={{ background: "rgba(44,44,46,0.8)", border: "1px solid rgba(255,255,255,0.1)" }}
@@ -1812,6 +1826,82 @@ export default function EQPage() {
}}
/>
<PeqPresetManageDialog
open={isPresetManageDialogOpen}
items={peqItems}
selectedIdx={headphoneIdx}
onClose={() => setIsPresetManageDialogOpen(false)}
eqUi={eqUi}
onDeletePresets={async (names) => {
try {
if (isDemoMode || !api) {
const nextItems = peqItems.filter(it => !names.includes(it.name));
names.forEach(n => delete peqPresetCacheRef.current[n]);
applyPeqStateToUI({ peq: nextItems, peqSelect: Math.min(headphoneIdx, Math.max(0, nextItems.length - 1)) });
toast.success(eqUi.toastDeleted);
return true;
}
names.forEach(n => delete peqPresetCacheRef.current[n]);
await api.removePeq(names);
const latest = await fetchEqSyncPeq(api, "deletePresets");
applyPeqStateToUI(latest);
toast.success(eqUi.toastDeleted);
return true;
} catch {
toast.error(eqUi.toastDeleteFail);
return false;
}
}}
onRenamePreset={async (oldName, newName, item) => {
try {
const rawFilters = normalizePeqFiltersForSubmit(item.filters);
const filters = rawFilters.map(f => ({
...f,
type: getFilterType(f.type),
}));
const payload: PeqChangePayload = {
peqChange: {
name: newName,
filters,
autoPre: item.autoPre,
preamp: item.preamp,
canDel: item.canDel ?? 1,
brand: item.brand,
model: item.model,
target: item.target,
form: item.form,
},
};
if (isDemoMode || !api) {
const nextItems = peqItems.map(it =>
it.name === oldName ? { ...it, name: newName } : it
);
delete peqPresetCacheRef.current[oldName];
applyPeqStateToUI({ peq: nextItems, peqSelect: headphoneIdx });
toast.success(eqUi.toastRenamed);
return true;
}
// Step 1: peqChange — create new preset with new name + same EQ data
// Use api.upgradePeqChange directly (NOT the DeviceContext wrapper)
// to avoid applyPeqFiltersToState side-effect that overwrites current UI bands.
await api.upgradePeqChange(payload);
// Step 2: peqRemove — delete the old preset
delete peqPresetCacheRef.current[oldName];
await api.removePeq([oldName]);
// Step 3: sync latest state from device
const latest = await fetchEqSyncPeq(api, "renamePreset");
applyPeqStateToUI(latest);
toast.success(eqUi.toastRenamed);
return true;
} catch {
toast.error(eqUi.toastRenameFail);
return false;
}
}}
/>
<ShareDialog
key={`share-dialog-${shareDialogKey}`}
open={isShareDialogOpen}