清理项目没用的代码,新增 EQ 预设管理界面
This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user